Moving from govendor to dep, updated dependencies (#48)

* Moving from govendor to dep.

* Making the pull request template more friendly.

* Fixing akward space in PR template.

* goimports run on whole project using ` goimports -w $(find . -type f -name '*.go' -not -path "./vendor/*" -not -path "./gen-go/*")`

source of command: https://gist.github.com/bgentry/fd1ffef7dbde01857f66
This commit is contained in:
Renan DelValle 2018-01-07 13:13:47 -08:00 committed by GitHub
parent 9631aa3aab
commit 8d445c1c77
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2186 changed files with 400410 additions and 352 deletions

View file

@ -0,0 +1,2 @@
analyzer:
strong-mode: true

View file

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

28
vendor/git.apache.org/thrift.git/lib/dart/Makefile.am generated vendored Normal file
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.
#
all-local:
$(DARTPUB) get
clean-local:
$(RM) -r .pub
find . -type d -name "packages" | xargs $(RM) -r
find . -type f -name ".packages" | xargs $(RM)
check-local: all

26
vendor/git.apache.org/thrift.git/lib/dart/README.md generated vendored Normal file
View file

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

View file

@ -0,0 +1,6 @@
# Dart Coding Standards
### Please follow:
* [Thrift General Coding Standards](/doc/coding_standards.md)
* [Use dartfmt](https://www.dartlang.org/tools/dartfmt/) and follow the
[Dart Style Guide](https://www.dartlang.org/articles/style-guide/)

View file

@ -0,0 +1,130 @@
/// Licensed to the Apache Software Foundation (ASF) under one
/// or more contributor license agreements. See the NOTICE file
/// distributed with this work for additional information
/// regarding copyright ownership. The ASF licenses this file
/// to you under the Apache License, Version 2.0 (the
/// "License"); you may not use this file except in compliance
/// with the License. You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing,
/// software distributed under the License is distributed on an
/// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
/// KIND, either express or implied. See the License for the
/// specific language governing permissions and limitations
/// under the License.
library thrift.src.browser;
import 'dart:async';
import 'dart:convert' show BASE64;
import 'dart:html' show CloseEvent;
import 'dart:html' show Event;
import 'dart:html' show MessageEvent;
import 'dart:html' show WebSocket;
import 'dart:typed_data' show Uint8List;
import 'package:thrift/thrift.dart';
/// A [TSocket] backed by a [WebSocket] from dart:html
class TWebSocket implements TSocket {
final Uri url;
final StreamController<TSocketState> _onStateController;
Stream<TSocketState> get onState => _onStateController.stream;
final StreamController<Object> _onErrorController;
Stream<Object> get onError => _onErrorController.stream;
final StreamController<Uint8List> _onMessageController;
Stream<Uint8List> get onMessage => _onMessageController.stream;
final List<Uint8List> _requests = [];
TWebSocket(this.url)
: _onStateController = new StreamController.broadcast(),
_onErrorController = new StreamController.broadcast(),
_onMessageController = new StreamController.broadcast() {
if (url == null || !url.hasAuthority || !url.hasPort) {
throw new ArgumentError('Invalid url');
}
}
WebSocket _socket;
bool get isOpen => _socket != null && _socket.readyState == WebSocket.OPEN;
bool get isClosed =>
_socket == null || _socket.readyState == WebSocket.CLOSED;
Future open() {
if (!isClosed) {
throw new TTransportError(
TTransportErrorType.ALREADY_OPEN, 'Socket already connected');
}
_socket = new WebSocket(url.toString());
_socket.onError.listen(_onError);
_socket.onOpen.listen(_onOpen);
_socket.onClose.listen(_onClose);
_socket.onMessage.listen(_onMessage);
return _socket.onOpen.first;
}
Future close() {
if (_socket != null) {
_socket.close();
return _socket.onClose.first;
} else {
return new Future.value();
}
}
void send(Uint8List data) {
_requests.add(data);
_sendRequests();
}
void _sendRequests() {
while (isOpen && _requests.isNotEmpty) {
Uint8List data = _requests.removeAt(0);
_socket.sendString(BASE64.encode(data));
}
}
void _onOpen(Event event) {
_onStateController.add(TSocketState.OPEN);
_sendRequests();
}
void _onClose(CloseEvent event) {
_socket = null;
if (_requests.isNotEmpty) {
_onErrorController
.add(new StateError('Socket was closed with pending requests'));
}
_requests.clear();
_onStateController.add(TSocketState.CLOSED);
}
void _onMessage(MessageEvent message) {
try {
Uint8List data =
new Uint8List.fromList(BASE64.decode(message.data));
_onMessageController.add(data);
} on FormatException catch (_) {
var error = new TProtocolError(TProtocolErrorType.INVALID_DATA,
"Expected a Base 64 encoded string.");
_onErrorController.add(error);
}
}
void _onError(Event event) {
close();
_onErrorController.add(event.toString());
}
}

View file

@ -0,0 +1,81 @@
/// Licensed to the Apache Software Foundation (ASF) under one
/// or more contributor license agreements. See the NOTICE file
/// distributed with this work for additional information
/// regarding copyright ownership. The ASF licenses this file
/// to you under the Apache License, Version 2.0 (the
/// "License"); you may not use this file except in compliance
/// with the License. You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing,
/// software distributed under the License is distributed on an
/// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
/// KIND, either express or implied. See the License for the
/// specific language governing permissions and limitations
/// under the License.
library thrift.src.console.t_tcp_socket;
import 'dart:async';
import 'dart:io';
import 'dart:typed_data' show Uint8List;
import 'package:thrift/thrift.dart';
/// A [TSocket] backed by a [Socket] from dart:io
class TTcpSocket implements TSocket {
final StreamController<TSocketState> _onStateController;
Stream<TSocketState> get onState => _onStateController.stream;
final StreamController<Object> _onErrorController;
Stream<Object> get onError => _onErrorController.stream;
final StreamController<Uint8List> _onMessageController;
Stream<Uint8List> get onMessage => _onMessageController.stream;
TTcpSocket(Socket socket)
: _onStateController = new StreamController.broadcast(),
_onErrorController = new StreamController.broadcast(),
_onMessageController = new StreamController.broadcast() {
if (socket == null) {
throw new ArgumentError.notNull('socket');
}
_socket = socket;
_socket.listen(_onMessage, onError: _onError, onDone: close);
}
Socket _socket;
bool get isOpen => _socket != null;
bool get isClosed => _socket == null;
Future open() async {
_onStateController.add(TSocketState.OPEN);
}
Future close() async {
if (_socket != null) {
await _socket.close();
_socket = null;
}
_onStateController.add(TSocketState.CLOSED);
}
void send(Uint8List data) {
_socket.add(data);
}
void _onMessage(List<int> message) {
Uint8List data = new Uint8List.fromList(message);
_onMessageController.add(data);
}
void _onError(Object error) {
close();
_onErrorController.add('$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.
library thrift.src.console.t_web_socket;
import 'dart:async';
import 'dart:convert' show BASE64;
import 'dart:io';
import 'dart:typed_data' show Uint8List;
import 'package:thrift/thrift.dart';
/// A [TSocket] backed by a [WebSocket] from dart:io
class TWebSocket implements TSocket {
final StreamController<TSocketState> _onStateController;
Stream<TSocketState> get onState => _onStateController.stream;
final StreamController<Object> _onErrorController;
Stream<Object> get onError => _onErrorController.stream;
final StreamController<Uint8List> _onMessageController;
Stream<Uint8List> get onMessage => _onMessageController.stream;
TWebSocket(WebSocket socket)
: _onStateController = new StreamController.broadcast(),
_onErrorController = new StreamController.broadcast(),
_onMessageController = new StreamController.broadcast() {
if (socket == null) {
throw new ArgumentError.notNull('socket');
}
_socket = socket;
_socket.listen(_onMessage, onError: _onError, onDone: close);
}
WebSocket _socket;
bool get isOpen => _socket != null;
bool get isClosed => _socket == null;
Future open() async {
_onStateController.add(TSocketState.OPEN);
}
Future close() async {
if (_socket != null) {
await _socket.close();
_socket = null;
}
_onStateController.add(TSocketState.CLOSED);
}
void send(Uint8List data) {
_socket.add(BASE64.encode(data));
}
void _onMessage(String message) {
try {
Uint8List data =
new Uint8List.fromList(BASE64.decode(message));
_onMessageController.add(data);
} on FormatException catch (_) {
var error = new TProtocolError(TProtocolErrorType.INVALID_DATA,
"Expected a Base 64 encoded string.");
_onErrorController.add(error);
}
}
void _onError(Object error) {
close();
_onErrorController.add('$error');
}
}

View file

@ -0,0 +1,281 @@
/// Licensed to the Apache Software Foundation (ASF) under one
/// or more contributor license agreements. See the NOTICE file
/// distributed with this work for additional information
/// regarding copyright ownership. The ASF licenses this file
/// to you under the Apache License, Version 2.0 (the
/// "License"); you may not use this file except in compliance
/// with the License. You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing,
/// software distributed under the License is distributed on an
/// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
/// KIND, either express or implied. See the License for the
/// specific language governing permissions and limitations
/// under the License.
part of thrift;
class TBinaryProtocolFactory implements TProtocolFactory<TBinaryProtocol> {
TBinaryProtocolFactory({this.strictRead: false, this.strictWrite: true});
final bool strictRead;
final bool strictWrite;
TBinaryProtocol getProtocol(TTransport transport) {
return new TBinaryProtocol(transport,
strictRead: strictRead, strictWrite: strictWrite);
}
}
/// Binary protocol implementation for Thrift.
///
/// Adapted from the C# version.
class TBinaryProtocol extends TProtocol {
static const int VERSION_MASK = 0xffff0000;
static const int VERSION_1 = 0x80010000;
static const Utf8Codec _utf8Codec = const Utf8Codec();
final bool strictRead;
final bool strictWrite;
TBinaryProtocol(TTransport transport,
{this.strictRead: false, this.strictWrite: true})
: super(transport);
/// write
void writeMessageBegin(TMessage message) {
if (strictWrite) {
int version = VERSION_1 | message.type;
writeI32(version);
writeString(message.name);
writeI32(message.seqid);
} else {
writeString(message.name);
writeByte(message.type);
writeI32(message.seqid);
}
}
void writeMessageEnd() {}
void writeStructBegin(TStruct struct) {}
void writeStructEnd() {}
void writeFieldBegin(TField field) {
writeByte(field.type);
writeI16(field.id);
}
void writeFieldEnd() {}
void writeFieldStop() {
writeByte(TType.STOP);
}
void writeMapBegin(TMap map) {
writeByte(map.keyType);
writeByte(map.valueType);
writeI32(map.length);
}
void writeMapEnd() {}
void writeListBegin(TList list) {
writeByte(list.elementType);
writeI32(list.length);
}
void writeListEnd() {}
void writeSetBegin(TSet set) {
writeByte(set.elementType);
writeI32(set.length);
}
void writeSetEnd() {}
void writeBool(bool b) {
if (b == null) b = false;
writeByte(b ? 1 : 0);
}
final ByteData _byteOut = new ByteData(1);
void writeByte(int byte) {
if (byte == null) byte = 0;
_byteOut.setUint8(0, byte);
transport.write(_byteOut.buffer.asUint8List(), 0, 1);
}
final ByteData _i16Out = new ByteData(2);
void writeI16(int i16) {
if (i16 == null) i16 = 0;
_i16Out.setInt16(0, i16);
transport.write(_i16Out.buffer.asUint8List(), 0, 2);
}
final ByteData _i32Out = new ByteData(4);
void writeI32(int i32) {
if (i32 == null) i32 = 0;
_i32Out.setInt32(0, i32);
transport.write(_i32Out.buffer.asUint8List(), 0, 4);
}
final Uint8List _i64Out = new Uint8List(8);
void writeI64(int i64) {
if (i64 == null) i64 = 0;
var i = new Int64(i64);
var bts = i.toBytes();
for (var j = 0; j < 8; j++) {
_i64Out[j] = bts[8 - j - 1];
}
transport.write(_i64Out, 0, 8);
}
void writeString(String s) {
var bytes = s != null ? _utf8Codec.encode(s) : new Uint8List.fromList([]);
writeI32(bytes.length);
transport.write(bytes, 0, bytes.length);
}
final ByteData _doubleOut = new ByteData(8);
void writeDouble(double d) {
if (d == null) d = 0.0;
_doubleOut.setFloat64(0, d);
transport.write(_doubleOut.buffer.asUint8List(), 0, 8);
}
void writeBinary(Uint8List bytes) {
var length = bytes.length;
writeI32(length);
transport.write(bytes, 0, length);
}
/// read
TMessage readMessageBegin() {
String name;
int type;
int seqid;
int size = readI32();
if (size < 0) {
int version = size & VERSION_MASK;
if (version != VERSION_1) {
throw new TProtocolError(TProtocolErrorType.BAD_VERSION,
"Bad version in readMessageBegin: $version");
}
type = size & 0x000000ff;
name = readString();
seqid = readI32();
} else {
if (strictRead) {
throw new TProtocolError(TProtocolErrorType.BAD_VERSION,
"Missing version in readMessageBegin");
}
name = _readString(size);
type = readByte();
seqid = readI32();
}
return new TMessage(name, type, seqid);
}
void readMessageEnd() {}
TStruct readStructBegin() {
return new TStruct();
}
void readStructEnd() {}
TField readFieldBegin() {
String name = "";
int type = readByte();
int id = type != TType.STOP ? readI16() : 0;
return new TField(name, type, id);
}
void readFieldEnd() {}
TMap readMapBegin() {
int keyType = readByte();
int valueType = readByte();
int length = readI32();
return new TMap(keyType, valueType, length);
}
void readMapEnd() {}
TList readListBegin() {
int elementType = readByte();
int length = readI32();
return new TList(elementType, length);
}
void readListEnd() {}
TSet readSetBegin() {
int elementType = readByte();
int length = readI32();
return new TSet(elementType, length);
}
void readSetEnd() {}
bool readBool() => readByte() == 1;
final Uint8List _byteIn = new Uint8List(1);
int readByte() {
transport.readAll(_byteIn, 0, 1);
return _byteIn.buffer.asByteData().getUint8(0);
}
final Uint8List _i16In = new Uint8List(2);
int readI16() {
transport.readAll(_i16In, 0, 2);
return _i16In.buffer.asByteData().getInt16(0);
}
final Uint8List _i32In = new Uint8List(4);
int readI32() {
transport.readAll(_i32In, 0, 4);
return _i32In.buffer.asByteData().getInt32(0);
}
final Uint8List _i64In = new Uint8List(8);
int readI64() {
transport.readAll(_i64In, 0, 8);
var i = new Int64.fromBytesBigEndian(_i64In);
return i.toInt();
}
final Uint8List _doubleIn = new Uint8List(8);
double readDouble() {
transport.readAll(_doubleIn, 0, 8);
return _doubleIn.buffer.asByteData().getFloat64(0);
}
String readString() {
int size = readI32();
return _readString(size);
}
String _readString(int size) {
Uint8List stringIn = new Uint8List(size);
transport.readAll(stringIn, 0, size);
return _utf8Codec.decode(stringIn);
}
Uint8List readBinary() {
int length = readI32();
Uint8List binaryIn = new Uint8List(length);
transport.readAll(binaryIn, 0, length);
return binaryIn;
}
}

View file

@ -0,0 +1,470 @@
/// Licensed to the Apache Software Foundation (ASF) under one
/// or more contributor license agreements. See the NOTICE file
/// distributed with this work for additional information
/// regarding copyright ownership. The ASF licenses this file
/// to you under the Apache License, Version 2.0 (the
/// 'License'); you may not use this file except in compliance
/// with the License. You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing,
/// software distributed under the License is distributed on an
/// 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
/// KIND, either express or implied. See the License for the
/// specific language governing permissions and limitations
/// under the License.
part of thrift;
class TCompactProtocolFactory implements TProtocolFactory<TCompactProtocol> {
TCompactProtocolFactory();
TCompactProtocol getProtocol(TTransport transport) {
return new TCompactProtocol(transport);
}
}
/// Compact protocol implementation for Thrift.
///
/// Use of fixnum library is required due to bugs like
/// https://github.com/dart-lang/sdk/issues/15361
///
/// Adapted from the Java version.
class TCompactProtocol extends TProtocol {
static const int PROTOCOL_ID = 0x82;
static const int VERSION = 1;
static const int VERSION_MASK = 0x1f;
static const int TYPE_MASK = 0xE0;
static const int TYPE_BITS = 0x07;
static const int TYPE_SHIFT_AMOUNT = 5;
static final TField TSTOP = new TField("", TType.STOP, 0);
static const int TYPE_BOOLEAN_TRUE = 0x01;
static const int TYPE_BOOLEAN_FALSE = 0x02;
static const int TYPE_BYTE = 0x03;
static const int TYPE_I16 = 0x04;
static const int TYPE_I32 = 0x05;
static const int TYPE_I64 = 0x06;
static const int TYPE_DOUBLE = 0x07;
static const int TYPE_BINARY = 0x08;
static const int TYPE_LIST = 0x09;
static const int TYPE_SET = 0x0A;
static const int TYPE_MAP = 0x0B;
static const int TYPE_STRUCT = 0x0C;
static final List<int> _typeMap = new List.unmodifiable(new List(16)
..[TType.STOP] = TType.STOP
..[TType.BOOL] = TYPE_BOOLEAN_TRUE
..[TType.BYTE] = TYPE_BYTE
..[TType.I16] = TYPE_I16
..[TType.I32] = TYPE_I32
..[TType.I64] = TYPE_I64
..[TType.DOUBLE] = TYPE_DOUBLE
..[TType.STRING] = TYPE_BINARY
..[TType.LIST] = TYPE_LIST
..[TType.SET] = TYPE_SET
..[TType.MAP] = TYPE_MAP
..[TType.STRUCT] = TYPE_STRUCT);
static const Utf8Codec _utf8Codec = const Utf8Codec();
// Pretend this is a stack
DoubleLinkedQueue<int> _lastField = new DoubleLinkedQueue<int>();
int _lastFieldId = 0;
TField _booleanField = null;
bool _boolValue = null;
final Uint8List tempList = new Uint8List(10);
final ByteData tempBD = new ByteData(10);
TCompactProtocol(TTransport transport) : super(transport);
/// Write
void writeMessageBegin(TMessage message) {
writeByte(PROTOCOL_ID);
writeByte((VERSION & VERSION_MASK) |
((message.type << TYPE_SHIFT_AMOUNT) & TYPE_MASK));
_writeVarInt32(new Int32(message.seqid));
writeString(message.name);
}
void writeMessageEnd() {}
void writeStructBegin(TStruct struct) {
_lastField.addLast(_lastFieldId);
_lastFieldId = 0;
}
void writeStructEnd() {
_lastFieldId = _lastField.removeLast();
}
void writeFieldBegin(TField field) {
if (field.type == TType.BOOL) {
_booleanField = field;
} else {
_writeFieldBegin(field, -1);
}
}
void _writeFieldBegin(TField field, int typeOverride) {
int typeToWrite =
typeOverride == -1 ? _getCompactType(field.type) : typeOverride;
if (field.id > _lastFieldId && field.id - _lastFieldId <= 15) {
writeByte((field.id - _lastFieldId) << 4 | typeToWrite);
} else {
writeByte(typeToWrite);
writeI16(field.id);
}
_lastFieldId = field.id;
}
void writeFieldEnd() {}
void writeFieldStop() {
writeByte(TType.STOP);
}
void writeMapBegin(TMap map) {
if (map.length == 0) {
writeByte(0);
} else {
_writeVarInt32(new Int32(map.length));
writeByte(
_getCompactType(map.keyType) << 4 | _getCompactType(map.valueType));
}
}
void writeMapEnd() {}
void writeListBegin(TList list) {
_writeCollectionBegin(list.elementType, list.length);
}
void writeListEnd() {}
void writeSetBegin(TSet set) {
_writeCollectionBegin(set.elementType, set.length);
}
void writeSetEnd() {}
void writeBool(bool b) {
if (b == null) b = false;
if (_booleanField != null) {
_writeFieldBegin(
_booleanField, b ? TYPE_BOOLEAN_TRUE : TYPE_BOOLEAN_FALSE);
_booleanField = null;
} else {
writeByte(b ? TYPE_BOOLEAN_TRUE : TYPE_BOOLEAN_FALSE);
}
}
void writeByte(int b) {
if (b == null) b = 0;
tempList[0] = b;
transport.write(tempList, 0, 1);
}
void writeI16(int i16) {
if (i16 == null) i16 = 0;
_writeVarInt32(_int32ToZigZag(new Int32(i16)));
}
void writeI32(int i32) {
if (i32 == null) i32 = 0;
_writeVarInt32(_int32ToZigZag(new Int32(i32)));
}
void writeI64(int i64) {
if (i64 == null) i64 = 0;
_writeVarInt64(_int64ToZigZag(new Int64(i64)));
}
void writeDouble(double d) {
if (d == null) d = 0.0;
tempBD.setFloat64(0, d, Endianness.LITTLE_ENDIAN);
transport.write(tempBD.buffer.asUint8List(), 0, 8);
}
void writeString(String str) {
Uint8List bytes =
str != null ? _utf8Codec.encode(str) : new Uint8List.fromList([]);
writeBinary(bytes);
}
void writeBinary(Uint8List bytes) {
_writeVarInt32(new Int32(bytes.length));
transport.write(bytes, 0, bytes.length);
}
void _writeVarInt32(Int32 n) {
int idx = 0;
while (true) {
if ((n & ~0x7F) == 0) {
tempList[idx++] = (n & 0xFF).toInt();
break;
} else {
tempList[idx++] = (((n & 0x7F) | 0x80) & 0xFF).toInt();
n = n.shiftRightUnsigned(7);
}
}
transport.write(tempList, 0, idx);
}
void _writeVarInt64(Int64 n) {
int idx = 0;
while (true) {
if ((n & ~0x7F) == 0) {
tempList[idx++] = (n & 0xFF).toInt();
break;
} else {
tempList[idx++] = (((n & 0x7F) | 0x80) & 0xFF).toInt();
n = n.shiftRightUnsigned(7);
}
}
transport.write(tempList, 0, idx);
}
void _writeCollectionBegin(int elemType, int length) {
if (length <= 14) {
writeByte(length << 4 | _getCompactType(elemType));
} else {
writeByte(0xF0 | _getCompactType(elemType));
_writeVarInt32(new Int32(length));
}
}
Int32 _int32ToZigZag(Int32 n) {
return (n << 1) ^ (n >> 31);
}
Int64 _int64ToZigZag(Int64 n) {
return (n << 1) ^ (n >> 63);
}
/// Read
TMessage readMessageBegin() {
int protocolId = readByte();
if (protocolId != PROTOCOL_ID) {
throw new TProtocolError(TProtocolErrorType.BAD_VERSION,
'Expected protocol id $PROTOCOL_ID but got $protocolId');
}
int versionAndType = readByte();
int version = versionAndType & VERSION_MASK;
if (version != VERSION) {
throw new TProtocolError(TProtocolErrorType.BAD_VERSION,
'Expected version $VERSION but got $version');
}
int type = (versionAndType >> TYPE_SHIFT_AMOUNT) & TYPE_BITS;
int seqId = _readVarInt32().toInt();
String messageName = readString();
return new TMessage(messageName, type, seqId);
}
void readMessageEnd() {}
TStruct readStructBegin() {
_lastField.addLast(_lastFieldId);
_lastFieldId = 0;
// TODO make this a constant?
return new TStruct();
}
void readStructEnd() {
_lastFieldId = _lastField.removeLast();
}
TField readFieldBegin() {
int type = readByte();
if (type == TType.STOP) {
return TSTOP;
}
int fieldId;
int modifier = (type & 0xF0) >> 4;
if (modifier == 0) {
fieldId = readI16();
} else {
fieldId = _lastFieldId + modifier;
}
TField field = new TField('', _getTType(type & 0x0F), fieldId);
if (_isBoolType(type)) {
_boolValue = (type & 0x0F) == TYPE_BOOLEAN_TRUE;
}
_lastFieldId = field.id;
return field;
}
void readFieldEnd() {}
TMap readMapBegin() {
int length = _readVarInt32().toInt();
_checkNegReadLength(length);
int keyAndValueType = length == 0 ? 0 : readByte();
int keyType = _getTType(keyAndValueType >> 4);
int valueType = _getTType(keyAndValueType & 0x0F);
return new TMap(keyType, valueType, length);
}
void readMapEnd() {}
TList readListBegin() {
int lengthAndType = readByte();
int length = (lengthAndType >> 4) & 0x0F;
if (length == 15) {
length = _readVarInt32().toInt();
}
_checkNegReadLength(length);
int type = _getTType(lengthAndType);
return new TList(type, length);
}
void readListEnd() {}
TSet readSetBegin() {
TList tlist = readListBegin();
return new TSet(tlist.elementType, tlist.length);
}
void readSetEnd() {}
bool readBool() {
if (_boolValue != null) {
bool result = _boolValue;
_boolValue = null;
return result;
}
return readByte() == TYPE_BOOLEAN_TRUE;
}
int readByte() {
transport.readAll(tempList, 0, 1);
return tempList.buffer.asByteData().getUint8(0);
}
int readI16() {
return _zigzagToInt32(_readVarInt32()).toInt();
}
int readI32() {
return _zigzagToInt32(_readVarInt32()).toInt();
}
int readI64() {
return _zigzagToInt64(_readVarInt64()).toInt();
}
double readDouble() {
transport.readAll(tempList, 0, 8);
return tempList.buffer.asByteData().getFloat64(0, Endianness.LITTLE_ENDIAN);
}
String readString() {
int length = _readVarInt32().toInt();
_checkNegReadLength(length);
// TODO look at using temp for small strings?
Uint8List buff = new Uint8List(length);
transport.readAll(buff, 0, length);
return _utf8Codec.decode(buff);
}
Uint8List readBinary() {
int length = _readVarInt32().toInt();
_checkNegReadLength(length);
Uint8List buff = new Uint8List(length);
transport.readAll(buff, 0, length);
return buff;
}
Int32 _readVarInt32() {
Int32 result = Int32.ZERO;
int shift = 0;
while (true) {
Int32 b = new Int32(readByte());
result |= (b & 0x7f) << shift;
if ((b & 0x80) != 0x80) break;
shift += 7;
}
return result;
}
Int64 _readVarInt64() {
Int64 result = Int64.ZERO;
int shift = 0;
while (true) {
Int64 b = new Int64(readByte());
result |= (b & 0x7f) << shift;
if ((b & 0x80) != 0x80) break;
shift += 7;
}
return result;
}
Int32 _zigzagToInt32(Int32 n) {
return (n.shiftRightUnsigned(1)) ^ -(n & 1);
}
Int64 _zigzagToInt64(Int64 n) {
return (n.shiftRightUnsigned(1)) ^ -(n & 1);
}
void _checkNegReadLength(int length) {
if (length < 0) {
throw new TProtocolError(
TProtocolErrorType.NEGATIVE_SIZE, 'Negative length: $length');
}
}
int _getCompactType(int ttype) {
return _typeMap[ttype];
}
int _getTType(int type) {
switch (type & 0x0F) {
case TType.STOP:
return TType.STOP;
case TYPE_BOOLEAN_FALSE:
case TYPE_BOOLEAN_TRUE:
return TType.BOOL;
case TYPE_BYTE:
return TType.BYTE;
case TYPE_I16:
return TType.I16;
case TYPE_I32:
return TType.I32;
case TYPE_I64:
return TType.I64;
case TYPE_DOUBLE:
return TType.DOUBLE;
case TYPE_BINARY:
return TType.STRING;
case TYPE_LIST:
return TType.LIST;
case TYPE_SET:
return TType.SET;
case TYPE_MAP:
return TType.MAP;
case TYPE_STRUCT:
return TType.STRUCT;
default:
throw new TProtocolError(
TProtocolErrorType.INVALID_DATA, "Unknown type: ${type & 0x0F}");
}
}
bool _isBoolType(int b) {
int lowerNibble = b & 0x0F;
return lowerNibble == TYPE_BOOLEAN_TRUE ||
lowerNibble == TYPE_BOOLEAN_FALSE;
}
}

View file

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

View file

@ -0,0 +1,784 @@
/// Licensed to the Apache Software Foundation (ASF) under one
/// or more contributor license agreements. See the NOTICE file
/// distributed with this work for additional information
/// regarding copyright ownership. The ASF licenses this file
/// to you under the Apache License, Version 2.0 (the
/// "License"); you may not use this file except in compliance
/// with the License. You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing,
/// software distributed under the License is distributed on an
/// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
/// KIND, either express or implied. See the License for the
/// specific language governing permissions and limitations
/// under the License.
part of thrift;
class TJsonProtocolFactory implements TProtocolFactory<TJsonProtocol> {
TJsonProtocol getProtocol(TTransport transport) {
return new TJsonProtocol(transport);
}
}
/// JSON protocol implementation for Thrift.
///
/// Adapted from the C# version.
class TJsonProtocol extends TProtocol {
static const int VERSION_1 = 1;
static const Utf8Codec utf8Codec = const Utf8Codec();
_BaseContext _context;
_BaseContext _rootContext;
_LookaheadReader _reader;
final List<_BaseContext> _contextStack = [];
final Uint8List _tempBuffer = new Uint8List(4);
TJsonProtocol(TTransport transport) : super(transport) {
_rootContext = new _BaseContext(this);
_reader = new _LookaheadReader(this);
_resetContext();
}
void _pushContext(_BaseContext c) {
_contextStack.add(c);
_context = c;
}
void _popContext() {
_contextStack.removeLast();
_context = _contextStack.isEmpty ? _rootContext : _contextStack.last;
}
void _resetContext() {
_contextStack.clear();
_context = _rootContext;
}
/// Read a byte that must match [char]; otherwise throw a [TProtocolError].
void _readJsonSyntaxChar(int charByte) {
int byte = _reader.read();
if (byte != charByte) {
throw new TProtocolError(TProtocolErrorType.INVALID_DATA,
"Expected character ${new String.fromCharCode(charByte)} but found: ${new String.fromCharCode(byte)}");
}
}
int _hexVal(int byte) {
if (byte >= _Constants.HEX_0_BYTES[0] &&
byte <= _Constants.HEX_9_BYTES[0]) {
return byte - _Constants.HEX_0_BYTES[0];
} else if (byte >= _Constants.HEX_A_BYTES[0] &&
byte <= _Constants.HEX_F_BYTES[0]) {
byte += 10;
return byte - _Constants.HEX_A_BYTES[0];
} else {
throw new TProtocolError(
TProtocolErrorType.INVALID_DATA, "Expected hex character");
}
}
int _hexChar(int byte) => byte.toRadixString(16).codeUnitAt(0);
/// write
/// Write the [bytes] as JSON characters, escaping as needed.
void _writeJsonString(Uint8List bytes) {
_context.write();
transport.writeAll(_Constants.QUOTE_BYTES);
int length = bytes.length;
for (int i = 0; i < length; i++) {
int byte = bytes[i];
if ((byte & 0x00FF) >= 0x30) {
if (byte == _Constants.BACKSLASH_BYTES[0]) {
transport.writeAll(_Constants.BACKSLASH_BYTES);
transport.writeAll(_Constants.BACKSLASH_BYTES);
} else {
transport.write(bytes, i, 1);
}
} else {
_tempBuffer[0] = _Constants.JSON_CHAR_TABLE[byte];
if (_tempBuffer[0] == 1) {
transport.write(bytes, i, 1);
} else if (_tempBuffer[0] > 1) {
transport.writeAll(_Constants.BACKSLASH_BYTES);
transport.write(_tempBuffer, 0, 1);
} else {
transport.writeAll(_Constants.ESCSEQ_BYTES);
_tempBuffer[0] = _hexChar(byte >> 4);
_tempBuffer[1] = _hexChar(byte);
transport.write(_tempBuffer, 0, 2);
}
}
}
transport.writeAll(_Constants.QUOTE_BYTES);
}
void _writeJsonInteger(int i) {
if (i == null) i = 0;
_context.write();
String str = i.toString();
if (_context.escapeNumbers) {
transport.writeAll(_Constants.QUOTE_BYTES);
}
transport.writeAll(utf8Codec.encode(str));
if (_context.escapeNumbers) {
transport.writeAll(_Constants.QUOTE_BYTES);
}
}
void _writeJsonDouble(double d) {
if (d == null) d = 0.0;
_context.write();
String str = d.toString();
bool escapeNumbers = d.isNaN || d.isInfinite || _context.escapeNumbers;
if (escapeNumbers) {
transport.writeAll(_Constants.QUOTE_BYTES);
}
transport.writeAll(utf8Codec.encode(str));
if (escapeNumbers) {
transport.writeAll(_Constants.QUOTE_BYTES);
}
}
void _writeJsonBase64(Uint8List bytes) {
_context.write();
transport.writeAll(_Constants.QUOTE_BYTES);
String base64 = BASE64.encode(bytes);
transport.writeAll(utf8Codec.encode(base64));
transport.writeAll(_Constants.QUOTE_BYTES);
}
void _writeJsonObjectStart() {
_context.write();
transport.writeAll(_Constants.LBRACE_BYTES);
_pushContext(new _PairContext(this));
}
void _writeJsonObjectEnd() {
_popContext();
transport.writeAll(_Constants.RBRACE_BYTES);
}
void _writeJsonArrayStart() {
_context.write();
transport.writeAll(_Constants.LBRACKET_BYTES);
_pushContext(new _ListContext(this));
}
void _writeJsonArrayEnd() {
_popContext();
transport.writeAll(_Constants.RBRACKET_BYTES);
}
void writeMessageBegin(TMessage message) {
_resetContext();
_writeJsonArrayStart();
_writeJsonInteger(VERSION_1);
_writeJsonString(utf8Codec.encode(message.name));
_writeJsonInteger(message.type);
_writeJsonInteger(message.seqid);
}
void writeMessageEnd() {
_writeJsonArrayEnd();
}
void writeStructBegin(TStruct struct) {
_writeJsonObjectStart();
}
void writeStructEnd() {
_writeJsonObjectEnd();
}
void writeFieldBegin(TField field) {
_writeJsonInteger(field.id);
_writeJsonObjectStart();
_writeJsonString(_Constants.getTypeNameBytesForTypeId(field.type));
}
void writeFieldEnd() {
_writeJsonObjectEnd();
}
void writeFieldStop() {}
void writeMapBegin(TMap map) {
_writeJsonArrayStart();
_writeJsonString(_Constants.getTypeNameBytesForTypeId(map.keyType));
_writeJsonString(_Constants.getTypeNameBytesForTypeId(map.valueType));
_writeJsonInteger(map.length);
_writeJsonObjectStart();
}
void writeMapEnd() {
_writeJsonObjectEnd();
_writeJsonArrayEnd();
}
void writeListBegin(TList list) {
_writeJsonArrayStart();
_writeJsonString(_Constants.getTypeNameBytesForTypeId(list.elementType));
_writeJsonInteger(list.length);
}
void writeListEnd() {
_writeJsonArrayEnd();
}
void writeSetBegin(TSet set) {
_writeJsonArrayStart();
_writeJsonString(_Constants.getTypeNameBytesForTypeId(set.elementType));
_writeJsonInteger(set.length);
}
void writeSetEnd() {
_writeJsonArrayEnd();
}
void writeBool(bool b) {
if (b == null) b = false;
_writeJsonInteger(b ? 1 : 0);
}
void writeByte(int b) {
_writeJsonInteger(b);
}
void writeI16(int i16) {
_writeJsonInteger(i16);
}
void writeI32(int i32) {
_writeJsonInteger(i32);
}
void writeI64(int i64) {
_writeJsonInteger(i64);
}
void writeDouble(double d) {
_writeJsonDouble(d);
}
void writeString(String s) {
var bytes = s != null ? utf8Codec.encode(s) : new Uint8List.fromList([]);
_writeJsonString(bytes);
}
void writeBinary(Uint8List bytes) {
_writeJsonBase64(bytes);
}
bool _isHighSurrogate(int b) => b >= 0xD800 && b <= 0xDBFF;
bool _isLowSurrogate(int b) => b >= 0xDC00 && b <= 0xDFFF;
/// read
Uint8List _readJsonString({bool skipContext: false}) {
List<int> bytes = [];
List<int> codeunits = [];
if (!skipContext) {
_context.read();
}
_readJsonSyntaxChar(_Constants.QUOTE_BYTES[0]);
while (true) {
int byte = _reader.read();
if (byte == _Constants.QUOTE_BYTES[0]) {
break;
}
// escaped?
if (byte != _Constants.ESCSEQ_BYTES[0]) {
bytes.add(byte);
continue;
}
byte = _reader.read();
// distinguish between \uXXXX and control chars like \n
if (byte != _Constants.ESCSEQ_BYTES[1]) {
String char = new String.fromCharCode(byte);
int offset = _Constants.ESCAPE_CHARS.indexOf(char);
if (offset == -1) {
throw new TProtocolError(
TProtocolErrorType.INVALID_DATA, "Expected control char");
}
byte = _Constants.ESCAPE_CHAR_VALS.codeUnitAt(offset);
bytes.add(byte);
continue;
}
// it's \uXXXX
transport.readAll(_tempBuffer, 0, 4);
byte = (_hexVal(_tempBuffer[0]) << 12)
+ (_hexVal(_tempBuffer[1]) << 8)
+ (_hexVal(_tempBuffer[2]) << 4)
+ _hexVal(_tempBuffer[3]);
if (_isHighSurrogate(byte)) {
if (codeunits.isNotEmpty) {
throw new TProtocolError(
TProtocolErrorType.INVALID_DATA, "Expected low surrogate");
}
codeunits.add(byte);
}
else if (_isLowSurrogate(byte)) {
if (codeunits.isEmpty) {
throw new TProtocolError(
TProtocolErrorType.INVALID_DATA, "Expected high surrogate");
}
codeunits.add(byte);
bytes.addAll(utf8Codec.encode(new String.fromCharCodes(codeunits)));
codeunits.clear();
}
else {
bytes.addAll(utf8Codec.encode(new String.fromCharCode(byte)));
}
}
if (codeunits.isNotEmpty) {
throw new TProtocolError(
TProtocolErrorType.INVALID_DATA, "Expected low surrogate");
}
return new Uint8List.fromList(bytes);
}
String _readJsonNumericChars() {
StringBuffer buffer = new StringBuffer();
while (true) {
if (!_Constants.isJsonNumeric(_reader.peek())) {
break;
}
buffer.write(new String.fromCharCode(_reader.read()));
}
return buffer.toString();
}
int _readJsonInteger() {
_context.read();
if (_context.escapeNumbers) {
_readJsonSyntaxChar(_Constants.QUOTE_BYTES[0]);
}
String str = _readJsonNumericChars();
if (_context.escapeNumbers) {
_readJsonSyntaxChar(_Constants.QUOTE_BYTES[0]);
}
try {
return int.parse(str);
} on FormatException catch (_) {
throw new TProtocolError(TProtocolErrorType.INVALID_DATA,
"Bad data encounted in numeric data");
}
}
double _readJsonDouble() {
_context.read();
if (_reader.peek() == _Constants.QUOTE_BYTES[0]) {
Uint8List bytes = _readJsonString(skipContext: true);
double d = double.parse(utf8Codec.decode(bytes), (_) {
throw new TProtocolError(TProtocolErrorType.INVALID_DATA,
"Bad data encounted in numeric data");
});
if (!_context.escapeNumbers && !d.isNaN && !d.isInfinite) {
throw new TProtocolError(TProtocolErrorType.INVALID_DATA,
"Numeric data unexpectedly quoted");
}
return d;
} else {
if (_context.escapeNumbers) {
// This will throw - we should have had a quote if escapeNumbers == true
_readJsonSyntaxChar(_Constants.QUOTE_BYTES[0]);
}
return double.parse(_readJsonNumericChars(), (_) {
throw new TProtocolError(TProtocolErrorType.INVALID_DATA,
"Bad data encounted in numeric data");
});
}
}
Uint8List _readJsonBase64() {
// convert UTF-8 bytes of a Base 64 encoded string to binary bytes
Uint8List base64Bytes = _readJsonString();
String base64 = utf8Codec.decode(base64Bytes);
return new Uint8List.fromList(BASE64.decode(base64));
}
void _readJsonObjectStart() {
_context.read();
_readJsonSyntaxChar(_Constants.LBRACE_BYTES[0]);
_pushContext(new _PairContext(this));
}
void _readJsonObjectEnd() {
_readJsonSyntaxChar(_Constants.RBRACE_BYTES[0]);
_popContext();
}
void _readJsonArrayStart() {
_context.read();
_readJsonSyntaxChar(_Constants.LBRACKET_BYTES[0]);
_pushContext(new _ListContext(this));
}
void _readJsonArrayEnd() {
_readJsonSyntaxChar(_Constants.RBRACKET_BYTES[0]);
_popContext();
}
TMessage readMessageBegin() {
_resetContext();
_readJsonArrayStart();
if (_readJsonInteger() != VERSION_1) {
throw new TProtocolError(
TProtocolErrorType.BAD_VERSION, "Message contained bad version.");
}
Uint8List buffer = _readJsonString();
String name = utf8Codec.decode(buffer);
int type = _readJsonInteger();
int seqid = _readJsonInteger();
return new TMessage(name, type, seqid);
}
void readMessageEnd() {
_readJsonArrayEnd();
}
TStruct readStructBegin() {
_readJsonObjectStart();
return new TStruct();
}
void readStructEnd() {
_readJsonObjectEnd();
}
TField readFieldBegin() {
String name = "";
int type = TType.STOP;
int id = 0;
if (_reader.peek() != _Constants.RBRACE_BYTES[0]) {
id = _readJsonInteger();
_readJsonObjectStart();
type = _Constants.getTypeIdForTypeName(_readJsonString());
}
return new TField(name, type, id);
}
void readFieldEnd() {
_readJsonObjectEnd();
}
TMap readMapBegin() {
_readJsonArrayStart();
int keyType = _Constants.getTypeIdForTypeName(_readJsonString());
int valueType = _Constants.getTypeIdForTypeName(_readJsonString());
int length = _readJsonInteger();
_readJsonObjectStart();
return new TMap(keyType, valueType, length);
}
void readMapEnd() {
_readJsonObjectEnd();
_readJsonArrayEnd();
}
TList readListBegin() {
_readJsonArrayStart();
int elementType = _Constants.getTypeIdForTypeName(_readJsonString());
int length = _readJsonInteger();
return new TList(elementType, length);
}
void readListEnd() {
_readJsonArrayEnd();
}
TSet readSetBegin() {
_readJsonArrayStart();
int elementType = _Constants.getTypeIdForTypeName(_readJsonString());
int length = _readJsonInteger();
return new TSet(elementType, length);
}
void readSetEnd() {
_readJsonArrayEnd();
}
bool readBool() {
return _readJsonInteger() == 0 ? false : true;
}
int readByte() {
return _readJsonInteger();
}
int readI16() {
return _readJsonInteger();
}
int readI32() {
return _readJsonInteger();
}
int readI64() {
return _readJsonInteger();
}
double readDouble() {
return _readJsonDouble();
}
String readString() {
return utf8Codec.decode(_readJsonString());
}
Uint8List readBinary() {
return new Uint8List.fromList(_readJsonBase64());
}
}
class _Constants {
static const utf8codec = const Utf8Codec();
static final Uint8List HEX_0_BYTES = new Uint8List.fromList('0'.codeUnits);
static final Uint8List HEX_9_BYTES = new Uint8List.fromList('9'.codeUnits);
static final Uint8List HEX_A_BYTES = new Uint8List.fromList('a'.codeUnits);
static final Uint8List HEX_F_BYTES = new Uint8List.fromList('f'.codeUnits);
static final Uint8List COMMA_BYTES = new Uint8List.fromList(','.codeUnits);
static final Uint8List COLON_BYTES = new Uint8List.fromList(':'.codeUnits);
static final Uint8List LBRACE_BYTES = new Uint8List.fromList('{'.codeUnits);
static final Uint8List RBRACE_BYTES = new Uint8List.fromList('}'.codeUnits);
static final Uint8List LBRACKET_BYTES = new Uint8List.fromList('['.codeUnits);
static final Uint8List RBRACKET_BYTES = new Uint8List.fromList(']'.codeUnits);
static final Uint8List QUOTE_BYTES = new Uint8List.fromList('"'.codeUnits);
static final Uint8List BACKSLASH_BYTES =
new Uint8List.fromList(r'\'.codeUnits);
static final ESCSEQ_BYTES = new Uint8List.fromList(r'\u00'.codeUnits);
static final Uint8List JSON_CHAR_TABLE = new Uint8List.fromList([
0, 0, 0, 0, 0, 0, 0, 0, // 8 bytes
'b'.codeUnitAt(0), 't'.codeUnitAt(0), 'n'.codeUnitAt(0), 0, // 4 bytes
'f'.codeUnitAt(0), 'r'.codeUnitAt(0), 0, 0, // 4 bytes
0, 0, 0, 0, 0, 0, 0, 0, // 8 bytes
0, 0, 0, 0, 0, 0, 0, 0, // 8 bytes
1, 1, '"'.codeUnitAt(0), 1, 1, 1, 1, 1, // 8 bytes
1, 1, 1, 1, 1, 1, 1, 1 // 8 bytes
]);
static const String ESCAPE_CHARS = r'"\/bfnrt';
static const String ESCAPE_CHAR_VALS = '"\\/\b\f\n\r\t';
static const String NAME_BOOL = 'tf';
static const String NAME_BYTE = 'i8';
static const String NAME_I16 = 'i16';
static const String NAME_I32 = 'i32';
static const String NAME_I64 = 'i64';
static const String NAME_DOUBLE = 'dbl';
static const String NAME_STRUCT = 'rec';
static const String NAME_STRING = 'str';
static const String NAME_MAP = 'map';
static const String NAME_LIST = 'lst';
static const String NAME_SET = 'set';
static final Map<int, Uint8List> _TYPE_ID_TO_NAME_BYTES =
new Map.unmodifiable({
TType.BOOL: new Uint8List.fromList(NAME_BOOL.codeUnits),
TType.BYTE: new Uint8List.fromList(NAME_BYTE.codeUnits),
TType.I16: new Uint8List.fromList(NAME_I16.codeUnits),
TType.I32: new Uint8List.fromList(NAME_I32.codeUnits),
TType.I64: new Uint8List.fromList(NAME_I64.codeUnits),
TType.DOUBLE: new Uint8List.fromList(NAME_DOUBLE.codeUnits),
TType.STRING: new Uint8List.fromList(NAME_STRING.codeUnits),
TType.STRUCT: new Uint8List.fromList(NAME_STRUCT.codeUnits),
TType.MAP: new Uint8List.fromList(NAME_MAP.codeUnits),
TType.SET: new Uint8List.fromList(NAME_SET.codeUnits),
TType.LIST: new Uint8List.fromList(NAME_LIST.codeUnits)
});
static Uint8List getTypeNameBytesForTypeId(int typeId) {
if (!_TYPE_ID_TO_NAME_BYTES.containsKey(typeId)) {
throw new TProtocolError(
TProtocolErrorType.NOT_IMPLEMENTED, "Unrecognized type");
}
return _TYPE_ID_TO_NAME_BYTES[typeId];
}
static final Map<String, int> _NAME_TO_TYPE_ID = new Map.unmodifiable({
NAME_BOOL: TType.BOOL,
NAME_BYTE: TType.BYTE,
NAME_I16: TType.I16,
NAME_I32: TType.I32,
NAME_I64: TType.I64,
NAME_DOUBLE: TType.DOUBLE,
NAME_STRING: TType.STRING,
NAME_STRUCT: TType.STRUCT,
NAME_MAP: TType.MAP,
NAME_SET: TType.SET,
NAME_LIST: TType.LIST
});
static int getTypeIdForTypeName(Uint8List bytes) {
String name = utf8codec.decode(bytes);
if (!_NAME_TO_TYPE_ID.containsKey(name)) {
throw new TProtocolError(
TProtocolErrorType.NOT_IMPLEMENTED, "Unrecognized type");
}
return _NAME_TO_TYPE_ID[name];
}
static final Set<int> _JSON_NUMERICS = new Set.from([
'+'.codeUnitAt(0),
'-'.codeUnitAt(0),
'.'.codeUnitAt(0),
'0'.codeUnitAt(0),
'1'.codeUnitAt(0),
'2'.codeUnitAt(0),
'3'.codeUnitAt(0),
'4'.codeUnitAt(0),
'5'.codeUnitAt(0),
'6'.codeUnitAt(0),
'7'.codeUnitAt(0),
'8'.codeUnitAt(0),
'9'.codeUnitAt(0),
'E'.codeUnitAt(0),
'e'.codeUnitAt(0)
]);
static bool isJsonNumeric(int byte) {
return _JSON_NUMERICS.contains(byte);
}
}
class _LookaheadReader {
final TJsonProtocol protocol;
_LookaheadReader(this.protocol);
bool _hasData = false;
final Uint8List _data = new Uint8List(1);
int read() {
if (_hasData) {
_hasData = false;
} else {
protocol.transport.readAll(_data, 0, 1);
}
return _data[0];
}
int peek() {
if (!_hasData) {
protocol.transport.readAll(_data, 0, 1);
}
_hasData = true;
return _data[0];
}
}
class _BaseContext {
final TJsonProtocol protocol;
_BaseContext(this.protocol);
void write() {}
void read() {}
bool get escapeNumbers => false;
String toString() => 'BaseContext';
}
class _ListContext extends _BaseContext {
_ListContext(TJsonProtocol protocol) : super(protocol);
bool _first = true;
void write() {
if (_first) {
_first = false;
} else {
protocol.transport.writeAll(_Constants.COMMA_BYTES);
}
}
void read() {
if (_first) {
_first = false;
} else {
protocol._readJsonSyntaxChar(_Constants.COMMA_BYTES[0]);
}
}
String toString() => 'ListContext';
}
class _PairContext extends _BaseContext {
_PairContext(TJsonProtocol protocol) : super(protocol);
bool _first = true;
bool _colon = true;
Uint8List get symbolBytes =>
_colon ? _Constants.COLON_BYTES : _Constants.COMMA_BYTES;
void write() {
if (_first) {
_first = false;
_colon = true;
} else {
protocol.transport.writeAll(symbolBytes);
_colon = !_colon;
}
}
void read() {
if (_first) {
_first = false;
_colon = true;
} else {
protocol._readJsonSyntaxChar(symbolBytes[0]);
_colon = !_colon;
}
}
bool get escapeNumbers => _colon;
String toString() => 'PairContext';
}

View file

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

View file

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

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.
part of thrift;
class TMessageType {
static const int CALL = 1;
static const int REPLY = 2;
static const int EXCEPTION = 3;
static const int ONEWAY = 4;
}
class TMessage {
final String name;
final int type;
final int seqid;
TMessage(this.name, this.type, this.seqid);
String toString() => "<TMessage name: '$name' type: $type seqid: $seqid>";
}

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.
part of thrift;
/// Adapted from the C# version.
class TMultiplexedProtocol extends TProtocolDecorator {
static const SEPARATOR = ':';
final String _serviceName;
TMultiplexedProtocol(TProtocol protocol, String serviceName)
: _serviceName = serviceName,
super(protocol) {
if (serviceName == null) {
throw new ArgumentError.notNull("serviceName");
}
}
void writeMessageBegin(TMessage message) {
if (message.type == TMessageType.CALL ||
message.type == TMessageType.ONEWAY) {
String name = _serviceName + SEPARATOR + message.name;
message = new TMessage(name, message.type, message.seqid);
}
super.writeMessageBegin(message);
}
}

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.
part of thrift;
abstract class TProtocol {
final TTransport transport;
TProtocol(this.transport);
/// Write
void writeMessageBegin(TMessage message);
void writeMessageEnd();
void writeStructBegin(TStruct struct);
void writeStructEnd();
void writeFieldBegin(TField field);
void writeFieldEnd();
void writeFieldStop();
void writeMapBegin(TMap map);
void writeMapEnd();
void writeListBegin(TList list);
void writeListEnd();
void writeSetBegin(TSet set);
void writeSetEnd();
void writeBool(bool b);
void writeByte(int b);
void writeI16(int i16);
void writeI32(int i32);
void writeI64(int i64);
void writeDouble(double d);
void writeString(String str);
void writeBinary(Uint8List bytes);
/// Read
TMessage readMessageBegin();
void readMessageEnd();
TStruct readStructBegin();
void readStructEnd();
TField readFieldBegin();
void readFieldEnd();
TMap readMapBegin();
void readMapEnd();
TList readListBegin();
void readListEnd();
TSet readSetBegin();
void readSetEnd();
bool readBool();
int readByte();
int readI16();
int readI32();
int readI64();
double readDouble();
String readString();
Uint8List readBinary();
}

View file

@ -0,0 +1,150 @@
/// Licensed to the Apache Software Foundation (ASF) under one
/// or more contributor license agreements. See the NOTICE file
/// distributed with this work for additional information
/// regarding copyright ownership. The ASF licenses this file
/// to you under the Apache License, Version 2.0 (the
/// "License"); you may not use this file except in compliance
/// with the License. You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing,
/// software distributed under the License is distributed on an
/// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
/// KIND, either express or implied. See the License for the
/// specific language governing permissions and limitations
/// under the License.
part of thrift;
/// Forward all operations to the wrapped protocol. Used as a base class.
///
/// Adapted from the C# version.
class TProtocolDecorator extends TProtocol {
final TProtocol _protocol;
TProtocolDecorator(TProtocol protocol)
: _protocol = protocol,
super(protocol.transport);
/// Write
void writeMessageBegin(TMessage message) {
_protocol.writeMessageBegin(message);
}
void writeMessageEnd() {
_protocol.writeMessageEnd();
}
void writeStructBegin(TStruct struct) {
_protocol.writeStructBegin(struct);
}
void writeStructEnd() {
_protocol.writeStructEnd();
}
void writeFieldBegin(TField field) {
_protocol.writeFieldBegin(field);
}
void writeFieldEnd() {
_protocol.writeFieldEnd();
}
void writeFieldStop() {
_protocol.writeFieldStop();
}
void writeMapBegin(TMap map) {
_protocol.writeMapBegin(map);
}
void writeMapEnd() {
_protocol.writeMapEnd();
}
void writeListBegin(TList list) {
_protocol.writeListBegin(list);
}
void writeListEnd() {
_protocol.writeListEnd();
}
void writeSetBegin(TSet set) {
_protocol.writeSetBegin(set);
}
void writeSetEnd() {
_protocol.writeSetEnd();
}
void writeBool(bool b) {
_protocol.writeBool(b);
}
void writeByte(int b) {
_protocol.writeByte(b);
}
void writeI16(int i16) {
_protocol.writeI16(i16);
}
void writeI32(int i32) {
_protocol.writeI32(i32);
}
void writeI64(int i64) {
_protocol.writeI64(i64);
}
void writeDouble(double d) {
_protocol.writeDouble(d);
}
void writeString(String str) {
_protocol.writeString(str);
}
void writeBinary(Uint8List bytes) {
_protocol.writeBinary(bytes);
}
/// Read
TMessage readMessageBegin() => _protocol.readMessageBegin();
void readMessageEnd() => _protocol.readMessageEnd();
TStruct readStructBegin() => _protocol.readStructBegin();
void readStructEnd() => _protocol.readStructEnd();
TField readFieldBegin() => _protocol.readFieldBegin();
void readFieldEnd() => _protocol.readFieldEnd();
TMap readMapBegin() => _protocol.readMapBegin();
void readMapEnd() => _protocol.readMapEnd();
TList readListBegin() => _protocol.readListBegin();
void readListEnd() => _protocol.readListEnd();
TSet readSetBegin() => _protocol.readSetBegin();
void readSetEnd() => _protocol.readSetEnd();
bool readBool() => _protocol.readBool();
int readByte() => _protocol.readByte();
int readI16() => _protocol.readI16();
int readI32() => _protocol.readI32();
int readI64() => _protocol.readI64();
double readDouble() => _protocol.readDouble();
String readString() => _protocol.readString();
Uint8List readBinary() => _protocol.readBinary();
}

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.
part of thrift;
class TProtocolErrorType {
static const int UNKNOWN = 0;
static const int INVALID_DATA = 1;
static const int NEGATIVE_SIZE = 2;
static const int SIZE_LIMIT = 3;
static const int BAD_VERSION = 4;
static const int NOT_IMPLEMENTED = 5;
static const int DEPTH_LIMIT = 6;
}
class TProtocolError extends TError {
TProtocolError([int type = TProtocolErrorType.UNKNOWN, String message = ""])
: super(type, message);
}

View file

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

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.
part of thrift;
class TProtocolUtil {
// equal to JavaScript Number.MAX_SAFE_INTEGER, 2^53 - 1
static const int defaultRecursionLimit = 9007199254740991;
static int maxRecursionLimit = defaultRecursionLimit;
static skip(TProtocol prot, int type) {
_skip(prot, type, maxRecursionLimit);
}
static _skip(TProtocol prot, int type, int recursionLimit) {
if (recursionLimit <= 0) {
throw new TProtocolError(
TProtocolErrorType.DEPTH_LIMIT, "Depth limit exceeded");
}
switch (type) {
case TType.BOOL:
prot.readBool();
break;
case TType.BYTE:
prot.readByte();
break;
case TType.I16:
prot.readI16();
break;
case TType.I32:
prot.readI32();
break;
case TType.I64:
prot.readI64();
break;
case TType.DOUBLE:
prot.readDouble();
break;
case TType.STRING:
prot.readBinary();
break;
case TType.STRUCT:
prot.readStructBegin();
while (true) {
TField field = prot.readFieldBegin();
if (field.type == TType.STOP) {
break;
}
_skip(prot, field.type, recursionLimit - 1);
prot.readFieldEnd();
}
prot.readStructEnd();
break;
case TType.MAP:
TMap map = prot.readMapBegin();
for (int i = 0; i < map.length; i++) {
_skip(prot, map.keyType, recursionLimit - 1);
_skip(prot, map.valueType, recursionLimit - 1);
}
prot.readMapEnd();
break;
case TType.SET:
TSet set = prot.readSetBegin();
for (int i = 0; i < set.length; i++) {
_skip(prot, set.elementType, recursionLimit - 1);
}
prot.readSetEnd();
break;
case TType.LIST:
TList list = prot.readListBegin();
for (int i = 0; i < list.length; i++) {
_skip(prot, list.elementType, recursionLimit - 1);
}
prot.readListEnd();
break;
default:
break;
}
}
}

View file

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

View file

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

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.
part of thrift;
class TType {
static const int STOP = 0;
static const int VOID = 1;
static const int BOOL = 2;
static const int BYTE = 3;
static const int DOUBLE = 4;
static const int I16 = 6;
static const int I32 = 8;
static const int I64 = 10;
static const int STRING = 11;
static const int STRUCT = 12;
static const int MAP = 13;
static const int SET = 14;
static const int LIST = 15;
}

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.
part of thrift;
class TDeserializer {
final message = new TMessage('Deserializer', TMessageType.ONEWAY, 1);
TBufferedTransport transport;
TProtocol protocol;
TDeserializer({TProtocolFactory protocolFactory}) {
this.transport = new TBufferedTransport();
if (protocolFactory == null) {
protocolFactory = new TBinaryProtocolFactory();
}
this.protocol = protocolFactory.getProtocol(this.transport);
}
void read(TBase base, Uint8List data) {
transport.writeAll(data);
transport.flush();
base.read(protocol);
}
void readString(TBase base, String data) {
transport.writeAll(BASE64.decode(data));
transport.flush();
base.read(protocol);
}
}

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.
part of thrift;
class TSerializer {
final message = new TMessage('Serializer', TMessageType.ONEWAY, 1);
TBufferedTransport transport;
TProtocol protocol;
TSerializer({TProtocolFactory protocolFactory}) {
this.transport = new TBufferedTransport();
if (protocolFactory == null) {
protocolFactory = new TBinaryProtocolFactory();
}
this.protocol = protocolFactory.getProtocol(this.transport);
}
Uint8List write(TBase base) {
base.write(protocol);
return transport.consumeWriteBuffer();
}
String writeString(TBase base) {
base.write(protocol);
Uint8List bytes = transport.consumeWriteBuffer();
return BASE64.encode(bytes);
}
}

View file

@ -0,0 +1,104 @@
/// Licensed to the Apache Software Foundation (ASF) under one
/// or more contributor license agreements. See the NOTICE file
/// distributed with this work for additional information
/// regarding copyright ownership. The ASF licenses this file
/// to you under the Apache License, Version 2.0 (the
/// "License"); you may not use this file except in compliance
/// with the License. You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing,
/// software distributed under the License is distributed on an
/// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
/// KIND, either express or implied. See the License for the
/// specific language governing permissions and limitations
/// under the License.
part of thrift;
class TApplicationErrorType {
static const int UNKNOWN = 0;
static const int UNKNOWN_METHOD = 1;
static const int INVALID_MESSAGE_TYPE = 2;
static const int WRONG_METHOD_NAME = 3;
static const int BAD_SEQUENCE_ID = 4;
static const int MISSING_RESULT = 5;
static const int INTERNAL_ERROR = 6;
static const int PROTOCOL_ERROR = 7;
static const int INVALID_TRANSFORM = 8;
static const int INVALID_PROTOCOL = 9;
static const int UNSUPPORTED_CLIENT_TYPE = 10;
}
class TApplicationError extends TError {
static final TStruct _struct = new TStruct("TApplicationError");
static const int MESSAGE = 1;
static final TField _messageField =
new TField("message", TType.STRING, MESSAGE);
static const int TYPE = 2;
static final TField _typeField = new TField("type", TType.I32, TYPE);
TApplicationError(
[int type = TApplicationErrorType.UNKNOWN, String message = ""])
: super(type, message);
static TApplicationError read(TProtocol iprot) {
TField field;
String message = null;
int type = TApplicationErrorType.UNKNOWN;
iprot.readStructBegin();
while (true) {
field = iprot.readFieldBegin();
if (field.type == TType.STOP) {
break;
}
switch (field.id) {
case MESSAGE:
if (field.type == TType.STRING) {
message = iprot.readString();
} else {
TProtocolUtil.skip(iprot, field.type);
}
break;
case TYPE:
if (field.type == TType.I32) {
type = iprot.readI32();
} else {
TProtocolUtil.skip(iprot, field.type);
}
break;
default:
TProtocolUtil.skip(iprot, field.type);
break;
}
iprot.readFieldEnd();
}
iprot.readStructEnd();
return new TApplicationError(type, message);
}
write(TProtocol oprot) {
oprot.writeStructBegin(_struct);
if (message != null && !message.isEmpty) {
oprot.writeFieldBegin(_messageField);
oprot.writeString(message);
oprot.writeFieldEnd();
}
oprot.writeFieldBegin(_typeField);
oprot.writeI32(type);
oprot.writeFieldEnd();
oprot.writeFieldStop();
oprot.writeStructEnd();
}
}

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.
part of thrift;
abstract class TBase {
/// Reads the TObject from the given input protocol.
void read(TProtocol iprot);
/// Writes the objects out to the [oprot] protocol.
void write(TProtocol oprot);
/// Check if a field is currently set or unset, using the [fieldId].
bool isSet(int fieldId);
/// Get a field's value by [fieldId]. Primitive types will be wrapped in the
/// appropriate "boxed" types.
getFieldValue(int fieldId);
/// Set a field's value by [fieldId]. Primitive types must be "boxed" in the
/// appropriate object wrapper type.
setFieldValue(int fieldId, Object value);
}

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.
part of thrift;
class TError extends Error {
final String message;
final int type;
TError(this.type, this.message);
String toString() => "<TError type: $type message: '$message'>";
}

View file

@ -0,0 +1,24 @@
/// Licensed to the Apache Software Foundation (ASF) under one
/// or more contributor license agreements. See the NOTICE file
/// distributed with this work for additional information
/// regarding copyright ownership. The ASF licenses this file
/// to you under the Apache License, Version 2.0 (the
/// "License"); you may not use this file except in compliance
/// with the License. You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing,
/// software distributed under the License is distributed on an
/// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
/// KIND, either express or implied. See the License for the
/// specific language governing permissions and limitations
/// under the License.
part of thrift;
/// A processor is a generic object which operates upon an input stream and
/// writes to some output stream.
abstract class TProcessor {
bool process(TProtocol input, TProtocol output);
}

View file

@ -0,0 +1,98 @@
/// Licensed to the Apache Software Foundation (ASF) under one
/// or more contributor license agreements. See the NOTICE file
/// distributed with this work for additional information
/// regarding copyright ownership. The ASF licenses this file
/// to you under the Apache License, Version 2.0 (the
/// "License"); you may not use this file except in compliance
/// with the License. You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing,
/// software distributed under the License is distributed on an
/// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
/// KIND, either express or implied. See the License for the
/// specific language governing permissions and limitations
/// under the License.
part of thrift;
/// Buffered implementation of [TTransport].
class TBufferedTransport extends TTransport {
final List<int> _writeBuffer = [];
Iterator<int> _readIterator;
Uint8List consumeWriteBuffer() {
Uint8List buffer = new Uint8List.fromList(_writeBuffer);
_writeBuffer.clear();
return buffer;
}
void _setReadBuffer(Uint8List readBuffer) {
_readIterator = readBuffer != null ? readBuffer.iterator : null;
}
void _reset({bool isOpen: false}) {
_isOpen = isOpen;
_writeBuffer.clear();
_readIterator = null;
}
bool get hasReadData => _readIterator != null;
bool _isOpen;
bool get isOpen => _isOpen;
Future open() async {
_reset(isOpen: true);
}
Future close() async {
_reset(isOpen: false);
}
int read(Uint8List buffer, int offset, int length) {
if (buffer == null) {
throw new ArgumentError.notNull("buffer");
}
if (offset + length > buffer.length) {
throw new ArgumentError("The range exceeds the buffer length");
}
if (_readIterator == null || length <= 0) {
return 0;
}
int i = 0;
while (i < length && _readIterator.moveNext()) {
buffer[offset + i] = _readIterator.current;
i++;
}
// cleanup iterator when we've reached the end
if (_readIterator.current == null) {
_readIterator = null;
}
return i;
}
void write(Uint8List buffer, int offset, int length) {
if (buffer == null) {
throw new ArgumentError.notNull("buffer");
}
if (offset + length > buffer.length) {
throw new ArgumentError("The range exceeds the buffer length");
}
_writeBuffer.addAll(buffer.sublist(offset, offset + length));
}
Future flush() {
_readIterator = consumeWriteBuffer().iterator;
return new Future.value();
}
}

View file

@ -0,0 +1,83 @@
/// Licensed to the Apache Software Foundation (ASF) under one
/// or more contributor license agreements. See the NOTICE file
/// distributed with this work for additional information
/// regarding copyright ownership. The ASF licenses this file
/// to you under the Apache License, Version 2.0 (the
/// "License"); you may not use this file except in compliance
/// with the License. You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing,
/// software distributed under the License is distributed on an
/// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
/// KIND, either express or implied. See the License for the
/// specific language governing permissions and limitations
/// under the License.
part of thrift;
/// Framed [TTransport].
///
/// Adapted from the Java Framed transport.
class TFramedTransport extends TBufferedTransport {
static const int headerByteCount = 4;
final TTransport _transport;
final Uint8List headerBytes = new Uint8List(headerByteCount);
TFramedTransport(TTransport transport) : _transport = transport {
if (transport == null) {
throw new ArgumentError.notNull("transport");
}
}
bool get isOpen => _transport.isOpen;
Future open() {
_reset(isOpen: true);
return _transport.open();
}
Future close() {
_reset(isOpen: false);
return _transport.close();
}
int read(Uint8List buffer, int offset, int length) {
if (hasReadData) {
int got = super.read(buffer, offset, length);
if (got > 0) return got;
}
_readFrame();
return super.read(buffer, offset, length);
}
void _readFrame() {
_transport.readAll(headerBytes, 0, headerByteCount);
int size = headerBytes.buffer.asByteData().getUint32(0);
if (size < 0) {
throw new TTransportError(
TTransportErrorType.UNKNOWN, "Read a negative frame size: $size");
}
Uint8List buffer = new Uint8List(size);
_transport.readAll(buffer, 0, size);
_setReadBuffer(buffer);
}
Future flush() {
Uint8List buffer = consumeWriteBuffer();
int length = buffer.length;
headerBytes.buffer.asByteData().setUint32(0, length);
_transport.write(headerBytes, 0, headerByteCount);
_transport.write(buffer, 0, length);
return _transport.flush();
}
}

View file

@ -0,0 +1,100 @@
/// Licensed to the Apache Software Foundation (ASF) under one
/// or more contributor license agreements. See the NOTICE file
/// distributed with this work for additional information
/// regarding copyright ownership. The ASF licenses this file
/// to you under the Apache License, Version 2.0 (the
/// "License"); you may not use this file except in compliance
/// with the License. You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing,
/// software distributed under the License is distributed on an
/// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
/// KIND, either express or implied. See the License for the
/// specific language governing permissions and limitations
/// under the License.
part of thrift;
/// HTTP implementation of [TTransport].
///
/// For example:
///
/// var transport = new THttpClientTransport(new BrowserClient(),
/// new THttpConfig(url, {'X-My-Custom-Header': 'my value'}));
/// var protocol = new TJsonProtocol(transport);
/// var client = new MyThriftServiceClient(protocol);
/// var result = client.myMethod();
///
/// Adapted from the JS XHR HTTP transport.
class THttpClientTransport extends TBufferedTransport {
final Client httpClient;
final THttpConfig config;
THttpClientTransport(this.httpClient, this.config) {
if (httpClient == null) {
throw new ArgumentError.notNull("httpClient");
}
}
Future close() async {
_reset(isOpen: false);
httpClient.close();
}
Future flush() {
var requestBody = BASE64.encode(consumeWriteBuffer());
// Use a sync completer to ensure that the buffer can be read immediately
// after the read buffer is set, and avoid a race condition where another
// response could overwrite the read buffer.
var completer = new Completer.sync();
httpClient
.post(config.url, headers: config.headers, body: requestBody)
.then((response) {
Uint8List data;
try {
data = new Uint8List.fromList(
BASE64.decode(response.body));
} on FormatException catch (_) {
throw new TProtocolError(TProtocolErrorType.INVALID_DATA,
"Expected a Base 64 encoded string.");
}
_setReadBuffer(data);
completer.complete();
});
return completer.future;
}
}
class THttpConfig {
final Uri url;
Map<String, String> _headers;
Map<String, String> get headers => _headers;
THttpConfig(this.url, Map<String, String> headers) {
if (url == null || !url.hasAuthority) {
throw new ArgumentError("Invalid url");
}
_initHeaders(headers);
}
void _initHeaders(Map<String, String> initial) {
var h = {};
if (initial != null) {
h.addAll(initial);
}
h['Content-Type'] = 'application/x-thrift';
h['Accept'] = 'application/x-thrift';
_headers = new Map.unmodifiable(h);
}
}

View file

@ -0,0 +1,99 @@
/// Licensed to the Apache Software Foundation (ASF) under one
/// or more contributor license agreements. See the NOTICE file
/// distributed with this work for additional information
/// regarding copyright ownership. The ASF licenses this file
/// to you under the Apache License, Version 2.0 (the
/// "License"); you may not use this file except in compliance
/// with the License. You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing,
/// software distributed under the License is distributed on an
/// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
/// KIND, either express or implied. See the License for the
/// specific language governing permissions and limitations
/// under the License.
part of thrift;
/// [TMessageReader] extracts a [TMessage] from bytes. This is used to allow a
/// transport to inspect the message seqid and map responses to requests.
class TMessageReader {
final TProtocolFactory protocolFactory;
final int byteOffset;
final _TMessageReaderTransport _transport;
/// Construct a [MessageReader]. The optional [byteOffset] specifies the
/// number of bytes to skip before reading the [TMessage].
TMessageReader(this.protocolFactory, {int byteOffset: 0})
: _transport = new _TMessageReaderTransport(),
this.byteOffset = byteOffset;
TMessage readMessage(Uint8List bytes) {
_transport.reset(bytes, byteOffset);
TProtocol protocol = protocolFactory.getProtocol(_transport);
TMessage message = protocol.readMessageBegin();
_transport.reset(null);
return message;
}
}
/// An internal class used to support [TMessageReader].
class _TMessageReaderTransport extends TTransport {
_TMessageReaderTransport();
Iterator<int> _readIterator;
void reset(Uint8List bytes, [int offset = 0]) {
if (bytes == null) {
_readIterator = null;
return;
}
if (offset > bytes.length) {
throw new ArgumentError("The offset exceeds the bytes length");
}
_readIterator = bytes.iterator;
for (var i = 0; i < offset; i++) {
_readIterator.moveNext();
}
}
get isOpen => true;
Future open() => throw new UnsupportedError("Unsupported in MessageReader");
Future close() => throw new UnsupportedError("Unsupported in MessageReader");
int read(Uint8List buffer, int offset, int length) {
if (buffer == null) {
throw new ArgumentError.notNull("buffer");
}
if (offset + length > buffer.length) {
throw new ArgumentError("The range exceeds the buffer length");
}
if (_readIterator == null || length <= 0) {
return 0;
}
int i = 0;
while (i < length && _readIterator.moveNext()) {
buffer[offset + i] = _readIterator.current;
i++;
}
return i;
}
void write(Uint8List buffer, int offset, int length) =>
throw new UnsupportedError("Unsupported in MessageReader");
Future flush() => throw new UnsupportedError("Unsupported in MessageReader");
}

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.
part of thrift;
enum TSocketState { CLOSED, OPEN }
abstract class TSocket {
Stream<TSocketState> get onState;
Stream<Object> get onError;
Stream<Uint8List> get onMessage;
bool get isOpen;
bool get isClosed;
Future open();
Future close();
void send(Uint8List data);
}

View file

@ -0,0 +1,175 @@
/// Licensed to the Apache Software Foundation (ASF) under one
/// or more contributor license agreements. See the NOTICE file
/// distributed with this work for additional information
/// regarding copyright ownership. The ASF licenses this file
/// to you under the Apache License, Version 2.0 (the
/// "License"); you may not use this file except in compliance
/// with the License. You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing,
/// software distributed under the License is distributed on an
/// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
/// KIND, either express or implied. See the License for the
/// specific language governing permissions and limitations
/// under the License.
part of thrift;
/// Socket implementation of [TTransport].
///
/// For example:
///
/// var transport = new TClientSocketTransport(new TWebSocket(url));
/// var protocol = new TBinaryProtocol(transport);
/// var client = new MyThriftServiceClient(protocol);
/// var result = client.myMethod();
///
/// Adapted from the JS WebSocket transport.
abstract class TSocketTransport extends TBufferedTransport {
final Logger logger = new Logger('thrift.TSocketTransport');
final TSocket socket;
/// A transport using the provided [socket].
TSocketTransport(this.socket) {
if (socket == null) {
throw new ArgumentError.notNull('socket');
}
socket.onError.listen((e) => logger.warning(e));
socket.onMessage.listen(handleIncomingMessage);
}
bool get isOpen => socket.isOpen;
Future open() {
_reset(isOpen: true);
return socket.open();
}
Future close() {
_reset(isOpen: false);
return socket.close();
}
/// Make an incoming message available to read from the transport.
void handleIncomingMessage(Uint8List messageBytes) {
_setReadBuffer(messageBytes);
}
}
/// [TClientSocketTransport] is a basic client socket transport. It sends
/// outgoing messages and expects a response.
///
/// NOTE: This transport expects a single threaded server, as it will process
/// responses in FIFO order.
class TClientSocketTransport extends TSocketTransport {
final List<Completer<Uint8List>> _completers = [];
TClientSocketTransport(TSocket socket) : super(socket);
Future flush() {
Uint8List bytes = consumeWriteBuffer();
// Use a sync completer to ensure that the buffer can be read immediately
// after the read buffer is set, and avoid a race condition where another
// response could overwrite the read buffer.
var completer = new Completer<Uint8List>.sync();
_completers.add(completer);
socket.send(bytes);
return completer.future;
}
void handleIncomingMessage(Uint8List messageBytes) {
super.handleIncomingMessage(messageBytes);
if (_completers.isNotEmpty) {
var completer = _completers.removeAt(0);
completer.complete();
}
}
}
/// [TAsyncClientSocketTransport] sends outgoing messages and expects an
/// asynchronous response.
///
/// NOTE: This transport uses a [MessageReader] to read a [TMessage] when an
/// incoming message arrives to correlate a response to a request, using the
/// seqid.
class TAsyncClientSocketTransport extends TSocketTransport {
static const defaultTimeout = const Duration(seconds: 30);
final Map<int, Completer<Uint8List>> _completers = {};
final TMessageReader messageReader;
final Duration responseTimeout;
TAsyncClientSocketTransport(TSocket socket, TMessageReader messageReader,
{Duration responseTimeout: defaultTimeout})
: this.messageReader = messageReader,
this.responseTimeout = responseTimeout,
super(socket);
Future flush() {
Uint8List bytes = consumeWriteBuffer();
TMessage message = messageReader.readMessage(bytes);
int seqid = message.seqid;
// Use a sync completer to ensure that the buffer can be read immediately
// after the read buffer is set, and avoid a race condition where another
// response could overwrite the read buffer.
var completer = new Completer<Uint8List>.sync();
_completers[seqid] = completer;
if (responseTimeout != null) {
new Future.delayed(responseTimeout, () {
var completer = _completers.remove(seqid);
if (completer != null) {
completer.completeError(
new TimeoutException("Response timed out.", responseTimeout));
}
});
}
socket.send(bytes);
return completer.future;
}
void handleIncomingMessage(Uint8List messageBytes) {
super.handleIncomingMessage(messageBytes);
TMessage message = messageReader.readMessage(messageBytes);
var completer = _completers.remove(message.seqid);
if (completer != null) {
completer.complete();
}
}
}
/// [TServerSocketTransport] listens for incoming messages. When it sends a
/// response, it does not expect an acknowledgement.
class TServerSocketTransport extends TSocketTransport {
final StreamController _onIncomingMessageController;
Stream get onIncomingMessage => _onIncomingMessageController.stream;
TServerSocketTransport(TSocket socket)
: _onIncomingMessageController = new StreamController.broadcast(),
super(socket);
Future flush() async {
Uint8List message = consumeWriteBuffer();
socket.send(message);
}
void handleIncomingMessage(Uint8List messageBytes) {
super.handleIncomingMessage(messageBytes);
_onIncomingMessageController.add(null);
}
}

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.
part of thrift;
abstract class TTransport {
/// Queries whether the transport is open.
/// Returns [true] if the transport is open.
bool get isOpen;
/// Opens the transport for reading/writing.
/// Throws [TTransportError] if the transport could not be opened.
Future open();
/// Closes the transport.
Future close();
/// Reads up to [length] bytes into [buffer], starting at [offset].
/// Returns the number of bytes actually read.
/// Throws [TTransportError] if there was an error reading data
int read(Uint8List buffer, int offset, int length);
/// Guarantees that all of [length] bytes are actually read off the transport.
/// Returns the number of bytes actually read, which must be equal to
/// [length].
/// Throws [TTransportError] if there was an error reading data
int readAll(Uint8List buffer, int offset, int length) {
int got = 0;
int ret = 0;
while (got < length) {
ret = read(buffer, offset + got, length - got);
if (ret <= 0) {
throw new TTransportError(
TTransportErrorType.UNKNOWN,
"Cannot read. Remote side has closed. Tried to read $length "
"bytes, but only got $got bytes.");
}
got += ret;
}
return got;
}
/// Writes up to [len] bytes from the buffer.
/// Throws [TTransportError] if there was an error writing data
void write(Uint8List buffer, int offset, int length);
/// Writes the [bytes] to the output.
/// Throws [TTransportError] if there was an error writing data
void writeAll(Uint8List buffer) {
write(buffer, 0, buffer.length);
}
/// Flush any pending data out of a transport buffer.
/// Throws [TTransportError] if there was an error writing out data.
Future flush();
}

View file

@ -0,0 +1,31 @@
/// Licensed to the Apache Software Foundation (ASF) under one
/// or more contributor license agreements. See the NOTICE file
/// distributed with this work for additional information
/// regarding copyright ownership. The ASF licenses this file
/// to you under the Apache License, Version 2.0 (the
/// "License"); you may not use this file except in compliance
/// with the License. You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing,
/// software distributed under the License is distributed on an
/// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
/// KIND, either express or implied. See the License for the
/// specific language governing permissions and limitations
/// under the License.
part of thrift;
class TTransportErrorType {
static const int UNKNOWN = 0;
static const int NOT_OPEN = 1;
static const int ALREADY_OPEN = 2;
static const int TIMED_OUT = 3;
static const int END_OF_FILE = 4;
}
class TTransportError extends TError {
TTransportError([int type = TTransportErrorType.UNKNOWN, String message = ""])
: super(type, message);
}

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.
part of thrift;
/// Factory class used to create wrapped instance of a [TTransport]. This is
/// used primarily in servers.
///
/// Adapted from the Java version.
class TTransportFactory {
Future<TTransport> getTransport(TTransport transport) =>
new Future.value(transport);
}

View file

@ -0,0 +1,64 @@
/// Licensed to the Apache Software Foundation (ASF) under one
/// or more contributor license agreements. See the NOTICE file
/// distributed with this work for additional information
/// regarding copyright ownership. The ASF licenses this file
/// to you under the Apache License, Version 2.0 (the
/// "License"); you may not use this file except in compliance
/// with the License. You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing,
/// software distributed under the License is distributed on an
/// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
/// KIND, either express or implied. See the License for the
/// specific language governing permissions and limitations
/// under the License.
library thrift;
import 'dart:async';
import 'dart:collection';
import 'dart:convert' show Utf8Codec, BASE64;
import 'dart:typed_data' show ByteData;
import 'dart:typed_data' show Endianness;
import 'dart:typed_data' show Uint8List;
import 'package:fixnum/fixnum.dart';
import 'package:http/http.dart' show Client;
import 'package:logging/logging.dart';
part 'src/t_application_error.dart';
part 'src/t_base.dart';
part 'src/t_error.dart';
part 'src/t_processor.dart';
part 'src/protocol/t_binary_protocol.dart';
part 'src/protocol/t_compact_protocol.dart';
part 'src/protocol/t_field.dart';
part 'src/protocol/t_json_protocol.dart';
part 'src/protocol/t_list.dart';
part 'src/protocol/t_map.dart';
part 'src/protocol/t_message.dart';
part 'src/protocol/t_multiplexed_protocol.dart';
part 'src/protocol/t_protocol.dart';
part 'src/protocol/t_protocol_decorator.dart';
part 'src/protocol/t_protocol_error.dart';
part 'src/protocol/t_protocol_factory.dart';
part 'src/protocol/t_protocol_util.dart';
part 'src/protocol/t_set.dart';
part 'src/protocol/t_struct.dart';
part 'src/protocol/t_type.dart';
part 'src/serializer/t_deserializer.dart';
part 'src/serializer/t_serializer.dart';
part 'src/transport/t_buffered_transport.dart';
part 'src/transport/t_framed_transport.dart';
part 'src/transport/t_http_transport.dart';
part 'src/transport/t_message_reader.dart';
part 'src/transport/t_socket.dart';
part 'src/transport/t_transport.dart';
part 'src/transport/t_transport_error.dart';
part 'src/transport/t_transport_factory.dart';
part 'src/transport/t_socket_transport.dart';

View file

@ -0,0 +1,22 @@
/// Licensed to the Apache Software Foundation (ASF) under one
/// or more contributor license agreements. See the NOTICE file
/// distributed with this work for additional information
/// regarding copyright ownership. The ASF licenses this file
/// to you under the Apache License, Version 2.0 (the
/// "License"); you may not use this file except in compliance
/// with the License. You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing,
/// software distributed under the License is distributed on an
/// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
/// KIND, either express or implied. See the License for the
/// specific language governing permissions and limitations
/// under the License.
library thrift_browser;
/// Classes that are only supported in browser applications go here
export 'src/browser/t_web_socket.dart' show TWebSocket;

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.
library thrift_console;
/// Classes that are only supported in console applications go here
export 'src/console/t_tcp_socket.dart' show TTcpSocket;
export 'src/console/t_web_socket.dart' show TWebSocket;

43
vendor/git.apache.org/thrift.git/lib/dart/pubspec.yaml generated vendored Normal file
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.
name: thrift
version: 0.10.0
description: >
A Dart library for Apache Thrift
author: Apache Thrift Developers <dev@thrift.apache.org>
homepage: http://thrift.apache.org
documentation: http://thrift.apache.org
environment:
sdk: ">=1.13.0 <2.0.0"
dependencies:
fixnum: ^0.10.2
http: ^0.11.3
logging: ^0.11.0
dev_dependencies:
# test
mockito: ^1.0.0
test: ^0.12.0
# dart_dev - https://github.com/Workiva/dart_dev
dart_dev: ^1.5.0
coverage: ^0.7.3
dart_style: ">=0.2.4 <0.3.0"
dartdoc: ^0.9.0

View file

@ -0,0 +1,406 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
library thrift.test.transport.t_json_protocol_test;
import 'dart:async';
import 'dart:convert' show UTF8;
import 'dart:typed_data' show Uint8List;
import 'package:test/test.dart';
import 'package:thrift/thrift.dart';
void main() {
final message = new TMessage('my message', TMessageType.ONEWAY, 123);
TProtocol protocol;
Primitive getPrimitive(int tType) {
switch (tType) {
case TType.BOOL:
return new Primitive(protocol.readBool, protocol.writeBool, false);
case TType.BYTE:
return new Primitive(protocol.readByte, protocol.writeByte, 0);
case TType.I16:
return new Primitive(protocol.readI16, protocol.writeI16, 0);
case TType.I32:
return new Primitive(protocol.readI32, protocol.writeI32, 0);
case TType.I64:
return new Primitive(protocol.readI64, protocol.writeI64, 0);
case TType.DOUBLE:
return new Primitive(protocol.readDouble, protocol.writeDouble, 0);
case TType.STRING:
return new Primitive(protocol.readString, protocol.writeString, '');
default:
throw new UnsupportedError("Unsupported TType $tType");
}
}
Future primitiveTest(Primitive primitive, input) async {
primitive.write(input);
protocol.writeMessageEnd();
await protocol.transport.flush();
protocol.readMessageBegin();
var output = primitive.read();
expect(output, input);
}
Future primitiveNullTest(Primitive primitive) async {
primitive.write(null);
protocol.writeMessageEnd();
await protocol.transport.flush();
protocol.readMessageBegin();
var output = primitive.read();
expect(output, primitive.defaultValue);
}
var sharedTests = () {
test('Test message', () async {
protocol.writeMessageEnd();
await protocol.transport.flush();
var subject = protocol.readMessageBegin();
expect(subject.name, message.name);
expect(subject.type, message.type);
expect(subject.seqid, message.seqid);
});
test('Test struct', () async {
var input = new TStruct();
protocol.writeStructBegin(input);
protocol.writeStructEnd();
protocol.writeMessageEnd();
await protocol.transport.flush();
protocol.readMessageBegin();
var output = protocol.readStructBegin();
// name is not serialized, see C# version for reference
expect(output, isNotNull);
});
test('Test field', () async {
var input = new TField('my field', TType.MAP, 123);
protocol.writeFieldBegin(input);
protocol.writeFieldEnd();
protocol.writeMessageEnd();
await protocol.transport.flush();
protocol.readMessageBegin();
var output = protocol.readFieldBegin();
// name is not serialized, see C# version for reference
expect(output.type, input.type);
expect(output.id, input.id);
});
test('Test map', () async {
var input = new TMap(TType.STRING, TType.STRUCT, 123);
protocol.writeMapBegin(input);
protocol.writeMapEnd();
protocol.writeMessageEnd();
await protocol.transport.flush();
protocol.readMessageBegin();
var output = protocol.readMapBegin();
expect(output.keyType, input.keyType);
expect(output.valueType, input.valueType);
expect(output.length, input.length);
});
test('Test list', () async {
var input = new TList(TType.STRING, 123);
protocol.writeListBegin(input);
protocol.writeListEnd();
protocol.writeMessageEnd();
await protocol.transport.flush();
protocol.readMessageBegin();
var output = protocol.readListBegin();
expect(output.elementType, input.elementType);
expect(output.length, input.length);
});
test('Test set', () async {
var input = new TSet(TType.STRING, 123);
protocol.writeSetBegin(input);
protocol.writeSetEnd();
protocol.writeMessageEnd();
await protocol.transport.flush();
protocol.readMessageBegin();
var output = protocol.readListBegin();
expect(output.elementType, input.elementType);
expect(output.length, input.length);
});
test('Test bool', () async {
await primitiveTest(getPrimitive(TType.BOOL), true);
});
test('Test bool null', () async {
await primitiveNullTest(getPrimitive(TType.BOOL));
});
test('Test byte', () async {
await primitiveTest(getPrimitive(TType.BYTE), 64);
});
test('Test byte null', () async {
await primitiveNullTest(getPrimitive(TType.BYTE));
});
test('Test I16', () async {
await primitiveTest(getPrimitive(TType.I16), 32767);
});
test('Test I16 null', () async {
await primitiveNullTest(getPrimitive(TType.I16));
});
test('Test I32', () async {
await primitiveTest(getPrimitive(TType.I32), 2147483647);
});
test('Test I32 null', () async {
await primitiveNullTest(getPrimitive(TType.I32));
});
test('Test I64', () async {
await primitiveTest(getPrimitive(TType.I64), 9223372036854775807);
});
test('Test I64 null', () async {
await primitiveNullTest(getPrimitive(TType.I64));
});
test('Test double', () async {
await primitiveTest(getPrimitive(TType.DOUBLE), 3.1415926);
});
test('Test double null', () async {
await primitiveNullTest(getPrimitive(TType.DOUBLE));
});
test('Test string', () async {
var input = 'There are only two hard things in computer science: '
'cache invalidation, naming things, and off-by-one errors.';
await primitiveTest(getPrimitive(TType.STRING), input);
});
test('Test string null', () async {
await primitiveNullTest(getPrimitive(TType.STRING));
});
test('Test binary', () async {
var input = new Uint8List.fromList(new List.filled(100, 123));
protocol.writeBinary(input);
protocol.writeMessageEnd();
await protocol.transport.flush();
protocol.readMessageBegin();
var output = protocol.readBinary();
expect(output.length, input.length);
expect(output.every((i) => i == 123), isTrue);
});
test('Test complex struct', () async {
// {1: {10: 20}, 2: {30: 40}}
protocol.writeStructBegin(new TStruct());
protocol.writeFieldBegin(new TField('success', TType.MAP, 0));
protocol.writeMapBegin(new TMap(TType.I32, TType.MAP, 2));
protocol.writeI32(1); // key
protocol.writeMapBegin(new TMap(TType.I32, TType.I32, 1));
protocol.writeI32(10); // key
protocol.writeI32(20); // value
protocol.writeMapEnd();
protocol.writeI32(2); // key
protocol.writeMapBegin(new TMap(TType.I32, TType.I32, 1));
protocol.writeI32(30); // key
protocol.writeI32(40); // value
protocol.writeMapEnd();
protocol.writeMapEnd();
protocol.writeFieldEnd();
protocol.writeFieldStop();
protocol.writeStructEnd();
protocol.writeMessageEnd();
await protocol.transport.flush();
protocol.readMessageBegin();
protocol.readStructBegin();
expect(protocol.readFieldBegin().type, TType.MAP);
expect(protocol.readMapBegin().length, 2);
expect(protocol.readI32(), 1); // key
expect(protocol.readMapBegin().length, 1);
expect(protocol.readI32(), 10); // key
expect(protocol.readI32(), 20); // value
protocol.readMapEnd();
expect(protocol.readI32(), 2); // key
expect(protocol.readMapBegin().length, 1);
expect(protocol.readI32(), 30); // key
expect(protocol.readI32(), 40); // value
protocol.readMapEnd();
protocol.readMapEnd();
protocol.readFieldEnd();
protocol.readStructEnd();
protocol.readMessageEnd();
});
test('Test nested maps and lists', () async {
// {1: [{10: 20}], 2: [{30: 40}]}
protocol.writeMapBegin(new TMap(TType.I32, TType.LIST, 2));
protocol.writeI32(1); // key
protocol.writeListBegin(new TList(TType.MAP, 1));
protocol.writeMapBegin(new TMap(TType.I32, TType.I32, 1));
protocol.writeI32(10); // key
protocol.writeI32(20); // value
protocol.writeMapEnd();
protocol.writeListEnd();
protocol.writeI32(2); // key
protocol.writeListBegin(new TList(TType.MAP, 1));
protocol.writeMapBegin(new TMap(TType.I32, TType.I32, 1));
protocol.writeI32(30); // key
protocol.writeI32(40); // value
protocol.writeMapEnd();
protocol.writeListEnd();
protocol.writeMapEnd();
protocol.writeMessageEnd();
await protocol.transport.flush();
protocol.readMessageBegin();
expect(protocol.readMapBegin().length, 2);
expect(protocol.readI32(), 1); // key
expect(protocol.readListBegin().length, 1);
expect(protocol.readMapBegin().length, 1);
expect(protocol.readI32(), 10); // key
expect(protocol.readI32(), 20); // value
protocol.readMapEnd();
protocol.readListEnd();
expect(protocol.readI32(), 2); // key
expect(protocol.readListBegin().length, 1);
expect(protocol.readMapBegin().length, 1);
expect(protocol.readI32(), 30); // key
expect(protocol.readI32(), 40); // value
protocol.readMapEnd();
protocol.readListEnd();
protocol.readMapEnd();
protocol.readMessageEnd();
});
};
group('JSON', () {
setUp(() {
protocol = new TJsonProtocol(new TBufferedTransport());
protocol.writeMessageBegin(message);
});
test('Test escaped unicode', () async {
/*
KOR_KAI
UTF-8: 0xE0 0xB8 0x81
UTF-16: 0x0E01
G clef:
UTF-8: 0xF0 0x9D 0x84 0x9E
UTF-16: 0xD834 0xDD1E
*/
var buffer = UTF8.encode(r'"\u0001\u0e01 \ud834\udd1e"');
var transport = new TBufferedTransport();
transport.writeAll(buffer);
var protocol = new TJsonProtocol(transport);
await protocol.transport.flush();
var subject = protocol.readString();
expect(subject,
UTF8.decode([0x01, 0xE0, 0xB8, 0x81, 0x20, 0xF0, 0x9D, 0x84, 0x9E]));
});
group('shared tests', sharedTests);
});
group('binary', () {
setUp(() {
protocol = new TBinaryProtocol(new TBufferedTransport());
protocol.writeMessageBegin(message);
});
group('shared tests', sharedTests);
});
group('compact', () {
setUp(() {
protocol = new TCompactProtocol(new TBufferedTransport());
protocol.writeMessageBegin(message);
});
group('shared tests', sharedTests);
});
}
class Primitive {
final Function read;
final Function write;
final defaultValue;
Primitive(this.read, this.write, this.defaultValue);
}

View file

@ -0,0 +1,119 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
library thrift.test.serializer.serializer_test;
import 'package:test/test.dart';
import 'package:thrift/thrift.dart';
import 'serializer_test_data.dart';
void main() {
var serializer = () {
TDeserializer deserializer;
TSerializer serializer;
TestTObject testTObject;
setUp(() {
serializer = new TSerializer();
deserializer = new TDeserializer();
testTObject = new TestTObject();
testTObject.b = true;
testTObject.s = "TEST";
testTObject.d = 15.25;
testTObject.i = 10;
var testList = new List<String>();
testList.add("TEST 1");
testList.add("TEST 2");
testTObject.l = testList;
});
assertNewObjectEqualsTObject(TestTObject newObject) {
expect(newObject.l, equals(testTObject.l));
expect(newObject.b, equals(testTObject.b));
expect(newObject.i, equals(testTObject.i));
expect(newObject.d, equals(testTObject.d));
expect(newObject.s, equals(testTObject.s));
}
runWriteStringTest() {
var s = serializer.writeString(testTObject);
var newObject = new TestTObject();
deserializer.readString(newObject, s);
assertNewObjectEqualsTObject(newObject);
};
runWriteTest() {
var s = serializer.write(testTObject);
var newObject = new TestTObject();
deserializer.read(newObject, s);
assertNewObjectEqualsTObject(newObject);
};
test('JSON Protocol String', () {
serializer.protocol = new TJsonProtocol(serializer.transport);
deserializer.protocol = new TJsonProtocol(deserializer.transport);
runWriteStringTest();
});
test('JSON Protocol', () {
serializer.protocol = new TJsonProtocol(serializer.transport);
deserializer.protocol = new TJsonProtocol(deserializer.transport);
runWriteTest();
});
test('Binary Protocol String', () {
serializer.protocol = new TBinaryProtocol(serializer.transport);
deserializer.protocol = new TBinaryProtocol(deserializer.transport);
runWriteStringTest();
});
test('Binary Protocol', () {
serializer.protocol = new TBinaryProtocol(serializer.transport);
deserializer.protocol = new TBinaryProtocol(deserializer.transport);
runWriteTest();
});
test('Compact Protocol String', () {
serializer.protocol = new TCompactProtocol(serializer.transport);
deserializer.protocol = new TCompactProtocol(deserializer.transport);
runWriteStringTest();
});
test('Compact Protocol', () {
serializer.protocol = new TCompactProtocol(serializer.transport);
deserializer.protocol = new TCompactProtocol(deserializer.transport);
runWriteTest();
});
};
group('Serializer', serializer);
}

View file

@ -0,0 +1,342 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
library thrift.test.serializer.serializer_test;
import 'package:thrift/thrift.dart';
/// TestTObject is a simple test struct
class TestTObject implements TBase {
static final TStruct _STRUCT_DESC = new TStruct("TestTObject");
static final TField _I_FIELD_DESC = new TField("i", TType.I32, 1);
static final TField _D_FIELD_DESC = new TField("d", TType.DOUBLE, 2);
static final TField _S_FIELD_DESC = new TField("s", TType.STRING, 3);
static final TField _L_FIELD_DESC = new TField("l", TType.LIST, 4);
static final TField _B_FIELD_DESC = new TField("b", TType.BOOL, 5);
int _i;
static const int I = 1;
double _d;
static const int D = 2;
String _s;
static const int S = 3;
List<String> _l;
static const int L = 4;
bool _b;
static const int B = 5;
bool __isset_i = false;
bool __isset_d = false;
bool __isset_b = false;
TestTObject() {
}
// i
int get i => this._i;
set i(int i) {
this._i = i;
this.__isset_i = true;
}
bool isSetI() => this.__isset_i;
unsetI() {
this.__isset_i = false;
}
// d
double get d => this._d;
set d(double d) {
this._d = d;
this.__isset_d = true;
}
bool isSetD() => this.__isset_d;
unsetD() {
this.__isset_d = false;
}
// s
String get s => this._s;
set s(String s) {
this._s = s;
}
bool isSetS() => this.s != null;
unsetS() {
this.s = null;
}
// l
List<String> get l => this._l;
set l(List<String> l) {
this._l = l;
}
bool isSetL() => this.l != null;
unsetL() {
this.l = null;
}
// b
bool get b => this._b;
set b(bool b) {
this._b = b;
this.__isset_b = true;
}
bool isSetB() => this.__isset_b;
unsetB() {
this.__isset_b = false;
}
getFieldValue(int fieldID) {
switch (fieldID) {
case I:
return this.i;
case D:
return this.d;
case S:
return this.s;
case L:
return this.l;
case B:
return this.b;
default:
throw new ArgumentError("Field $fieldID doesn't exist!");
}
}
setFieldValue(int fieldID, Object value) {
switch (fieldID) {
case I:
if (value == null) {
unsetI();
} else {
this.i = value;
}
break;
case D:
if (value == null) {
unsetD();
} else {
this.d = value;
}
break;
case S:
if (value == null) {
unsetS();
} else {
this.s = value;
}
break;
case L:
if (value == null) {
unsetL();
} else {
this.l = value as List<String>;
}
break;
case B:
if (value == null) {
unsetB();
} else {
this.b = value;
}
break;
default:
throw new ArgumentError("Field $fieldID doesn't exist!");
}
}
// Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise
bool isSet(int fieldID) {
switch (fieldID) {
case I:
return isSetI();
case D:
return isSetD();
case S:
return isSetS();
case L:
return isSetL();
case B:
return isSetB();
default:
throw new ArgumentError("Field $fieldID doesn't exist!");
}
}
read(TProtocol iprot) {
TField field;
iprot.readStructBegin();
while (true) {
field = iprot.readFieldBegin();
if (field.type == TType.STOP) {
break;
}
switch (field.id) {
case I:
if (field.type == TType.I32) {
this.i = iprot.readI32();
this.__isset_i = true;
} else {
TProtocolUtil.skip(iprot, field.type);
}
break;
case D:
if (field.type == TType.DOUBLE) {
this.d = iprot.readDouble();
this.__isset_d = true;
} else {
TProtocolUtil.skip(iprot, field.type);
}
break;
case S:
if (field.type == TType.STRING) {
this.s = iprot.readString();
} else {
TProtocolUtil.skip(iprot, field.type);
}
break;
case L:
if (field.type == TType.LIST) {
{
TList _list74 = iprot.readListBegin();
this.l = new List<String>();
for (int _i75 = 0; _i75 < _list74.length; ++_i75) {
String _elem76;
_elem76 = iprot.readString();
this.l.add(_elem76);
}
iprot.readListEnd();
}
} else {
TProtocolUtil.skip(iprot, field.type);
}
break;
case B:
if (field.type == TType.BOOL) {
this.b = iprot.readBool();
this.__isset_b = true;
} else {
TProtocolUtil.skip(iprot, field.type);
}
break;
default:
TProtocolUtil.skip(iprot, field.type);
break;
}
iprot.readFieldEnd();
}
iprot.readStructEnd();
// check for required fields of primitive type, which can't be checked in the validate method
validate();
}
write(TProtocol oprot) {
validate();
oprot.writeStructBegin(_STRUCT_DESC);
oprot.writeFieldBegin(_I_FIELD_DESC);
oprot.writeI32(this.i);
oprot.writeFieldEnd();
oprot.writeFieldBegin(_D_FIELD_DESC);
oprot.writeDouble(this.d);
oprot.writeFieldEnd();
if (this.s != null) {
oprot.writeFieldBegin(_S_FIELD_DESC);
oprot.writeString(this.s);
oprot.writeFieldEnd();
}
if (this.l != null) {
oprot.writeFieldBegin(_L_FIELD_DESC);
{
oprot.writeListBegin(new TList(TType.STRING, this.l.length));
for (var elem77 in this.l) {
oprot.writeString(elem77);
}
oprot.writeListEnd();
}
oprot.writeFieldEnd();
}
oprot.writeFieldBegin(_B_FIELD_DESC);
oprot.writeBool(this.b);
oprot.writeFieldEnd();
oprot.writeFieldStop();
oprot.writeStructEnd();
}
String toString() {
StringBuffer ret = new StringBuffer("TestTObject(");
ret.write("i:");
ret.write(this.i);
ret.write(", ");
ret.write("d:");
ret.write(this.d);
ret.write(", ");
ret.write("s:");
if (this.s == null) {
ret.write("null");
} else {
ret.write(this.s);
}
ret.write(", ");
ret.write("l:");
if (this.l == null) {
ret.write("null");
} else {
ret.write(this.l);
}
ret.write(", ");
ret.write("b:");
ret.write(this.b);
ret.write(")");
return ret.toString();
}
validate() {
// check for required fields
// check that fields of type enum have valid values
}
}

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.
library thrift.test.t_application_error_test;
import 'package:test/test.dart';
import 'package:thrift/thrift.dart';
void main() {
TProtocol protocol;
setUp(() {
protocol = new TBinaryProtocol(new TBufferedTransport());
});
test('Write and read an application error', () {
var expectedType = TApplicationErrorType.INTERNAL_ERROR;
var expectedMessage = 'test error message';
TApplicationError error =
new TApplicationError(expectedType, expectedMessage);
error.write(protocol);
protocol.transport.flush();
TApplicationError subject = TApplicationError.read(protocol);
expect(subject, isNotNull);
expect(subject.type, expectedType);
expect(subject.message, expectedMessage);
});
}

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.
library thrift.test.transport.t_socket_transport_test;
import 'dart:async';
import 'dart:convert' show Encoding;
import 'dart:convert' show Utf8Codec, BASE64;
import 'dart:typed_data' show Uint8List;
import 'package:http/http.dart' show BaseRequest;
import 'package:http/http.dart' show Client;
import 'package:http/http.dart' show Response;
import 'package:http/http.dart' show StreamedResponse;
import 'package:test/test.dart';
import 'package:thrift/thrift.dart';
void main() {
const utf8Codec = const Utf8Codec();
group('THttpClientTransport', () {
FakeHttpClient client;
THttpClientTransport transport;
setUp(() {
client = new FakeHttpClient(sync: false);
var config = new THttpConfig(Uri.parse('http://localhost'), {});
transport = new THttpClientTransport(client, config);
});
test('Test transport sends body', () async {
var expectedText = 'my request';
transport.writeAll(utf8Codec.encode(expectedText));
expect(client.postRequest, isEmpty);
await transport.flush();
expect(client.postRequest, isNotEmpty);
var requestText =
utf8Codec.decode(BASE64.decode(client.postRequest));
expect(requestText, expectedText);
});
test('Test transport receives response', () async {
var expectedText = 'my response';
var expectedBytes = utf8Codec.encode(expectedText);
client.postResponse = BASE64.encode(expectedBytes);
transport.writeAll(utf8Codec.encode('my request'));
expect(transport.hasReadData, isFalse);
await transport.flush();
expect(transport.hasReadData, isTrue);
var buffer = new Uint8List(expectedBytes.length);
transport.readAll(buffer, 0, expectedBytes.length);
var bufferText = utf8Codec.decode(buffer);
expect(bufferText, expectedText);
});
});
group('THttpClientTransport with multiple messages', () {
FakeHttpClient client;
THttpClientTransport transport;
setUp(() {
client = new FakeHttpClient(sync: true);
var config = new THttpConfig(Uri.parse('http://localhost'), {});
transport = new THttpClientTransport(client, config);
});
test('Test read correct buffer after flush', () async {
String bufferText;
var expectedText = 'response 1';
var expectedBytes = utf8Codec.encode(expectedText);
// prepare a response
transport.writeAll(utf8Codec.encode('request 1'));
client.postResponse = BASE64.encode(expectedBytes);
Future responseReady = transport.flush().then((_) {
var buffer = new Uint8List(expectedBytes.length);
transport.readAll(buffer, 0, expectedBytes.length);
bufferText = utf8Codec.decode(buffer);
});
// prepare a second response
transport.writeAll(utf8Codec.encode('request 2'));
var response2Bytes = utf8Codec.encode('response 2');
client.postResponse = BASE64.encode(response2Bytes);
await transport.flush();
await responseReady;
expect(bufferText, expectedText);
});
});
}
class FakeHttpClient implements Client {
String postResponse = '';
String postRequest = '';
final bool sync;
FakeHttpClient({this.sync: false});
Future<Response> post(url,
{Map<String, String> headers, body, Encoding encoding}) {
postRequest = body;
var response = new Response(postResponse, 200);
if (sync) {
return new Future.sync(() => response);
} else {
return new Future.value(response);
}
}
Future<Response> head(url, {Map<String, String> headers}) =>
throw new UnimplementedError();
Future<Response> get(url, {Map<String, String> headers}) =>
throw new UnimplementedError();
Future<Response> put(url,
{Map<String, String> headers, body, Encoding encoding}) =>
throw new UnimplementedError();
Future<Response> patch(url,
{Map<String, String> headers, body, Encoding encoding}) =>
throw new UnimplementedError();
Future<Response> delete(url, {Map<String, String> headers}) =>
throw new UnimplementedError();
Future<String> read(url, {Map<String, String> headers}) =>
throw new UnimplementedError();
Future<Uint8List> readBytes(url, {Map<String, String> headers}) =>
throw new UnimplementedError();
Future<StreamedResponse> send(BaseRequest request) =>
throw new UnimplementedError();
void close() => throw new UnimplementedError();
}

View file

@ -0,0 +1,311 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
library thrift.test.transport.t_socket_transport_test;
import 'dart:async';
import 'dart:convert' show Utf8Codec, BASE64;
import 'dart:typed_data' show Uint8List;
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';
import 'package:thrift/thrift.dart';
void main() {
const utf8Codec = const Utf8Codec();
final requestText = 'my test request';
final requestBytes = new Uint8List.fromList(utf8Codec.encode(requestText));
final requestBase64 = BASE64.encode(requestBytes);
final responseText = 'response 1';
final responseBytes = new Uint8List.fromList(utf8Codec.encode(responseText));
final responseBase64 = BASE64.encode(responseBytes);
final framedResponseBase64 =
BASE64.encode(_getFramedResponse(responseBytes));
group('TClientSocketTransport', () {
FakeSocket socket;
TTransport transport;
setUp(() async {
socket = new FakeSocket(sync: false);
await socket.open();
transport = new TClientSocketTransport(socket);
await transport.open();
transport.writeAll(requestBytes);
});
test('Test client sending data over transport', () async {
expect(socket.sendPayload, isNull);
Future responseReady = transport.flush();
// allow microtask events to finish
await new Future.value();
expect(socket.sendPayload, isNotNull);
expect(socket.sendPayload, requestBytes);
// simulate a response
socket.receiveFakeMessage(responseBase64);
await responseReady;
var buffer = new Uint8List(responseBytes.length);
transport.readAll(buffer, 0, responseBytes.length);
var bufferText = utf8Codec.decode(buffer);
expect(bufferText, responseText);
});
}, timeout: new Timeout(new Duration(seconds: 1)));
group('TClientSocketTransport with FramedTransport', () {
FakeSocket socket;
TTransport transport;
setUp(() async {
socket = new FakeSocket(sync: true);
await socket.open();
transport = new TFramedTransport(new TClientSocketTransport(socket));
await transport.open();
transport.writeAll(requestBytes);
});
test('Test client sending data over framed transport', () async {
String bufferText;
Future responseReady = transport.flush().then((_) {
var buffer = new Uint8List(responseBytes.length);
transport.readAll(buffer, 0, responseBytes.length);
bufferText = utf8Codec.decode(buffer);
});
// simulate a response
socket.receiveFakeMessage(framedResponseBase64);
await responseReady;
expect(bufferText, responseText);
});
}, timeout: new Timeout(new Duration(seconds: 1)));
group('TAsyncClientSocketTransport', () {
FakeSocket socket;
FakeProtocolFactory protocolFactory;
TTransport transport;
setUp(() async {
socket = new FakeSocket(sync: true);
await socket.open();
protocolFactory = new FakeProtocolFactory();
protocolFactory.message = new TMessage('foo', TMessageType.CALL, 123);
transport = new TAsyncClientSocketTransport(
socket, new TMessageReader(protocolFactory),
responseTimeout: Duration.ZERO);
await transport.open();
transport.writeAll(requestBytes);
});
test('Test response correlates to correct request', () async {
String bufferText;
Future responseReady = transport.flush().then((_) {
var buffer = new Uint8List(responseBytes.length);
transport.readAll(buffer, 0, responseBytes.length);
bufferText = utf8Codec.decode(buffer);
});
// simulate a response
protocolFactory.message = new TMessage('foo', TMessageType.REPLY, 123);
socket.receiveFakeMessage(responseBase64);
// simulate a second response
var response2Text = 'response 2';
var response2Bytes =
new Uint8List.fromList(utf8Codec.encode(response2Text));
var response2Base64 = BASE64.encode(response2Bytes);
protocolFactory.message = new TMessage('foo2', TMessageType.REPLY, 124);
socket.receiveFakeMessage(response2Base64);
await responseReady;
expect(bufferText, responseText);
});
test('Test response timeout', () async {
Future responseReady = transport.flush();
expect(responseReady, throwsA(new isInstanceOf<TimeoutException>()));
});
}, timeout: new Timeout(new Duration(seconds: 1)));
group('TAsyncClientSocketTransport with TFramedTransport', () {
FakeSocket socket;
FakeProtocolFactory protocolFactory;
TTransport transport;
setUp(() async {
socket = new FakeSocket(sync: true);
await socket.open();
protocolFactory = new FakeProtocolFactory();
protocolFactory.message = new TMessage('foo', TMessageType.CALL, 123);
var messageReader = new TMessageReader(protocolFactory,
byteOffset: TFramedTransport.headerByteCount);
transport = new TFramedTransport(new TAsyncClientSocketTransport(
socket, messageReader,
responseTimeout: Duration.ZERO));
await transport.open();
transport.writeAll(requestBytes);
});
test('Test async client sending data over framed transport', () async {
String bufferText;
Future responseReady = transport.flush().then((_) {
var buffer = new Uint8List(responseBytes.length);
transport.readAll(buffer, 0, responseBytes.length);
bufferText = utf8Codec.decode(buffer);
});
// simulate a response
protocolFactory.message = new TMessage('foo', TMessageType.REPLY, 123);
socket.receiveFakeMessage(framedResponseBase64);
await responseReady;
expect(bufferText, responseText);
});
}, timeout: new Timeout(new Duration(seconds: 1)));
group('TServerTransport', () {
test('Test server transport listens to socket', () async {
var socket = new FakeSocket();
await socket.open();
expect(socket.isOpen, isTrue);
var transport = new TServerSocketTransport(socket);
expect(transport.hasReadData, isFalse);
socket.receiveFakeMessage(requestBase64);
// allow microtask events to finish
await new Future.value();
expect(transport.hasReadData, isTrue);
var buffer = new Uint8List(requestBytes.length);
transport.readAll(buffer, 0, requestBytes.length);
var bufferText = utf8Codec.decode(buffer);
expect(bufferText, requestText);
});
test('Test server sending data over transport', () async {
var socket = new FakeSocket();
await socket.open();
var transport = new TServerSocketTransport(socket);
transport.writeAll(responseBytes);
expect(socket.sendPayload, isNull);
transport.flush();
// allow microtask events to finish
await new Future.value();
expect(socket.sendPayload, isNotNull);
expect(socket.sendPayload, responseBytes);
});
}, timeout: new Timeout(new Duration(seconds: 1)));
}
class FakeSocket extends TSocket {
final StreamController<TSocketState> _onStateController;
Stream<TSocketState> get onState => _onStateController.stream;
final StreamController<Object> _onErrorController;
Stream<Object> get onError => _onErrorController.stream;
final StreamController<Uint8List> _onMessageController;
Stream<Uint8List> get onMessage => _onMessageController.stream;
FakeSocket({bool sync: false})
: _onStateController = new StreamController.broadcast(sync: sync),
_onErrorController = new StreamController.broadcast(sync: sync),
_onMessageController = new StreamController.broadcast(sync: sync);
bool _isOpen;
bool get isOpen => _isOpen;
bool get isClosed => !isOpen;
Future open() async {
_isOpen = true;
_onStateController.add(TSocketState.OPEN);
}
Future close() async {
_isOpen = false;
_onStateController.add(TSocketState.CLOSED);
}
Uint8List _sendPayload;
Uint8List get sendPayload => _sendPayload;
void send(Uint8List data) {
if (!isOpen) throw new StateError('The socket is not open');
_sendPayload = data;
}
void receiveFakeMessage(String base64) {
if (!isOpen) throw new StateError('The socket is not open');
var message =
new Uint8List.fromList(BASE64.decode(base64));
_onMessageController.add(message);
}
}
class FakeProtocolFactory implements TProtocolFactory {
FakeProtocolFactory();
TMessage message;
getProtocol(TTransport transport) => new FakeProtocol(message);
}
class FakeProtocol extends Mock implements TProtocol {
FakeProtocol(this._message);
TMessage _message;
readMessageBegin() => _message;
}
Uint8List _getFramedResponse(Uint8List responseBytes) {
var byteOffset = TFramedTransport.headerByteCount;
var response = new Uint8List(byteOffset + responseBytes.length);
response.buffer.asByteData().setInt32(0, responseBytes.length);
response.setAll(byteOffset, responseBytes);
return response;
}

View file

@ -0,0 +1,41 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
library thrift.test.transport.t_socket_transport_test;
import 'package:test/test.dart';
import 'package:thrift/thrift.dart';
/// Common transport tests
void main() {
group('TTransportFactory', () {
test('transport is returned from base factory', () async {
TTransport result;
TTransport transport = null;
var factory = new TTransportFactory();
result = await factory.getTransport(transport);
expect(result, isNull);
transport = new TBufferedTransport();
result = await factory.getTransport(transport);
expect(result, transport);
});
});
}

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.
library tool.dev;
import 'package:dart_dev/dart_dev.dart' show dev, config;
main(List<String> args) async {
// https://github.com/Workiva/dart_dev
var directories = ['lib/', 'test/', 'tool/'];
config.analyze.entryPoints = directories;
config.format.directories = directories;
config.copyLicense
..licensePath = 'LICENSE_HEADER'
..directories = directories;
await dev(args);
}