Add grpc opentracing support to the binaries

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
docker-18.09
Tonis Tiigi 2018-01-05 15:17:35 -08:00
parent dc43b45489
commit 6b98dedaef
251 changed files with 39482 additions and 11 deletions

View File

@ -6,8 +6,10 @@ import (
"io/ioutil"
"time"
"github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc"
controlapi "github.com/moby/buildkit/api/services/control"
"github.com/moby/buildkit/util/appdefaults"
opentracing "github.com/opentracing/opentracing-go"
"github.com/pkg/errors"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
@ -39,6 +41,11 @@ func New(address string, opts ...ClientOpt) (*Client, error) {
gopts = append(gopts, opt)
needWithInsecure = false
}
if wt, ok := o.(*withTracer); ok {
gopts = append(gopts,
grpc.WithUnaryInterceptor(otgrpc.OpenTracingClientInterceptor(wt.tracer, otgrpc.LogPayloads())),
grpc.WithStreamInterceptor(otgrpc.OpenTracingStreamClientInterceptor(wt.tracer)))
}
}
if needWithInsecure {
gopts = append(gopts, grpc.WithInsecure())
@ -115,3 +122,11 @@ func loadCredentials(opts *withCredentials) (grpc.DialOption, error) {
return grpc.WithTransportCredentials(credentials.NewTLS(cfg)), nil
}
func WithTracer(t opentracing.Tracer) ClientOpt {
return &withTracer{t}
}
type withTracer struct {
tracer opentracing.Tracer
}

View File

@ -17,6 +17,7 @@ import (
"github.com/moby/buildkit/session/filesync"
"github.com/moby/buildkit/session/grpchijack"
"github.com/moby/buildkit/solver/pb"
opentracing "github.com/opentracing/opentracing-go"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/sync/errgroup"
@ -61,6 +62,10 @@ func (c *Client) Solve(ctx context.Context, def *llb.Definition, opt SolveOpt, s
statusContext, cancelStatus := context.WithCancel(context.Background())
defer cancelStatus()
if span := opentracing.SpanFromContext(ctx); span != nil {
statusContext = opentracing.ContextWithSpan(statusContext, span)
}
s, err := session.NewSession(defaultSessionName(), opt.SharedKey)
if err != nil {
return errors.Wrap(err, "failed to create session")

View File

@ -12,7 +12,6 @@ import (
"github.com/moby/buildkit/client"
"github.com/moby/buildkit/client/llb"
"github.com/moby/buildkit/solver/pb"
"github.com/moby/buildkit/util/appcontext"
"github.com/moby/buildkit/util/progress/progressui"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
@ -116,7 +115,7 @@ func build(clicontext *cli.Context) error {
ch := make(chan *client.SolveStatus)
displayCh := make(chan *client.SolveStatus)
eg, ctx := errgroup.WithContext(appcontext.Context())
eg, ctx := errgroup.WithContext(commandContext(clicontext))
exporterAttrs, err := attrMap(clicontext.StringSlice("exporter-opt"))
if err != nil {

View File

@ -1,13 +1,13 @@
package debug
import (
"context"
"fmt"
"os"
"sort"
"text/tabwriter"
"github.com/moby/buildkit/client"
"github.com/moby/buildkit/util/appcontext"
"github.com/urfave/cli"
)
@ -37,7 +37,7 @@ func listWorkers(clicontext *cli.Context) error {
return err
}
workers, err := c.ListWorkers(appcontext.Context(), client.WithWorkerFilter(clicontext.StringSlice("filter")))
workers, err := c.ListWorkers(commandContext(clicontext), client.WithWorkerFilter(clicontext.StringSlice("filter")))
if err != nil {
return err
}
@ -86,3 +86,7 @@ func sortedKeys(m map[string]string) []string {
sort.Strings(s)
return s
}
func commandContext(c *cli.Context) context.Context {
return c.App.Metadata["context"].(context.Context)
}

View File

@ -7,7 +7,6 @@ import (
"text/tabwriter"
"github.com/moby/buildkit/client"
"github.com/moby/buildkit/util/appcontext"
"github.com/tonistiigi/units"
"github.com/urfave/cli"
)
@ -34,7 +33,7 @@ func diskUsage(clicontext *cli.Context) error {
return err
}
du, err := c.DiskUsage(appcontext.Context(), client.WithFilter(clicontext.String("filter")))
du, err := c.DiskUsage(commandContext(clicontext), client.WithFilter(clicontext.String("filter")))
if err != nil {
return err
}

View File

@ -8,6 +8,7 @@ import (
"github.com/moby/buildkit/client"
"github.com/moby/buildkit/util/appdefaults"
"github.com/moby/buildkit/util/profiler"
opentracing "github.com/opentracing/opentracing-go"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
)
@ -71,6 +72,8 @@ func main() {
return nil
}
attachAppContext(app)
profiler.Attach(app)
if err := app.Run(os.Args); err != nil {
@ -96,7 +99,13 @@ func resolveClient(c *cli.Context) (*client.Client, error) {
caCert := c.GlobalString("tlscacert")
cert := c.GlobalString("tlscert")
key := c.GlobalString("tlskey")
opts := []client.ClientOpt{client.WithBlock()}
if span := opentracing.SpanFromContext(commandContext(c)); span != nil {
opts = append(opts, client.WithTracer(span.Tracer()))
}
if caCert != "" || cert != "" || key != "" {
opts = append(opts, client.WithCredentials(serverName, caCert, cert, key))
}

View File

@ -6,7 +6,6 @@ import (
"text/tabwriter"
"github.com/moby/buildkit/client"
"github.com/moby/buildkit/util/appcontext"
"github.com/tonistiigi/units"
"github.com/urfave/cli"
)
@ -53,7 +52,7 @@ func prune(clicontext *cli.Context) error {
}
}()
err = c.Prune(appcontext.Context(), ch)
err = c.Prune(commandContext(clicontext), ch)
close(ch)
<-printed
if err != nil {

92
cmd/buildctl/trace.go Normal file
View File

@ -0,0 +1,92 @@
package main
import (
"context"
"io"
"os"
"strings"
"github.com/moby/buildkit/util/appcontext"
opentracing "github.com/opentracing/opentracing-go"
"github.com/opentracing/opentracing-go/ext"
"github.com/opentracing/opentracing-go/log"
jaeger "github.com/uber/jaeger-client-go"
"github.com/urfave/cli"
)
func getTracer() (opentracing.Tracer, io.Closer) {
if traceAddr := os.Getenv("JAEGER_TRACE"); traceAddr != "" {
tr, err := jaeger.NewUDPTransport(traceAddr, 0)
if err != nil {
panic(err)
}
// metricsFactory := prometheus.New()
return jaeger.NewTracer(
"buildctl",
jaeger.NewConstSampler(true),
jaeger.NewRemoteReporter(tr),
)
}
return opentracing.NoopTracer{}, &nopCloser{}
}
func attachAppContext(app *cli.App) {
ctx := appcontext.Context()
tracer, closer := getTracer()
var span opentracing.Span
for i, cmd := range app.Commands {
func(before cli.BeforeFunc) {
name := cmd.Name
app.Commands[i].Before = func(clicontext *cli.Context) error {
if before != nil {
if err := before(clicontext); err != nil {
return err
}
}
span = tracer.StartSpan(name)
span.LogFields(log.String("command", strings.Join(os.Args, " ")))
ctx = opentracing.ContextWithSpan(ctx, span)
clicontext.App.Metadata["context"] = ctx
return nil
}
}(cmd.Before)
}
app.ExitErrHandler = func(clicontext *cli.Context, err error) {
ext.Error.Set(span, true)
cli.HandleExitCoder(err)
}
after := app.After
app.After = func(clicontext *cli.Context) error {
if after != nil {
if err := after(clicontext); err != nil {
return err
}
}
if span != nil {
span.Finish()
}
return closer.Close()
}
}
func commandContext(c *cli.Context) context.Context {
return c.App.Metadata["context"].(context.Context)
}
type nopCloser struct {
}
func (*nopCloser) Close() error {
return nil
}

View File

@ -13,6 +13,7 @@ import (
"github.com/containerd/containerd/sys"
"github.com/docker/go-connections/sockets"
"github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc"
"github.com/moby/buildkit/cache/cacheimport"
"github.com/moby/buildkit/control"
"github.com/moby/buildkit/frontend"
@ -107,7 +108,7 @@ func main() {
return err
}
}
opts := []grpc.ServerOption{unaryInterceptor(ctx)}
opts := []grpc.ServerOption{unaryInterceptor(ctx), grpc.StreamInterceptor(otgrpc.OpenTracingStreamServerInterceptor(tracer))}
creds, err := serverCredentials(c)
if err != nil {
return err
@ -163,6 +164,13 @@ func main() {
return nil
}
app.After = func(context *cli.Context) error {
if closeTracer != nil {
return closeTracer.Close()
}
return nil
}
profiler.Attach(app)
if err := app.Run(os.Args); err != nil {
@ -217,6 +225,8 @@ func getListener(addr string) (net.Listener, error) {
}
func unaryInterceptor(globalCtx context.Context) grpc.ServerOption {
withTrace := otgrpc.OpenTracingServerInterceptor(tracer, otgrpc.LogPayloads())
return grpc.UnaryInterceptor(func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
@ -229,7 +239,7 @@ func unaryInterceptor(globalCtx context.Context) grpc.ServerOption {
}
}()
resp, err = handler(ctx, req)
resp, err = withTrace(ctx, req, info, handler)
if err != nil {
logrus.Errorf("%s returned error: %+v", info.FullMethod, err)
}

31
cmd/buildkitd/trace.go Normal file
View File

@ -0,0 +1,31 @@
package main
import (
"io"
"os"
opentracing "github.com/opentracing/opentracing-go"
jaeger "github.com/uber/jaeger-client-go"
)
var tracer opentracing.Tracer
var closeTracer io.Closer
func init() {
tracer = opentracing.NoopTracer{}
if traceAddr := os.Getenv("JAEGER_TRACE"); traceAddr != "" {
tr, err := jaeger.NewUDPTransport(traceAddr, 0)
if err != nil {
panic(err)
}
tracer, closeTracer = jaeger.NewTracer(
"buildkitd",
jaeger.NewConstSampler(true),
jaeger.NewRemoteReporter(tr),
)
}
}

View File

@ -47,4 +47,12 @@ github.com/docker/distribution 30578ca32960a4d368bf6db67b0a33c2a1f3dc6f
github.com/tonistiigi/units 29de085e9400559bd68aea2e7bc21566e7b8281d
github.com/docker/cli 99576756eb3303b7af8102c502f21a912e3c1af6 https://github.com/tonistiigi/docker-cli.git
github.com/docker/docker-credential-helpers d68f9aeca33f5fd3f08eeae5e9d175edf4e731d1
github.com/docker/libnetwork 822e5b59d346b7ad0735df2c8e445e9787320e67
github.com/docker/libnetwork 822e5b59d346b7ad0735df2c8e445e9787320e67
github.com/grpc-ecosystem/grpc-opentracing 420e5c3331a082e0c873adeeab1819fe1749dd0b git://github.com/tonistiigi/grpc-opentracing.git # pr#25
github.com/opentracing/opentracing-go 1361b9cd60be79c4c3a7fa9841b3c132e40066a7
github.com/uber/jaeger-client-go e02c85f9069ea625a96fc4e1afb5e9ac6c569a6d
github.com/apache/thrift b2a4d4ae21c789b689dd162deb819665567f481c
github.com/uber/jaeger-lib c48167d9cae5887393dd5e61efd06a4a48b7fbb3
github.com/codahale/hdrhistogram f8ad88b59a584afeee9d334eff879b104439117b

239
vendor/github.com/apache/thrift/LICENSE generated vendored Normal file
View File

@ -0,0 +1,239 @@
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 <thomas@randspringer.de>
#
# 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 <douglas@crockford.com>)
--------------------------------------------------

5
vendor/github.com/apache/thrift/NOTICE generated vendored Normal file
View File

@ -0,0 +1,5 @@
Apache Thrift
Copyright 2006-2010 The Apache Software Foundation.
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).

166
vendor/github.com/apache/thrift/README.md generated vendored Normal file
View File

@ -0,0 +1,166 @@
Apache Thrift
=============
+[![Build Status](https://travis-ci.org/apache/thrift.svg?branch=master)](https://travis-ci.org/apache/thrift)
- +[![AppVeyor Build status](https://ci.appveyor.com/api/projects/status/e2qks7enyp9gw7ma?svg=true)](https://ci.appveyor.com/project/apache/thrift)
Introduction
============
Thrift is a lightweight, language-independent software stack with an
associated code generation mechanism for RPC. Thrift provides clean
abstractions for data transport, data serialization, and application
level processing. The code generation system takes a simple definition
language as its input and generates code across programming languages that
uses the abstracted stack to build interoperable RPC clients and servers.
Thrift is specifically designed to support non-atomic version changes
across client and server code.
For more details on Thrift's design and implementation, take a gander at
the Thrift whitepaper included in this distribution or at the README.md files
in your particular subdirectory of interest.
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.
Requirements
============
See http://thrift.apache.org/docs/install for an up-to-date list of build requirements.
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
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/<language>/ folder for more details on the
installation of each language library package.
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.
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.

83
vendor/github.com/apache/thrift/compiler/cpp/README.md generated vendored Normal file
View File

@ -0,0 +1,83 @@
# Build compiler using CMake
Use the following steps to build using cmake:
mkdir cmake-build
cd cmake-build
cmake ..
make
### Create an eclipse project
mkdir cmake-ec && cd cmake-ec
cmake -G "Eclipse CDT4 - Unix Makefiles" ..
make
Now open the folder cmake-ec using eclipse.
### Cross compile using mingw32 and generate a Windows Installer with CPack
mkdir cmake-mingw32 && cd cmake-mingw32
cmake -DCMAKE_TOOLCHAIN_FILE=../build/cmake/mingw32-toolchain.cmake -DBUILD_COMPILER=ON -DBUILD_LIBRARIES=OFF -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF ..
cpack
## Build on windows
### using Git Bash
Git Bash provides flex and bison, so you just need to do this:
mkdir cmake-vs && cd cmake-vs
cmake -DWITH_SHARED_LIB=off ..
### using Win flex-bison
In order to build on windows with winflexbison a few additional steps are necessary:
1. Download winflexbison from http://sourceforge.net/projects/winflexbison/
2. Extract the winflex bison files to for e.g. C:\winflexbison
3. Make the CMake variables point to the correct binaries.
* FLEX_EXECUTABLE = C:/winbuild/win_flex.exe
* BISON_EXECUTABLE = C:/winbuild/win_bison.exe
4. Generate a Visual Studio project:
```
mkdir cmake-vs && cd cmake-vs
cmake -G "Visual Studio 12" -DWITH_SHARED_LIB=off ..
```
5. Now open the folder build_vs using Visual Studio 2013.
# Building the Thrift IDL compiler in Windows
If you don't want to use CMake you can use the already available Visual Studio
2010 solution.
The Visual Studio project contains pre-build commands to generate the
thriftl.cc, thrifty.cc and thrifty.hh files which are necessary to build
the compiler. These depend on bison, flex and their dependencies to
work properly.
Download flex & bison as described above.
Place these binaries somewhere in the path and
rename win_flex.exe and win_bison.exe to flex.exe and bison.exe respectively.
If this doesn't work on a system, try these manual pre-build steps.
Open compiler.sln and remove the Pre-build commands under the project's
Properties -> Build Events -> Pre-Build Events.
From a command prompt:
> cd thrift/compiler/cpp
> flex -osrc\thrift\thriftl.cc src\thrift\thriftl.ll
In the generated thriftl.cc, comment out #include <unistd.h>
Place a copy of bison.simple in thrift/compiler/cpp
> bison -y -o "src/thrift/thrifty.cc" --defines src/thrift/thrifty.yy
> move src\thrift\thrifty.cc.hh src\thrift\thrifty.hh
Bison might generate the yacc header file "thrifty.cc.h" with just one h ".h" extension; in this case you'll have to rename to "thrifty.h".
> move src\thrift\version.h.in src\thrift\version.h
Download inttypes.h from the interwebs and place it in an include path
location (e.g. thrift/compiler/cpp/src).
Build the compiler in Visual Studio.

View File

@ -0,0 +1,66 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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
#include <io.h>
#include <stdlib.h>
#include <direct.h>
#define strtoll(begin_ptr, end_ptr, length) _strtoi64(begin_ptr, end_ptr, length)
#define PRIu64 "I64d"
#define PRIi64 "I64d"
// squelch deprecation warnings
#pragma warning(disable : 4996)
// squelch bool conversion performance warning
#pragma warning(disable : 4800)
// MSVC10 (2010) or later has stdint.h
#if _MSC_VER >= 1600
#define HAVE_STDINT_H 1
#endif
// Must be using VS2010 or later, or boost, so that C99 types are defined in the global namespace
#ifdef HAVE_STDINT_H
#include <stdint.h>
#else
#include <boost/cstdint.hpp>
typedef boost::int64_t int64_t;
typedef boost::uint64_t uint64_t;
typedef boost::int32_t int32_t;
typedef boost::uint32_t uint32_t;
typedef boost::int16_t int16_t;
typedef boost::uint16_t uint16_t;
typedef boost::int8_t int8_t;
typedef boost::uint8_t uint8_t;
#endif
#endif // _THRIFT_WINDOWS_CONFIG_H_

34
vendor/github.com/apache/thrift/lib/c_glib/README.md generated vendored Normal file
View File

@ -0,0 +1,34 @@
Thrift 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/

View File

@ -0,0 +1,143 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <thrift/c_glib/thrift.h>
#include <thrift/c_glib/thrift_application_exception.h>
#include <thrift/c_glib/processor/thrift_dispatch_processor.h>
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;
}

View File

@ -0,0 +1,95 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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 <glib-object.h>
#include <thrift/c_glib/processor/thrift_processor.h>
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 */

View File

@ -0,0 +1,45 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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/c_glib/thrift.h>
#include <thrift/c_glib/processor/thrift_processor.h>
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);
}

View File

@ -0,0 +1,76 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef _THRIFT_PROCESSOR_H
#define _THRIFT_PROCESSOR_H
#include <glib-object.h>
#include <thrift/c_glib/protocol/thrift_protocol.h>
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 */

View File

@ -0,0 +1,904 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <string.h>
#include <stdio.h>
#include <thrift/c_glib/thrift.h>
#include <thrift/c_glib/protocol/thrift_protocol.h>
#include <thrift/c_glib/protocol/thrift_binary_protocol.h>
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);
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;
}
*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);
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;
}
*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)
{
/* allocate the memory for the string */
len = (guint32) read_len + 1; /* space for null terminator */
*str = g_new0 (gchar, len);
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 = NULL;
}
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)
{
/* 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;
}
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 = THRIFT_PROTOCOL_CLASS (klass);
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;
}

View File

@ -0,0 +1,72 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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 <glib-object.h>
#include <thrift/c_glib/protocol/thrift_protocol.h>
#include <thrift/c_glib/transport/thrift_transport.h>
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;
};
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);
G_END_DECLS
#endif /* _THRIFT_BINARY_PROTOCOL_H */

View File

@ -0,0 +1,50 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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/c_glib/thrift.h>
#include <thrift/c_glib/protocol/thrift_binary_protocol.h>
#include <thrift/c_glib/protocol/thrift_binary_protocol_factory.h>
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);
}

View File

@ -0,0 +1,56 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef _THRIFT_BINARY_PROTOCOL_FACTORY_H
#define _THRIFT_BINARY_PROTOCOL_FACTORY_H
#include <glib-object.h>
#include <thrift/c_glib/protocol/thrift_protocol_factory.h>
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 */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,107 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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 <glib.h>
#include <glib-object.h>
#include <thrift/c_glib/protocol/thrift_protocol.h>
#include <thrift/c_glib/transport/thrift_transport.h>
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 */

View File

@ -0,0 +1,140 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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/c_glib/thrift.h>
#include <thrift/c_glib/protocol/thrift_compact_protocol.h>
#include <thrift/c_glib/protocol/thrift_compact_protocol_factory.h>
/* 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);
}

View File

@ -0,0 +1,70 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef _THRIFT_COMPACT_PROTOCOL_FACTORY_H
#define _THRIFT_COMPACT_PROTOCOL_FACTORY_H
#include <glib-object.h>
#include <thrift/c_glib/protocol/thrift_protocol_factory.h>
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 */

View File

@ -0,0 +1,605 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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/c_glib/thrift.h>
#include <thrift/c_glib/protocol/thrift_protocol.h>
#include <thrift/c_glib/transport/thrift_transport.h>
/* 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_get_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);
}
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;
guint32 len;
gint32 ret = thrift_protocol_read_binary (protocol, &data, &len, error);
g_free (data);
return ret;
}
case T_STRUCT:
{
guint32 result = 0;
gchar *name;
gint16 fid;
ThriftType ftype;
result += thrift_protocol_read_struct_begin (protocol, &name, error);
while (1)
{
result += thrift_protocol_read_field_begin (protocol, &name, &ftype,
&fid, error);
if (ftype == T_STOP)
{
break;
}
result += thrift_protocol_skip (protocol, ftype, error);
result += thrift_protocol_read_field_end (protocol, error);
}
result += thrift_protocol_read_struct_end (protocol, error);
return result;
}
case T_SET:
{
guint32 result = 0;
ThriftType elem_type;
guint32 i, size;
result += thrift_protocol_read_set_begin (protocol, &elem_type, &size,
error);
for (i = 0; i < size; i++)
{
result += thrift_protocol_skip (protocol, elem_type, error);
}
result += thrift_protocol_read_set_end (protocol, error);
return result;
}
case T_MAP:
{
guint32 result = 0;
ThriftType elem_type;
ThriftType key_type;
guint32 i, size;
result += thrift_protocol_read_map_begin (protocol, &key_type, &elem_type, &size,
error);
for (i = 0; i < size; i++)
{
result += thrift_protocol_skip (protocol, key_type, error);
result += thrift_protocol_skip (protocol, elem_type, error);
}
result += thrift_protocol_read_map_end (protocol, error);
return result;
}
case T_LIST:
{
guint32 result = 0;
ThriftType elem_type;
guint32 i, size;
result += thrift_protocol_read_list_begin (protocol, &elem_type, &size,
error);
for (i = 0; i < size; i++)
{
result += thrift_protocol_skip (protocol, elem_type, error);
}
result += thrift_protocol_read_list_end (protocol, error);
return result;
}
default:
return 0;
}
}
/* 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_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;
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;
}

View File

@ -0,0 +1,341 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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 <glib-object.h>
#include <thrift/c_glib/transport/thrift_transport.h>
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);
};
/* 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);
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 */

View File

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

View File

@ -0,0 +1,73 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef _THRIFT_PROTOCOL_FACTORY_H
#define _THRIFT_PROTOCOL_FACTORY_H
#include <glib-object.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include <thrift/c_glib/protocol/thrift_protocol.h>
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 */

View File

@ -0,0 +1,174 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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/c_glib/thrift.h>
#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:
server->processor = g_value_get_object (value);
break;
case PROP_THRIFT_SERVER_SERVER_TRANSPORT:
server->server_transport = g_value_get_object (value);
break;
case PROP_THRIFT_SERVER_INPUT_TRANSPORT_FACTORY:
server->input_transport_factory = g_value_get_object (value);
break;
case PROP_THRIFT_SERVER_OUTPUT_TRANSPORT_FACTORY:
server->output_transport_factory = g_value_get_object (value);
break;
case PROP_THRIFT_SERVER_INPUT_PROTOCOL_FACTORY:
server->input_protocol_factory = g_value_get_object (value);
break;
case PROP_THRIFT_SERVER_OUTPUT_PROTOCOL_FACTORY:
server->output_protocol_factory = g_value_get_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;
}
/* 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;
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;
}

View File

@ -0,0 +1,93 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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 <glib-object.h>
#include <thrift/c_glib/processor/thrift_processor.h>
#include <thrift/c_glib/transport/thrift_server_transport.h>
#include <thrift/c_glib/transport/thrift_transport_factory.h>
#include <thrift/c_glib/protocol/thrift_protocol_factory.h>
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 */

View File

@ -0,0 +1,138 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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/c_glib/server/thrift_simple_server.h>
#include <thrift/c_glib/transport/thrift_transport_factory.h>
#include <thrift/c_glib/protocol/thrift_protocol_factory.h>
#include <thrift/c_glib/protocol/thrift_binary_protocol_factory.h>
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);
}
}
/* 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;
}

View File

@ -0,0 +1,70 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef _THRIFT_SIMPLE_SERVER_H
#define _THRIFT_SIMPLE_SERVER_H
#include <glib-object.h>
#include <thrift/c_glib/server/thrift_server.h>
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 */

View File

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

View File

@ -0,0 +1,49 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef _THRIFT_H
#define _THRIFT_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <glib.h>
/* 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 */

View File

@ -0,0 +1,277 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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 <thrift/c_glib/protocol/thrift_protocol.h>
/* 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);
}

View File

@ -0,0 +1,86 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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 <glib-object.h>
#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 */

View File

@ -0,0 +1,52 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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/c_glib/thrift.h>
#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);
}

