parent
6841d112b0
commit
023b43dacf
3 changed files with 106 additions and 0 deletions
@ -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