| Did you know ... | Search Documentation: |
| Example: Heterogeneous Collections |
This is an example of using the low-level interface.
The following example shows how one can specify a Protocol Buffer message that can deal with variable-length, unstructured bags of numbers:
compound_protobuf(complex(Real, Img), group(12, [double(1, Real), double(2, Img)])).
compound_protobuf(float(Val), float(13, Val)).
compound_protobuf(double(Val), double(14, Val)).
compound_protobuf((Num rdiv Den), group(15, [integer(1, Num), integer(2, Den)])).
compound_protobuf(integer(Val), integer(16, Val)).
protobuf_bag([], []).
protobuf_bag([ Type | More], WireCodes) :-
compound_protobuf(Type, X),
Proto = protobuf([embedded(1, protobuf([X]))]),
protobuf_message(Proto, WireCodes, WireCodes1),
protobuf_bag(More, WireCodes1), !.
Use it as follows:
?- protobuf_bag([complex(2,3), complex(4,5),
complex(6,7), 355 rdiv -113, integer(11)], X).
X = [10, 20, 99, 9, 0, 0, 0, 0, 0|...].
?- protobuf_bag(Y, $X).
Y = [complex(2.0, 3.0), complex(4.0, 5.0),
complex(6.0, 7.0), 355 rdiv -113, integer(11)].
A protobuf description that is compatible with the above wire stream follows:
message compound_protobuf {
optional group Complex = 12 {
required double real = 1;
required double img = 2;
};
optional group Fraction = 15 {
required sint64 num = 1;
required sint64 den = 2;
};
optional float float = 13;
optional double double = 14;
optional sint32 integer = 16;
}
message protobuf_bag {
repeated compound_protobuf bag = 1;
Verify the wire stream using the protobuf compiler's decoder:
$ protoc --decode=protobuf_bag pb_vector.proto <tmp96.tmp
bag {
Complex {
real: 2
img: 3
}
}
bag {
Complex {
real: 4
img: 5
}
}
bag {
Complex {
real: 6
img: 7
}
}
bag {
Fraction {
num: 355
den: -113
}
}
bag {
integer: 11
}