View File

@ -0,0 +1,68 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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 <glib-object.h>
#include <thrift/c_glib/protocol/thrift_protocol.h>
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

View File

@ -0,0 +1,391 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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 <assert.h>
#include <netdb.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <thrift/c_glib/thrift.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include <thrift/c_glib/transport/thrift_buffered_transport.h>
/* 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
};
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_alloca (len);
guint32 have = t->r_buf->len;
/* we shouldn't hit this unless the buffer doesn't have enough to read */
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) {
return ret;
}
got += ret;
/* copy the data starting from where we left off */
memcpy ((guint8 *)buf + have, tmpdata, got);
return got + have;
} else {
guint32 give;
if ((ret = THRIFT_TRANSPORT_GET_CLASS (t->transport)->read (t->transport,
tmpdata,
want,
error)) < 0) {
return ret;
}
got += ret;
t->r_buf = g_byte_array_append (t->r_buf, tmpdata, got);
/* 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);
/* 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);
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);
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;
}
}
/* property mutator */
void
thrift_buffered_transport_set_property (GObject *object, guint property_id,
const GValue *value, GParamSpec *pspec)
{
ThriftBufferedTransport *transport = THRIFT_BUFFERED_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;
}
}
/* 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);
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;
}

View File

@ -0,0 +1,77 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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 <glib.h>
#include <glib-object.h>
#include <thrift/c_glib/transport/thrift_transport.h>
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

View File

@ -0,0 +1,55 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <thrift/c_glib/thrift.h>
#include <thrift/c_glib/transport/thrift_buffered_transport.h>
#include <thrift/c_glib/transport/thrift_buffered_transport_factory.h>
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;
}

View File

@ -0,0 +1,86 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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 <glib-object.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include <thrift/c_glib/transport/thrift_transport_factory.h>
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 */

