parent
6841d112b0
commit
023b43dacf
|
@ -0,0 +1,106 @@
|
|||
import 'package:pb_runtime/ffi/bytes.dart';
|
||||
import 'package:third_party.protobuf.conformance/conformance.upb.dart';
|
||||
import 'package:third_party.protobuf/test_messages_proto2.upb.dart';
|
||||
import 'package:third_party.protobuf/test_messages_proto3.upb.dart';
|
||||
|
||||
import 'dart:io';
|
||||
import 'package:pb_runtime/pb_runtime.dart' as pb;
|
||||
|
||||
List<int>? readFromStdin(int numBytes) {
|
||||
final bytesOut = <int>[];
|
||||
for (var i = 0; i < numBytes; i++) {
|
||||
final byte = stdin.readByteSync();
|
||||
if (byte == -1) return null;
|
||||
bytesOut.add(byte);
|
||||
}
|
||||
return bytesOut;
|
||||
}
|
||||
|
||||
int readLittleEndianIntFromStdin() {
|
||||
final buf = readFromStdin(4);
|
||||
if (buf == null) return -1;
|
||||
return (buf[0] & 0xff) |
|
||||
((buf[1] & 0xff) << 8) |
|
||||
((buf[2] & 0xff) << 16) |
|
||||
((buf[3] & 0xff) << 24);
|
||||
}
|
||||
|
||||
void writeLittleEndianIntToStdout(int value) {
|
||||
final buf = <int>[];
|
||||
buf.add(value & 0xff);
|
||||
buf.add((value >> 8) & 0xff);
|
||||
buf.add((value >> 16) & 0xff);
|
||||
buf.add((value >> 24) & 0xff);
|
||||
stdout.add(buf);
|
||||
}
|
||||
|
||||
ConformanceResponse doTest(ConformanceRequest request) {
|
||||
final response = ConformanceResponse();
|
||||
pb.GeneratedMessage? testMessage;
|
||||
final messageType = request.messageType;
|
||||
final isProto3 =
|
||||
messageType == 'protobuf_test_messages.proto3.TestAllTypesProto3';
|
||||
|
||||
if (!isProto3 &&
|
||||
messageType != 'protobuf_test_messages.proto2.TestAllTypesProto2') {
|
||||
throw ArgumentError('Invalid message type $messageType');
|
||||
}
|
||||
|
||||
switch (request.whichPayload) {
|
||||
case ConformanceRequest_payload.protobufPayload:
|
||||
try {
|
||||
testMessage = isProto3
|
||||
? TestAllTypesProto3.fromBinary(request.protobufPayload.data)
|
||||
: TestAllTypesProto2.fromBinary(request.protobufPayload.data);
|
||||
} catch (e) {
|
||||
final parseErrorResponse = ConformanceResponse();
|
||||
parseErrorResponse.parseError = '$e';
|
||||
return parseErrorResponse;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
response.skipped = 'Only protobuf payload input is supported';
|
||||
return response;
|
||||
}
|
||||
|
||||
switch (request.requestedOutputFormat) {
|
||||
case WireFormat.PROTOBUF:
|
||||
try {
|
||||
response.protobufPayload =
|
||||
Bytes(pb.GeneratedMessage.toBinary(testMessage));
|
||||
} catch (e) {
|
||||
response.serializeError = '$e';
|
||||
}
|
||||
break;
|
||||
default:
|
||||
response.skipped = 'Only protobuf payload output is supported';
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
Future<bool> doTestIo() async {
|
||||
final msgLength = readLittleEndianIntFromStdin();
|
||||
if (msgLength == -1) return false; // EOF
|
||||
final serializedMsg = readFromStdin(msgLength);
|
||||
if (serializedMsg == null) {
|
||||
throw 'Unexpected EOF from test program.';
|
||||
}
|
||||
final request = ConformanceRequest.fromBinary(serializedMsg);
|
||||
final response = doTest(request);
|
||||
final serializedOutput = pb.GeneratedMessage.toBinary(response);
|
||||
writeLittleEndianIntToStdout(serializedOutput.length);
|
||||
stdout.add(serializedOutput);
|
||||
await stdout.flush();
|
||||
return true;
|
||||
}
|
||||
|
||||
void main() async {
|
||||
await pb.initGlobalInstance();
|
||||
var testCount = 0;
|
||||
while (await doTestIo()) {
|
||||
testCount++;
|
||||
}
|
||||
stderr.writeln(
|
||||
'ConformanceDart: received EOF from test runner after $testCount tests');
|
||||
}
|
Loading…
Reference in New Issue