Releases: xaxys/bubbler
v1.3.1
v1.3.0
Command Option Added: -rmpath
-rmpath <path[,path...]>
: Remove Path Prefix (Remove the path prefix of the output file path when generating files)
This option is usually used when generating Go target. For example, if a .bb
file has go_package
option set to github.com/xaxys/bubbler/proto/rpc
, the generated file will be generated in the output/github.com/xaxys/bubbler/proto/rpc
directory. If you want to remove the path prefix github.com/xaxys/bubbler/proto/rpc
, you can set this option to github.com/xaxys/bubbler/proto
. Then the generated file will be generated in the output/rpc
directory.
It can be use like this:
bubbler -t go -rmpath github.com/xaxys/bubbler/proto -o output example.bb
Changelog
- cccf4a4 Add rmpath option
v1.2.2
v1.2.1
v1.2.0
Go Language Target is Supported!
Now you can use go as language target, like this:
bubbler -t go -o /path/to/mydir/ ./example.bb
go
: Go language, output one.bb.go
file for each.bb
file. The folder structure will be affected by thego_package
option. (i.e.,github.com/xaxys/bubbler
will generate in thegithub.com/xaxys/bubbler
directory)- With
-single
: Output one file that includes all definitions for all.bb
files. The output file name (including the extension) is determined by the-o
option. The package name is determined by the package statement of the input.bb
file. - With
-memcpy
: make a copy of thebytes
field when decoding. Thestring
field will always be copied. - Without
-memcpy
: a slice of the original buffer will be assigned to thebytes
field. Thestring
field will always be copied.
- With
Changelog
v1.1.1
v1.1.0
C++ Language Target is Supported!
Now you can use c++ as language target, like this:
bubbler -t cpp -o /path/to/mydir/ ./example.bb
cpp
: C++ language, output one.bb.hpp
file and one.bb.cpp
file for each.bb
file.- With
-single
: Output one file that includes all definitions for all.bb
files. The output file name (including the extension) is determined by the-o
option. - With
-minimal
: No generation of getter/setter methods for fields. - With
-memcpy
: Usestd::shared_ptr<uint8_t[]>
to heap-allocate memory forbytes
fields, and copy the content from the original buffer.string
fields will always usestd::string
and copied every time. - Without
-memcpy
: Usestd::shared_ptr<uint8_t[]>
with null deleter to reference the original buffer forbytes
fields.string
fields will always usestd::string
and copied every time.
- With
Changelog
Snapshot v1.0.0-5c730fd-dev
Fix format of C target Signed-off-by: xaxys <[email protected]>
v1.0.0
Var-sized Type string
& bytes
are Supported!
Use the string
and bytes
to send variable-sized data. For example:
struct Frame {
int32 code;
string msg;
bytes data;
}
String
String type is used for send string message. In binary form, the text encoding of a string field is UTF8. Since a string shouldn't contain any EOF character, the end of a string is defined by \0
in data stream. So the size of a string field is str.utf8_length + 1
. String type is not supposed to store too long message, because in programming language there is usually no zero-copy feature for string and encoding/decoding cost could be high.
Bytes
Bytes type is used for store binary data in any form. In binary form, bytes data is store in length
+ data
two part.
Length part denotes the num of bytes contained in the bytes field. It is composed by several size unit, each unit occupied 1 byte as below:
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| C | 7-bit Size |
+---+---+---+---+---+---+---+---+
C = Continue Flag
Continue Flag indicates if there is another size unit after this unit. If Continue Flag is 0, it is the last size unit.
7-bit spaces stores the length in little-endian.
Therefore, 1 size unit can represent 0-127 bytes data; 2 size units can represent 128-16383 bytes data; 3 size units can represent 16384-2,097,151 bytes data; 4 size units can represent 2,097,152-268,435,455 bytes data; ... (Please notice that some programming languages do not support array with more than Int32.Max elements)
Data part contains the raw binary data in continues form.
Data type is supposed to store long data, and zero-copy feature is provided in some programming language targets.
Memory Copy Option
-memcpy
: Enable memory copy for fields (Duplicate content of string
and bytes
fields when decoding, instead of directly referencing the original buffer)
For different language target, -memcpy
option functions as below:
-
C language
- With
-memcpy
: Usemalloc
to heap-allocate memory forstring
andbytes
fields, and copy the content from the original buffer. - Without
-memcpy
: Pointer reference to the original buffer forstring
andbytes
fields. Zero-copy and zero-heap-allocate.
- With
-
C# language
- With
-memcpy
: Usebyte[]
as the type forbytes
fields. Encode and decode methods will only be compatible withbyte[]
parameters. Old .NET Framework versions should use this option. - Without
-memcpy
: UseMemory<byte>
as the type forbytes
fields. Encode and decode methods will be compatible withbyte[]
,Memory<byte>
andSpan<byte>
(encode only) parameters.System.Memory
package is required for this case.
- With
-
CommonJS module
- Force enabled:
-memcpy
.
- Force enabled:
-
Java language
- Force enabled:
-memcpy
.
- Force enabled:
-
Python language
- Force enabled:
-memcpy
.
- Force enabled:
Enum Value as Constant!
You can now use enum value defined in previous enum type as constant value:
enum FrameType[1] {
FRAME_KEEPALIVE = 0x00,
FRAME_DATA = 0x01,
FRAME_CONTROL = 0x02,
};
struct DataFrame {
FrameType opcode = FRAME_DATA;
bytes data;
};
struct ControlFrame {
FrameType opcode = FRAME_CONTROL;
string msg;
};
In that case, you can define different frame with different header value, and try to decode them one by one.
frame = DataFrame()
if (frame.decode(buffer) > 0) handle_data_frame(frame)
frame = ControlFrame()
if (frame.decode(buffer) > 0) handle_control_frame(frame)
You can also use enum value defined in previous enum type in new enum definition:
enum FrameType[1] {
FRAME_KEEPALIVE = 0x00,
FRAME_DATA = 0x01,
FRAME_CONTROL = 0x02,
};
enum FrameTypeExt[1] {
FRAME_KEEPALIVE2 = FRAME_KEEPALIVE,
}
Breaking Change of API
Since variable-sized type is introduced, all decode method returning bool
are now returning an integer indicates the num of bytes decoded (-1 for failure), all encoding method returning void
are now returning an interger indicates the num of bytes encoded.
dynamic
field or method is added to indicate if a struct has dynamic size. (i.e. with string or bytes field in it)
encode_size()
method is added to calculate the num of bytes encoded without doing real encoding.
Generated field type change of C# language target without -memcpy
option. Refer to section #Memory Copy Option.
Changelog
v0.7.1
Ban different method (return / param) type of same method
From 0.7.1
on, getter and setter methods with the same name must return and accept the same type.
Because we are using property
feature in C# to generate code like this:
// CustomGetterSetter: TemperaturePercent
public double TemperaturePercent
{
get => ((this.temperature / 10) - 40);
set => this.temperature = (ushort)((value == 0) ? 0 : ((value + 40) * 10));
}
If we allow users define method like this, then we are not able to use property
any more.
struct RovSensorCabTempHumidPressData2 {
uint16 temperature[2] {
get temperature_percent(float64): value / 10 - 40;
set temperature_percent(int32): (uint16)(value == 0 ? 0 : (value + 40) * 10);
};
}
Bugfix
- Fix getter & setter format, remove redundant empty line for C# target.
- Fix wrong order in the error info while method name conflicting with field name.
Changelog
- f3ef12b Ban different method type of same method. Fix C# getter setter format. Fix error info