View File

@ -0,0 +1,265 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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 <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <glib.h>
#include <glib/gstdio.h>
#include <thrift/c_glib/thrift.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include <thrift/c_glib/transport/thrift_fd_transport.h>
/* object properties */
enum _ThriftFDTransportProperties
{
PROP_0,
PROP_THRIFT_FD_TRANSPORT_FD
};
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);
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);
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);
switch (property_id) {
case PROP_THRIFT_FD_TRANSPORT_FD:
g_value_set_int (value, t->fd);
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);
switch (property_id) {
case PROP_THRIFT_FD_TRANSPORT_FD:
t->fd = g_value_get_int (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);
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;
}

View File

@ -0,0 +1,74 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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 <glib-object.h>
#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 */

View File

@ -0,0 +1,384 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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 <assert.h>
#include <netdb.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <thrift/c_glib/thrift.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include <thrift/c_glib/transport/thrift_framed_transport.h>
/* 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
};
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);
/* create a buffer to hold the data and read that much data */
tmpdata = g_alloca (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;
}
}
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 */
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);
/* 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);
gint32 sz_hbo, sz_nbo;
guchar *tmpdata;
/* 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_alloca (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);
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 ();
}
/* 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);
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;
}
}
/* property mutator */
void
thrift_framed_transport_set_property (GObject *object, guint property_id,
const GValue *value, GParamSpec *pspec)
{
ThriftFramedTransport *transport = THRIFT_FRAMED_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;
}
}
/* 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);
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;
}

View File

@ -0,0 +1,77 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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 <glib.h>
#include <glib-object.h>
#include <thrift/c_glib/transport/thrift_transport.h>
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 */
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

View File

@ -0,0 +1,55 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <thrift/c_glib/thrift.h>
#include <thrift/c_glib/transport/thrift_framed_transport.h>
#include <thrift/c_glib/transport/thrift_framed_transport_factory.h>
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;
}

View File

@ -0,0 +1,86 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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 <glib-object.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include <thrift/c_glib/transport/thrift_transport_factory.h>
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 */

View File

@ -0,0 +1,286 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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 <assert.h>
#include <netdb.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <thrift/c_glib/thrift.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include <thrift/c_glib/transport/thrift_memory_buffer.h>
/* object properties */
enum _ThriftMemoryBufferProperties
{
PROP_0,
PROP_THRIFT_MEMORY_BUFFER_BUFFER_SIZE,
PROP_THRIFT_MEMORY_BUFFER_BUFFER,
PROP_THRIFT_MEMORY_BUFFER_OWNER
};
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);
guint32 give = len;
THRIFT_UNUSED_VAR (error);
/* 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;
}
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);
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;
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);
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;
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);
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;
}

View File

@ -0,0 +1,72 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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 <glib.h>
#include <glib-object.h>
#include <thrift/c_glib/transport/thrift_transport.h>
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

View File

@ -0,0 +1,253 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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 <errno.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <thrift/c_glib/thrift.h>
#include <thrift/c_glib/transport/thrift_socket.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include <thrift/c_glib/transport/thrift_server_transport.h>
#include <thrift/c_glib/transport/thrift_server_socket.h>
/* object properties */
enum _ThriftServerSocketProperties
{
PROP_0,
PROP_THRIFT_SERVER_SOCKET_PORT,
PROP_THRIFT_SERVER_SOCKET_BACKLOG
};
/* 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() */
struct sockaddr_in pin;
ThriftServerSocket *tsocket = THRIFT_SERVER_SOCKET (transport);
/* create a address structure */
memset (&pin, 0, sizeof(pin));
pin.sin_family = AF_INET;
pin.sin_addr.s_addr = INADDR_ANY;
pin.sin_port = htons(tsocket->port);
/* create a socket */
if ((tsocket->sd = socket (AF_INET, 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));
return FALSE;
}
/* bind to the socket */
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));
return FALSE;
}
if (listen(tsocket->sd, tsocket->backlog) == -1)
{
g_set_error (error, THRIFT_SERVER_SOCKET_ERROR,
THRIFT_SERVER_SOCKET_ERROR_LISTEN,
"failed to listen to port %d - %s",
tsocket->port, strerror(errno));
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);
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 FALSE;
}
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);
switch (property_id)
{
case PROP_THRIFT_SERVER_SOCKET_PORT:
g_value_set_uint (value, socket->port);
break;
case PROP_THRIFT_SERVER_SOCKET_BACKLOG:
g_value_set_uint (value, socket->backlog);
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);
switch (property_id)
{
case PROP_THRIFT_SERVER_SOCKET_PORT:
socket->port = g_value_get_uint (value);
break;
case PROP_THRIFT_SERVER_SOCKET_BACKLOG:
socket->backlog = g_value_get_uint (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 */
65534, /* 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_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);
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;
}

View File

@ -0,0 +1,90 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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 <glib-object.h>
#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 */
gshort port;
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

View File

@ -0,0 +1,62 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <thrift/c_glib/thrift.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include <thrift/c_glib/transport/thrift_server_transport.h>
G_DEFINE_ABSTRACT_TYPE(ThriftServerTransport, thrift_server_transport, G_TYPE_OBJECT)
/* base initializer for the server transport interface */
static void
thrift_server_transport_class_init (ThriftServerTransportClass *c)
{
c->listen = thrift_server_transport_listen;
c->accept = thrift_server_transport_accept;
c->close = thrift_server_transport_close;
}
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);
}

View File

@ -0,0 +1,89 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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 <glib-object.h>
#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;
};
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);
};
/* 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 */

View File

@ -0,0 +1,368 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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 <errno.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <thrift/c_glib/thrift.h>
#include <thrift/c_glib/transport/thrift_transport.h>
#include <thrift/c_glib/transport/thrift_socket.h>
/* object properties */
enum _ThriftSocketProperties
{
PROP_0,
PROP_THRIFT_SOCKET_HOSTNAME,
PROP_THRIFT_SOCKET_PORT
};
G_DEFINE_TYPE(ThriftSocket, thrift_socket, THRIFT_TYPE_TRANSPORT)
/* 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_open */
gboolean
thrift_socket_open (ThriftTransport *transport, GError **error)
{
struct hostent *hp = NULL;
struct sockaddr_in pin;
int err;
#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);
/* 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))->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)
{
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));
return FALSE;
}
return TRUE;
}
/* 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_read */
gint32
thrift_socket_read (ThriftTransport *transport, gpointer buf,
guint32 len, GError **error)
{
gint ret = 0;
guint got = 0;
ThriftSocket *socket = THRIFT_SOCKET (transport);
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->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);
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;
}
}
/* property mutator */
void
thrift_socket_set_property (GObject *object, guint property_id,
const GValue *value, GParamSpec *pspec)
{
ThriftSocket *socket = THRIFT_SOCKET (object);
THRIFT_UNUSED_VAR (pspec);
switch (property_id)
{
case PROP_THRIFT_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;
}
}
/* 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",
0, /* min */
65534, /* 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);
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;
}

View File

@ -0,0 +1,75 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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 <glib-object.h>
#include <thrift/c_glib/transport/thrift_transport.h>
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;
gshort port;
int sd;
guint8 *buf;
guint32 buf_size;
guint32 buf_len;
};
typedef struct _ThriftSocketClass ThriftSocketClass;
/*!
* Thrift Socket class.
*/
struct _ThriftSocketClass
{
ThriftTransportClass parent;
};
/* used by THRIFT_TYPE_SOCKET */
GType thrift_socket_get_type (void);
G_END_DECLS
#endif

View File

@ -0,0 +1,162 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <thrift/c_glib/thrift.h>
#include <thrift/c_glib/transport/thrift_transport.h>
/* 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;
}
/* define the GError domain for Thrift transports */
GQuark
thrift_transport_error_quark (void)
{
return g_quark_from_static_string (THRIFT_TRANSPORT_ERROR_DOMAIN);
}
/* class initializer for ThriftTransport */
static void
thrift_transport_class_init (ThriftTransportClass *cls)
{
/* 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;
}
static void
thrift_transport_init (ThriftTransport *transport)
{
THRIFT_UNUSED_VAR (transport);
}

View File

@ -0,0 +1,176 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef _THRIFT_TRANSPORT_H
#define _THRIFT_TRANSPORT_H
#include <glib-object.h>
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;
};
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);
};
/* 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
} 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 */

View File

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

View File

@ -0,0 +1,71 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef _THRIFT_TRANSPORT_FACTORY_H
#define _THRIFT_TRANSPORT_FACTORY_H
#include <glib-object.h>
#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 */

21
vendor/github.com/apache/thrift/lib/cocoa/README.md generated vendored Normal file
View File

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

View File

@ -0,0 +1,55 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import "TProtocol.h"
extern NSString *TApplicationErrorDomain;
typedef NS_ENUM (int, TApplicationError) {
TApplicationErrorUnknown = 0,
TApplicationErrorUnknownMethod = 1,
TApplicationErrorInvalidMessageType = 2,
TApplicationErrorWrongMethodName = 3,
TApplicationErrorBadSequenceId = 4,
TApplicationErrorMissingResult = 5,
TApplicationErrorInternalError = 6,
TApplicationErrorProtocolError = 7,
TApplicationErrorInvalidTransform = 8,
TApplicationErrorInvalidProtocol = 9,
TApplicationErrorUnsupportedClientType = 10,
};
extern NSString *TApplicationErrorNameKey;
extern NSString *TApplicationErrorReasonKey;
extern NSString *TApplicationErrorMethodKey;
@interface NSError (TApplicationError)
@property (readonly, copy) NSString *name;
@property (readonly, copy) NSString *reason;
+(instancetype) errorWithType:(TApplicationError)type reason:(NSString *)reason;
+(instancetype) read:(id<TProtocol>)protocol;
-(BOOL) write:(id<TProtocol>)outProtocol error:(NSError *__autoreleasing *)error;
@end

View File

@ -0,0 +1,27 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import "TProtocol.h"
#import "TApplicationError.h"
@interface TBaseClient : NSObject
-(NSError *) checkIncomingMessageException:(id<TProtocol>)protocol;
@end

23
vendor/github.com/apache/thrift/lib/cocoa/src/TError.h generated vendored Normal file
View File

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

View File

@ -0,0 +1,35 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import <Foundation/Foundation.h>
#import "TProtocol.h"
NS_ASSUME_NONNULL_BEGIN
@protocol TProcessor <NSObject>
-(BOOL) processOnInputProtocol:(id <TProtocol>)inProtocol
outputProtocol:(id <TProtocol>)outProtocol
error:(NSError **)error;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,33 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import <Foundation/Foundation.h>
#import "TProcessor.h"
NS_ASSUME_NONNULL_BEGIN
@protocol TProcessorFactory <NSObject>
-(id<TProcessor>) processorForTransport:(id<TTransport>)transport;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,28 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import <Foundation/Foundation.h>
#import "TProcessorFactory.h"
@interface TSharedProcessorFactory : NSObject <TProcessorFactory>
-(id) initWithSharedProcessor:(id<TProcessor>)sharedProcessor;
@end

20
vendor/github.com/apache/thrift/lib/cocoa/src/Thrift.h generated vendored Normal file
View File

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

View File

@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import <Foundation/Foundation.h>
#import "TProtocol.h"
@protocol TBase <NSObject>
/**
* De-serialize object from the given input protocol
*
* @param input protocol used for reading
*/
-(BOOL) read:(id <TProtocol>)inProtocol error:(NSError **)error;
/**
* Serialize object to the given protocol
*
* @param buf output protocol used for writing
*/
-(BOOL) write:(id <TProtocol>)outProtocol error:(NSError **)error;
/**
* Validate required fields
*/
-(BOOL) validate:(NSError *__autoreleasing *)__thriftError;
@end

View File

@ -0,0 +1,49 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import "TProtocol.h"
#import "TTransport.h"
#import "TProtocolFactory.h"
NS_ASSUME_NONNULL_BEGIN
@interface TBinaryProtocol : NSObject <TProtocol>
@property (assign, nonatomic) UInt32 messageSizeLimit;
-(id) initWithTransport:(id <TTransport>)transport;
-(id) initWithTransport:(id <TTransport>)transport
strictRead:(BOOL)strictRead
strictWrite:(BOOL)strictWrite;
@end;
@interface TBinaryProtocolFactory : NSObject <TProtocolFactory>
+(TBinaryProtocolFactory *) sharedFactory;
-(TBinaryProtocol *) newProtocolOnTransport:(id <TTransport>)transport;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,42 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import "TProtocol.h"
#import "TTransport.h"
#import "TProtocolFactory.h"
NS_ASSUME_NONNULL_BEGIN
@interface TCompactProtocol : NSObject <TProtocol>
-(id) initWithTransport:(id <TTransport>)transport;
@end
@interface TCompactProtocolFactory : NSObject <TProtocolFactory>
+(TCompactProtocolFactory *) sharedFactory;
-(TCompactProtocol *) newProtocolOnTransport:(id <TTransport>)transport;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,38 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import <Foundation/Foundation.h>
#import "TProtocolDecorator.h"
NS_ASSUME_NONNULL_BEGIN
extern NSString *TMultiplexedProtocolSeperator;
@interface TMultiplexedProtocol : TProtocolDecorator
-(id) initWithProtocol:(id <TProtocol>)protocol
serviceName:(NSString *)name;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,164 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import <Foundation/Foundation.h>
#import "TTransport.h"
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM (int, TMessageType) {
TMessageTypeCALL = 1,
TMessageTypeREPLY = 2,
TMessageTypeEXCEPTION = 3,
TMessageTypeONEWAY = 4
};
typedef NS_ENUM (int, TType) {
TTypeSTOP = 0,
TTypeVOID = 1,
TTypeBOOL = 2,
TTypeBYTE = 3,
TTypeDOUBLE = 4,
TTypeI16 = 6,
TTypeI32 = 8,
TTypeI64 = 10,
TTypeSTRING = 11,
TTypeSTRUCT = 12,
TTypeMAP = 13,
TTypeSET = 14,
TTypeLIST = 15
};
@protocol TProtocol <NSObject>
-(id <TTransport>) transport;
-(BOOL) readMessageBeginReturningName:(NSString *__nullable __autoreleasing *__nullable)name
type:(nullable SInt32 *)type
sequenceID:(nullable SInt32 *)sequenceID
error:(NSError *__autoreleasing *)error;
-(BOOL) readMessageEnd:(NSError *__autoreleasing *)error;
-(BOOL) readStructBeginReturningName:(NSString *__nullable __autoreleasing *__nullable)name
error:(NSError *__autoreleasing *)error;
-(BOOL) readStructEnd:(NSError *__autoreleasing *)error;
-(BOOL) readFieldBeginReturningName:(NSString *__nullable __autoreleasing *__nullable)name
type:(SInt32 *)fieldType
fieldID:(nullable SInt32 *)fieldID
error:(NSError *__autoreleasing *)error;
-(BOOL) readFieldEnd:(NSError *__autoreleasing *)error;
-(BOOL) readString:(NSString *__nonnull __autoreleasing *__nonnull)value error:(NSError **)error;
-(BOOL) readBool:(BOOL *)value error:(NSError *__autoreleasing *)error;
-(BOOL) readByte:(UInt8 *)value error:(NSError *__autoreleasing *)error;
-(BOOL) readI16:(SInt16 *)value error:(NSError *__autoreleasing *)error;
-(BOOL) readI32:(SInt32 *)value error:(NSError *__autoreleasing *)error;
-(BOOL) readI64:(SInt64 *)value error:(NSError *__autoreleasing *)error;
-(BOOL) readDouble:(double *)value error:(NSError *__autoreleasing *)error;
-(BOOL) readBinary:(NSData *__nonnull __autoreleasing *__nonnull)value error:(NSError **)error;
-(BOOL) readMapBeginReturningKeyType:(nullable SInt32 *)keyType
valueType:(nullable SInt32 *)valueType
size:(SInt32 *)size
error:(NSError *__autoreleasing *)error;
-(BOOL) readMapEnd:(NSError *__autoreleasing *)error;
-(BOOL) readSetBeginReturningElementType:(nullable SInt32 *)elementType
size:(SInt32 *)size
error:(NSError *__autoreleasing *)error;
-(BOOL) readSetEnd:(NSError *__autoreleasing *)error;
-(BOOL) readListBeginReturningElementType:(nullable SInt32 *)elementType
size:(SInt32 *)size
error:(NSError *__autoreleasing *)error;
-(BOOL) readListEnd:(NSError *__autoreleasing *)error;
-(BOOL) writeMessageBeginWithName:(NSString *)name
type:(SInt32)messageType
sequenceID:(SInt32)sequenceID
error:(NSError *__autoreleasing *)error;
-(BOOL) writeMessageEnd:(NSError *__autoreleasing *)error;
-(BOOL) writeStructBeginWithName:(NSString *)name error:(NSError **)error;
-(BOOL) writeStructEnd:(NSError *__autoreleasing *)error;
-(BOOL) writeFieldBeginWithName:(NSString *)name
type:(SInt32)fieldType
fieldID:(SInt32)fieldID
error:(NSError *__autoreleasing *)error;
-(BOOL) writeI32:(SInt32)value error:(NSError *__autoreleasing *)error;
-(BOOL) writeI64:(SInt64)value error:(NSError *__autoreleasing *)error;
-(BOOL) writeI16:(short)value error:(NSError *__autoreleasing *)error;
-(BOOL) writeByte:(UInt8)value error:(NSError *__autoreleasing *)error;
-(BOOL) writeString:(NSString *)value error:(NSError *__autoreleasing *)error;
-(BOOL) writeDouble:(double)value error:(NSError *__autoreleasing *)error;
-(BOOL) writeBool:(BOOL)value error:(NSError *__autoreleasing *)error;
-(BOOL) writeBinary:(NSData *)data error:(NSError *__autoreleasing *)error;
-(BOOL) writeFieldStop:(NSError *__autoreleasing *)error;
-(BOOL) writeFieldEnd:(NSError *__autoreleasing *)error;
-(BOOL) writeMapBeginWithKeyType:(SInt32)keyType
valueType:(SInt32)valueType
size:(SInt32)size
error:(NSError *__autoreleasing *)error;
-(BOOL) writeMapEnd:(NSError *__autoreleasing *)error;
-(BOOL) writeSetBeginWithElementType:(SInt32)elementType
size:(SInt32)size
error:(NSError *__autoreleasing *)error;
-(BOOL) writeSetEnd:(NSError *__autoreleasing *)error;
-(BOOL) writeListBeginWithElementType:(SInt32)elementType
size:(SInt32)size
error:(NSError *__autoreleasing *)error;
-(BOOL) writeListEnd:(NSError *__autoreleasing *)error;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,34 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import <Foundation/Foundation.h>
#import "TProtocol.h"
NS_ASSUME_NONNULL_BEGIN
@interface TProtocolDecorator : NSObject <TProtocol>
-(id) initWithProtocol:(id <TProtocol>)protocol;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,76 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import "TError.h"
extern NSString *TProtocolErrorDomain;
typedef NS_ENUM (int, TProtocolError) {
TProtocolErrorUnknown = 0,
TProtocolErrorInvalidData = 1,
TProtocolErrorNegativeSize = 2,
TProtocolErrorSizeLimit = 3,
TProtocolErrorBadVersion = 4,
TProtocolErrorNotImplemented = 5,
TProtocolErrorDepthLimit = 6,
};
typedef NS_ENUM(int, TProtocolExtendedError) {
TProtocolExtendedErrorMissingRequiredField = 1001,
TProtocolExtendedErrorUnexpectedType = 1002,
TProtocolExtendedErrorMismatchedProtocol = 1003,
};
extern NSString *TProtocolErrorExtendedErrorKey;
extern NSString *TProtocolErrorFieldNameKey;
extern NSString *TProtocolErrorExpectedIdKey;
extern NSString *TProtocolErrorExpectedVersionKey;
extern NSString *TProtocolErrorTypeKey;
extern NSString *TProtocolErrorSourceLineKey;
extern NSString *TProtocolErrorSourceFileKey;
extern NSString *TProtocolErrorSourceMethodKey;
extern NSString *TProtocolErrorMessageNameKey;
#define PROTOCOL_ERROR(ret, err, ...) \
if (error) { \
*error = [NSError errorWithDomain:TProtocolErrorDomain \
code:TProtocolError ## err \
userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat:__VA_ARGS__], \
@"SourceFile": [NSString stringWithUTF8String:__FILE__], \
@"SourceLine": @(__LINE__), \
@"SourceFunction": [NSString stringWithUTF8String:__PRETTY_FUNCTION__], \
@"Message": self.currentMessageName ? self.currentMessageName : @""}]; \
} \
return ret
#define PROTOCOL_TRANSPORT_ERROR(ret, errorPtr, ...) \
if (errorPtr) { \
*error = [NSError errorWithDomain:TProtocolErrorDomain \
code:TProtocolErrorUnknown \
userInfo:@{NSLocalizedDescriptionKey: [[NSString stringWithFormat:__VA_ARGS__] stringByAppendingFormat:@": %@", [(*errorPtr) localizedDescription]], \
TProtocolErrorSourceFileKey: [NSString stringWithUTF8String:__FILE__], \
TProtocolErrorSourceLineKey: @(__LINE__), \
TProtocolErrorSourceMethodKey: [NSString stringWithUTF8String:__PRETTY_FUNCTION__], \
TProtocolErrorMessageNameKey: self.currentMessageName ? self.currentMessageName : @"", \
NSUnderlyingErrorKey: *errorPtr}]; \
} \
return ret

View File

@ -0,0 +1,36 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import <Foundation/Foundation.h>
#import "TProtocol.h"
#import "TTransport.h"
NS_ASSUME_NONNULL_BEGIN
@protocol TProtocolFactory <NSObject>
@property (readonly, nonatomic) NSString *protocolName;
-(id<TProtocol>) newProtocolOnTransport:(id<TTransport>)transport;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,33 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import "TProtocol.h"
#import "TTransport.h"
NS_ASSUME_NONNULL_BEGIN
@interface TProtocolUtil : NSObject
+(BOOL) skipType:(int)type onProtocol:(id <TProtocol>)protocol error:(NSError **)error;
@end;
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,47 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import <Foundation/Foundation.h>
#import "TProtocolFactory.h"
#import "TProcessorFactory.h"
#if !TARGET_OS_IPHONE
#import <CoreServices/CoreServices.h>
#else
#import <CFNetwork/CFNetwork.h>
#endif
NS_ASSUME_NONNULL_BEGIN
extern NSString *const TSocketServerClientConnectionFinished;
extern NSString *const TSocketServerProcessorKey;
extern NSString *const TSockerServerTransportKey;
@interface TSocketServer : NSObject
-(instancetype) initWithPort:(int)port
protocolFactory:(id <TProtocolFactory>)protocolFactory
processorFactory:(id <TProcessorFactory>)processorFactory;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import "TTransport.h"
NS_ASSUME_NONNULL_BEGIN
@protocol TAsyncTransport;
@protocol TAsyncTransportFactory <NSObject>
-(id<TAsyncTransport>) newTransport;
@end
typedef void (^TAsyncCompletionBlock)();
typedef void (^TAsyncFailureBlock)(NSError * __nonnull);
@protocol TAsyncTransport <TTransport>
-(void) flushWithCompletion:(TAsyncCompletionBlock)completed failure:(TAsyncFailureBlock)failure;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,33 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import <Foundation/Foundation.h>
#import "TTransport.h"
NS_ASSUME_NONNULL_BEGIN
@interface TFramedTransport : NSObject <TTransport>
-(id) initWithTransport:(id <TTransport>)transport;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,47 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import <Foundation/Foundation.h>
#import "TAsyncTransport.h"
NS_ASSUME_NONNULL_BEGIN
typedef NSError *__nullable (^THTTPSessionTransportResponseValidateBlock) (NSHTTPURLResponse *response, NSData *responseData);
@interface THTTPSessionTransportFactory : NSObject<TAsyncTransportFactory>
@property (strong, nonatomic) THTTPSessionTransportResponseValidateBlock responseValidate;
+(void) setupDefaultsForSessionConfiguration:(NSURLSessionConfiguration *)config
withProtocolName:(NSString *)protocolName;
-(id) initWithSession:(NSURLSession *)session
URL:(NSURL *)aURL;
@end
@interface THTTPSessionTransport : NSObject <TAsyncTransport>
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,39 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import <Foundation/Foundation.h>
#import "TTransport.h"
NS_ASSUME_NONNULL_BEGIN
@interface THTTPTransport : NSObject <TTransport>
-(id) initWithURL:(NSURL *)aURL;
-(id) initWithURL:(NSURL *)aURL
userAgent:(nullable NSString *)userAgent
timeout:(int)timeout;
-(void) setURL:(NSURL *)aURL;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,37 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import <Foundation/Foundation.h>
#import "TTransport.h"
NS_ASSUME_NONNULL_BEGIN
@interface TMemoryBuffer : NSObject <TTransport>
-(NSData *) buffer;
-(id) initWithData:(NSData *)data;
-(id) initWithDataNoCopy:(NSMutableData *)data;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,38 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import <Foundation/Foundation.h>
#import "TTransport.h"
NS_ASSUME_NONNULL_BEGIN
@interface TNSFileHandleTransport : NSObject <TTransport>
-(id) initWithFileHandle:(NSFileHandle *)fileHandle;
-(id) initWithInputFileHandle:(NSFileHandle *)inputFileHandle
outputFileHandle:(NSFileHandle *)outputFileHandle;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,43 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import <Foundation/Foundation.h>
#import "TTransport.h"
NS_ASSUME_NONNULL_BEGIN
@interface TNSStreamTransport : NSObject <TTransport>
@property (strong, nonatomic) NSInputStream *input;
@property (strong, nonatomic) NSOutputStream *output;
-(id) initWithInputStream:(nullable NSInputStream *)input
outputStream:(nullable NSOutputStream *)output;
-(id) initWithInputStream:(NSInputStream *)input;
-(id) initWithOutputStream:(NSOutputStream *)output;
-(void) close;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,37 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import <Foundation/Foundation.h>
#import "TNSStreamTransport.h"
NS_ASSUME_NONNULL_BEGIN
@interface TSSLSocketTransport : TNSStreamTransport <NSStreamDelegate>
-(id) initWithHostname:(NSString *)hostname
port:(int)port
error:(NSError **)error;
-(BOOL) isOpen;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,30 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import "TTransportError.h"
extern NSString *TSSLSocketTransportErrorDomain;
typedef NS_ENUM (int, TSSLSocketTransportError) {
TSSLSocketTransportErrorHostanameResolution = -10000,
TSSLSocketTransportErrorSocketCreate = -10001,
TSSLSocketTransportErrorConnect = -10002,
};

View File

@ -0,0 +1,34 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import <Foundation/Foundation.h>
#import "TNSStreamTransport.h"
NS_ASSUME_NONNULL_BEGIN
@interface TSocketTransport : TNSStreamTransport
-(id) initWithHostname:(NSString *)hostname
port:(int)port;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,48 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@protocol TTransport <NSObject>
/**
* Guarantees that all of len bytes are read
*
* @param buf Buffer to read into
* @param off Index in buffer to start storing bytes at
* @param len Maximum number of bytes to read
* @return YES if succeeded, NO if failed
* @throws TTransportError if there was an error reading data
*/
-(BOOL) readAll:(UInt8 *)buf offset:(UInt32)off length:(UInt32)len error:(NSError *__autoreleasing *)error;
-(UInt32) readAvail:(UInt8 *)buf offset:(UInt32)off maxLength:(UInt32)maxLen error:(NSError *__autoreleasing *)error;
-(BOOL) write:(const UInt8 *)data offset:(UInt32)offset length:(UInt32)length error:(NSError *__autoreleasing *)error;
-(BOOL) flush:(NSError *__autoreleasing *)error;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,43 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#import "TError.h"
extern NSString *TTransportErrorDomain;
typedef NS_ENUM (int, TTransportError) {
TTransportErrorUnknown = 0,
TTransportErrorNotOpen = 1,
TTransportErrorAlreadyOpen = 2,
TTransportErrorTimedOut = 3,
TTransportErrorEndOfFile = 4,
};
extern NSString *TTransportErrorExtendedErrorKey;
extern NSString *TTransportErrorHttpErrorKey;
typedef NS_ENUM(int, THttpTransportError) {
THttpTransportErrorInvalidResponse = 1001,
THttpTransportErrorInvalidStatus = 1002,
THttpTransportErrorAuthentication = 1003,
};

81
vendor/github.com/apache/thrift/lib/go/README.md generated vendored Normal file
View File

@ -0,0 +1,81 @@
Thrift 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.
Using Thrift with Go
====================
In following Go conventions, we recommend you use the 'go' tool to install
Thrift for go.
$ go get git.apache.org/thrift.git/lib/go/thrift/...
Will retrieve and install the most recent version of the package.
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"`
}

View File

@ -0,0 +1,142 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES 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
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
)
// Application level Thrift exception
type TApplicationException interface {
TException
TypeId() int32
Read(iprot TProtocol) (TApplicationException, error)
Write(oprot TProtocol) error
}
type tApplicationException struct {
message string
type_ int32
}
func (e tApplicationException) Error() string {
return e.message
}
func NewTApplicationException(type_ int32, message string) TApplicationException {
return &tApplicationException{message, type_}
}
func (p *tApplicationException) TypeId() int32 {
return p.type_
}
func (p *tApplicationException) Read(iprot TProtocol) (TApplicationException, error) {
_, err := iprot.ReadStructBegin()
if err != nil {
return nil, err
}
message := ""
type_ := int32(UNKNOWN_APPLICATION_EXCEPTION)
for {
_, ttype, id, err := iprot.ReadFieldBegin()
if err != nil {
return nil, err
}
if ttype == STOP {
break
}
switch id {
case 1:
if ttype == STRING {
if message, err = iprot.ReadString(); err != nil {
return nil, err
}
} else {
if err = SkipDefaultDepth(iprot, ttype); err != nil {
return nil, err
}
}
case 2:
if ttype == I32 {
if type_, err = iprot.ReadI32(); err != nil {
return nil, err
}
} else {
if err = SkipDefaultDepth(iprot, ttype); err != nil {
return nil, err
}
}
default:
if err = SkipDefaultDepth(iprot, ttype); err != nil {
return nil, err
}
}
if err = iprot.ReadFieldEnd(); err != nil {
return nil, err
}
}
return NewTApplicationException(type_, message), iprot.ReadStructEnd()
}
func (p *tApplicationException) Write(oprot TProtocol) (err error) {
err = oprot.WriteStructBegin("TApplicationException")
if len(p.Error()) > 0 {
err = oprot.WriteFieldBegin("message", STRING, 1)
if err != nil {
return
}
err = oprot.WriteString(p.Error())
if err != nil {
return
}
err = oprot.WriteFieldEnd()
if err != nil {
return
}
}
err = oprot.WriteFieldBegin("type", I32, 2)
if err != nil {
return
}
err = oprot.WriteI32(p.type_)
if err != nil {
return
}
err = oprot.WriteFieldEnd()
if err != nil {
return
}
err = oprot.WriteFieldStop()
if err != nil {
return
}
err = oprot.WriteStructEnd()
return
}

View File

@ -0,0 +1,514 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES 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"
"encoding/binary"
"errors"
"fmt"
"io"
"math"
)
type TBinaryProtocol struct {
trans TRichTransport
origTransport TTransport
reader io.Reader
writer io.Writer
strictRead bool
strictWrite bool
buffer [64]byte
}
type TBinaryProtocolFactory struct {
strictRead bool
strictWrite bool
}
func NewTBinaryProtocolTransport(t TTransport) *TBinaryProtocol {
return NewTBinaryProtocol(t, false, true)
}
func NewTBinaryProtocol(t TTransport, strictRead, strictWrite bool) *TBinaryProtocol {
p := &TBinaryProtocol{origTransport: t, strictRead: strictRead, strictWrite: strictWrite}
if et, ok := t.(TRichTransport); ok {
p.trans = et
} else {
p.trans = NewTRichTransport(t)
}
p.reader = p.trans
p.writer = p.trans
return p
}
func NewTBinaryProtocolFactoryDefault() *TBinaryProtocolFactory {
return NewTBinaryProtocolFactory(false, true)
}
func NewTBinaryProtocolFactory(strictRead, strictWrite bool) *TBinaryProtocolFactory {
return &TBinaryProtocolFactory{strictRead: strictRead, strictWrite: strictWrite}
}
func (p *TBinaryProtocolFactory) GetProtocol(t TTransport) TProtocol {
return NewTBinaryProtocol(t, p.strictRead, p.strictWrite)
}
/**
* Writing Methods
*/
func (p *TBinaryProtocol) WriteMessageBegin(name string, typeId TMessageType, seqId int32) error {
if p.strictWrite {
version := uint32(VERSION_1) | uint32(typeId)
e := p.WriteI32(int32(version))
if e != nil {
return e
}
e = p.WriteString(name)
if e != nil {
return e
}
e = p.WriteI32(seqId)
return e
} else {
e := p.WriteString(name)
if e != nil {
return e
}
e = p.WriteByte(int8(typeId))
if e != nil {
return e
}
e = p.WriteI32(seqId)
return e
}
return nil
}
func (p *TBinaryProtocol) WriteMessageEnd() error {
return nil
}
func (p *TBinaryProtocol) WriteStructBegin(name string) error {
return nil
}
func (p *TBinaryProtocol) WriteStructEnd() error {
return nil
}
func (p *TBinaryProtocol) WriteFieldBegin(name string, typeId TType, id int16) error {
e := p.WriteByte(int8(typeId))
if e != nil {
return e
}
e = p.WriteI16(id)
return e
}
func (p *TBinaryProtocol) WriteFieldEnd() error {
return nil
}
func (p *TBinaryProtocol) WriteFieldStop() error {
e := p.WriteByte(STOP)
return e
}
func (p *TBinaryProtocol) WriteMapBegin(keyType TType, valueType TType, size int) error {
e := p.WriteByte(int8(keyType))
if e != nil {
return e
}
e = p.WriteByte(int8(valueType))
if e != nil {
return e
}
e = p.WriteI32(int32(size))
return e
}
func (p *TBinaryProtocol) WriteMapEnd() error {
return nil
}
func (p *TBinaryProtocol) WriteListBegin(elemType TType, size int) error {
e := p.WriteByte(int8(elemType))
if e != nil {
return e
}
e = p.WriteI32(int32(size))
return e
}
func (p *TBinaryProtocol) WriteListEnd() error {
return nil
}
func (p *TBinaryProtocol) WriteSetBegin(elemType TType, size int) error {
e := p.WriteByte(int8(elemType))
if e != nil {
return e
}
e = p.WriteI32(int32(size))
return e
}
func (p *TBinaryProtocol) WriteSetEnd() error {
return nil
}
func (p *TBinaryProtocol) WriteBool(value bool) error {
if value {
return p.WriteByte(1)
}
return p.WriteByte(0)
}
func (p *TBinaryProtocol) WriteByte(value int8) error {
e := p.trans.WriteByte(byte(value))
return NewTProtocolException(e)
}
func (p *TBinaryProtocol) WriteI16(value int16) error {
v := p.buffer[0:2]
binary.BigEndian.PutUint16(v, uint16(value))
_, e := p.writer.Write(v)
return NewTProtocolException(e)
}
func (p *TBinaryProtocol) WriteI32(value int32) error {
v := p.buffer[0:4]
binary.BigEndian.PutUint32(v, uint32(value))
_, e := p.writer.Write(v)
return NewTProtocolException(e)
}
func (p *TBinaryProtocol) WriteI64(value int64) error {
v := p.buffer[0:8]
binary.BigEndian.PutUint64(v, uint64(value))
_, err := p.writer.Write(v)
return NewTProtocolException(err)
}
func (p *TBinaryProtocol) WriteDouble(value float64) error {
return p.WriteI64(int64(math.Float64bits(value)))
}
func (p *TBinaryProtocol) WriteString(value string) error {
e := p.WriteI32(int32(len(value)))
if e != nil {
return e
}
_, err := p.trans.WriteString(value)
return NewTProtocolException(err)
}
func (p *TBinaryProtocol) WriteBinary(value []byte) error {
e := p.WriteI32(int32(len(value)))
if e != nil {
return e
}
_, err := p.writer.Write(value)
return NewTProtocolException(err)
}
/**
* Reading methods
*/
func (p *TBinaryProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err error) {
size, e := p.ReadI32()
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()
if e != nil {
return name, typeId, seqId, NewTProtocolException(e)
}
seqId, e = p.ReadI32()
if e != nil {
return name, typeId, seqId, NewTProtocolException(e)
}
return name, typeId, seqId, nil
}
if p.strictRead {
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()
if e3 != nil {
return name, typeId, seqId, e3
}
typeId = TMessageType(b)
seqId, e4 := p.ReadI32()
if e4 != nil {
return name, typeId, seqId, e4
}
return name, typeId, seqId, nil
}
func (p *TBinaryProtocol) ReadMessageEnd() error {
return nil
}
func (p *TBinaryProtocol) ReadStructBegin() (name string, err error) {
return
}
func (p *TBinaryProtocol) ReadStructEnd() error {
return nil
}
func (p *TBinaryProtocol) ReadFieldBegin() (name string, typeId TType, seqId int16, err error) {
t, err := p.ReadByte()
typeId = TType(t)
if err != nil {
return name, typeId, seqId, err
}
if t != STOP {
seqId, err = p.ReadI16()
}
return name, typeId, seqId, err
}
func (p *TBinaryProtocol) ReadFieldEnd() error {
return nil
}
var invalidDataLength = NewTProtocolExceptionWithType(INVALID_DATA, errors.New("Invalid data length"))
func (p *TBinaryProtocol) ReadMapBegin() (kType, vType TType, size int, err error) {
k, e := p.ReadByte()
if e != nil {
err = NewTProtocolException(e)
return
}
kType = TType(k)
v, e := p.ReadByte()
if e != nil {
err = NewTProtocolException(e)
return
}
vType = TType(v)
size32, e := p.ReadI32()
if e != nil {
err = NewTProtocolException(e)
return
}
if size32 < 0 {
err = invalidDataLength
return
}
size = int(size32)
return kType, vType, size, nil
}
func (p *TBinaryProtocol) ReadMapEnd() error {
return nil
}
func (p *TBinaryProtocol) ReadListBegin() (elemType TType, size int, err error) {
b, e := p.ReadByte()
if e != nil {
err = NewTProtocolException(e)
return
}
elemType = TType(b)
size32, e := p.ReadI32()
if e != nil {
err = NewTProtocolException(e)
return
}
if size32 < 0 {
err = invalidDataLength
return
}
size = int(size32)
return
}
func (p *TBinaryProtocol) ReadListEnd() error {
return nil
}
func (p *TBinaryProtocol) ReadSetBegin() (elemType TType, size int, err error) {
b, e := p.ReadByte()
if e != nil {
err = NewTProtocolException(e)
return
}
elemType = TType(b)
size32, e := p.ReadI32()
if e != nil {
err = NewTProtocolException(e)
return
}
if size32 < 0 {
err = invalidDataLength
return
}
size = int(size32)
return elemType, size, nil
}
func (p *TBinaryProtocol) ReadSetEnd() error {
return nil
}
func (p *TBinaryProtocol) ReadBool() (bool, error) {
b, e := p.ReadByte()
v := true
if b != 1 {
v = false
}
return v, e
}
func (p *TBinaryProtocol) ReadByte() (int8, error) {
v, err := p.trans.ReadByte()
return int8(v), err
}
func (p *TBinaryProtocol) ReadI16() (value int16, err error) {
buf := p.buffer[0:2]
err = p.readAll(buf)
value = int16(binary.BigEndian.Uint16(buf))
return value, err
}
func (p *TBinaryProtocol) ReadI32() (value int32, err error) {
buf := p.buffer[0:4]
err = p.readAll(buf)
value = int32(binary.BigEndian.Uint32(buf))
return value, err
}
func (p *TBinaryProtocol) ReadI64() (value int64, err error) {
buf := p.buffer[0:8]
err = p.readAll(buf)
value = int64(binary.BigEndian.Uint64(buf))
return value, err
}
func (p *TBinaryProtocol) ReadDouble() (value float64, err error) {
buf := p.buffer[0:8]
err = p.readAll(buf)
value = math.Float64frombits(binary.BigEndian.Uint64(buf))
return value, err
}
func (p *TBinaryProtocol) ReadString() (value string, err error) {
size, e := p.ReadI32()
if e != nil {
return "", e
}
if size < 0 {
err = invalidDataLength
return
}
return p.readStringBody(size)
}
func (p *TBinaryProtocol) ReadBinary() ([]byte, error) {
size, e := p.ReadI32()
if e != nil {
return nil, e
}
if size < 0 {
return nil, invalidDataLength
}
if uint64(size) > p.trans.RemainingBytes() {
return nil, invalidDataLength
}
isize := int(size)
buf := make([]byte, isize)
_, err := io.ReadFull(p.trans, buf)
return buf, NewTProtocolException(err)
}
func (p *TBinaryProtocol) Flush() (err error) {
return NewTProtocolException(p.trans.Flush())
}
func (p *TBinaryProtocol) Skip(fieldType TType) (err error) {
return SkipDefaultDepth(p, fieldType)
}
func (p *TBinaryProtocol) Transport() TTransport {
return p.origTransport
}
func (p *TBinaryProtocol) readAll(buf []byte) error {
_, err := io.ReadFull(p.reader, buf)
return NewTProtocolException(err)
}
const readLimit = 32768
func (p *TBinaryProtocol) readStringBody(size int32) (value string, err error) {
if size < 0 {
return "", nil
}
if uint64(size) > p.trans.RemainingBytes() {
return "", invalidDataLength
}
var (
buf bytes.Buffer
e error
b []byte
)
switch {
case int(size) <= len(p.buffer):
b = p.buffer[:size] // avoids allocation for small reads
case int(size) < readLimit:
b = make([]byte, size)
default:
b = make([]byte, readLimit)
}
for size > 0 {
_, e = io.ReadFull(p.trans, b)
buf.Write(b)
if e != nil {
break
}
size -= readLimit
if size < readLimit && size > 0 {
b = b[:size]
}
}
return buf.String(), NewTProtocolException(e)
}

View File

@ -0,0 +1,91 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package thrift
import (
"bufio"
)
type TBufferedTransportFactory struct {
size int
}
type TBufferedTransport struct {
bufio.ReadWriter
tp TTransport
}
func (p *TBufferedTransportFactory) GetTransport(trans TTransport) TTransport {
return NewTBufferedTransport(trans, p.size)
}
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() error {
if err := p.ReadWriter.Flush(); err != nil {
p.ReadWriter.Writer.Reset(p.tp)
return err
}
return p.tp.Flush()
}
func (p *TBufferedTransport) RemainingBytes() (num_bytes uint64) {
return p.tp.RemainingBytes()
}

View File

@ -0,0 +1,815 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES 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/binary"
"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
)
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,
}
}
type TCompactProtocolFactory struct{}
func NewTCompactProtocolFactory() *TCompactProtocolFactory {
return &TCompactProtocolFactory{}
}
func (p *TCompactProtocolFactory) GetProtocol(trans TTransport) TProtocol {
return NewTCompactProtocol(trans)
}
type TCompactProtocol struct {
trans TRichTransport
origTransport TTransport
// 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
}
// Create a TCompactProtocol given a TTransport
func NewTCompactProtocol(trans TTransport) *TCompactProtocol {
p := &TCompactProtocol{origTransport: trans, lastField: []int{}}
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(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(name)
return e
}
func (p *TCompactProtocol) WriteMessageEnd() 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(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() error {
p.lastFieldId = p.lastField[len(p.lastField)-1]
p.lastField = p.lastField[:len(p.lastField)-1]
return nil
}
func (p *TCompactProtocol) WriteFieldBegin(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(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(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(id)
written = 1 + 2
if err != nil {
return 0, err
}
}
p.lastFieldId = fieldId
// p.lastField.Push(field.id);
return written, nil
}
func (p *TCompactProtocol) WriteFieldEnd() error { return nil }
func (p *TCompactProtocol) WriteFieldStop() error {
err := p.writeByteDirect(STOP)
return NewTProtocolException(err)
}
func (p *TCompactProtocol) WriteMapBegin(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() error { return nil }
// Write a list header.
func (p *TCompactProtocol) WriteListBegin(elemType TType, size int) error {
_, err := p.writeCollectionBegin(elemType, size)
return NewTProtocolException(err)
}
func (p *TCompactProtocol) WriteListEnd() error { return nil }
// Write a set header.
func (p *TCompactProtocol) WriteSetBegin(elemType TType, size int) error {
_, err := p.writeCollectionBegin(elemType, size)
return NewTProtocolException(err)
}
func (p *TCompactProtocol) WriteSetEnd() error { return nil }
func (p *TCompactProtocol) WriteBool(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(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(value int8) error {
err := p.writeByteDirect(byte(value))
return NewTProtocolException(err)
}
// Write an I16 as a zigzag varint.
func (p *TCompactProtocol) WriteI16(value int16) error {
_, err := p.writeVarint32(p.int32ToZigzag(int32(value)))
return NewTProtocolException(err)
}
// Write an i32 as a zigzag varint.
func (p *TCompactProtocol) WriteI32(value int32) error {
_, err := p.writeVarint32(p.int32ToZigzag(value))
return NewTProtocolException(err)
}
// Write an i64 as a zigzag varint.
func (p *TCompactProtocol) WriteI64(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(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(value string) error {
_, e := p.writeVarint32(int32(len(value)))
if e != nil {
return NewTProtocolException(e)
}
if len(value) > 0 {
}
_, e = p.trans.WriteString(value)
return e
}
// Write a byte array, using a varint for the size.
func (p *TCompactProtocol) WriteBinary(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
}
//
// Reading methods.
//
// Read a message header.
func (p *TCompactProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err error) {
protocolId, err := p.readByteDirect()
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()
return
}
func (p *TCompactProtocol) ReadMessageEnd() 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() (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() error {
// consume the last field we read off the wire.
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() (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()
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() 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() (keyType TType, valueType TType, size int, err error) {
size32, e := p.readVarint32()
if e != nil {
err = NewTProtocolException(e)
return
}
if size32 < 0 {
err = invalidDataLength
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))
return
}
func (p *TCompactProtocol) ReadMapEnd() 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() (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
}
if size2 < 0 {
err = invalidDataLength
return
}
size = int(size2)
}
elemType, e := p.getTType(tCompactType(size_and_type))
if e != nil {
err = NewTProtocolException(e)
return
}
return
}
func (p *TCompactProtocol) ReadListEnd() 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() (elemType TType, size int, err error) {
return p.ReadListBegin()
}
func (p *TCompactProtocol) ReadSetEnd() 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() (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() (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() (value int16, err error) {
v, err := p.ReadI32()
return int16(v), err
}
// Read an i32 from the wire as a zigzag varint.
func (p *TCompactProtocol) ReadI32() (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() (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() (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() (value string, err error) {
length, e := p.readVarint32()
if e != nil {
return "", NewTProtocolException(e)
}
if length < 0 {
return "", invalidDataLength
}
if uint64(length) > p.trans.RemainingBytes() {
return "", invalidDataLength
}
if length == 0 {
return "", nil
}
var buf []byte
if length <= int32(len(p.buffer)) {
buf = p.buffer[0:length]
} else {
buf = make([]byte, length)
}
_, e = io.ReadFull(p.trans, buf)
return string(buf), NewTProtocolException(e)
}
// Read a []byte from the wire.
func (p *TCompactProtocol) ReadBinary() (value []byte, err error) {
length, e := p.readVarint32()
if e != nil {
return nil, NewTProtocolException(e)
}
if length == 0 {
return []byte{}, nil
}
if length < 0 {
return nil, invalidDataLength
}
if uint64(length) > p.trans.RemainingBytes() {
return nil, invalidDataLength
}
buf := make([]byte, length)
_, e = io.ReadFull(p.trans, buf)
return buf, NewTProtocolException(e)
}
func (p *TCompactProtocol) Flush() (err error) {
return NewTProtocolException(p.trans.Flush())
}
func (p *TCompactProtocol) Skip(fieldType TType) (err error) {
return SkipDefaultDepth(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)
}
func (p *TCompactProtocol) fixedUint64ToBytes(n uint64, buf []byte) {
binary.LittleEndian.PutUint64(buf, n)
}
func (p *TCompactProtocol) fixedInt64ToBytes(n int64, buf []byte) {
binary.LittleEndian.PutUint64(buf, uint64(n))
}
// 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)
}
// Writes a byte without any possibility of all that field header nonsense.
func (p *TCompactProtocol) writeIntAsByteDirect(n int) (int, error) {
return 1, p.writeByteDirect(byte(n))
}
//
// 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) bytesToInt64(b []byte) int64 {
return int64(binary.LittleEndian.Uint64(b))
}
// 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
}
return STOP, TException(fmt.Errorf("don't know what type: %s", t&0x0f))
}
// Given a TType value, find the appropriate TCompactProtocol.Types constant.
func (p *TCompactProtocol) getCompactType(t TType) tCompactType {
return ttypeToCompactType[t]
}

Some files were not shown because too many files have changed in this diff Show More