Skip to content

Commit

Permalink
Document tag_and_type() better.
Browse files Browse the repository at this point in the history
See #69.
  • Loading branch information
joto committed Jan 13, 2017
1 parent b49ebd1 commit 412476c
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 2 deletions.
6 changes: 6 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ macro `PROTOZERO_STRICT_API` in which case Protozero will compile without the
code used for backwards compatibilty. You will then get compile errors for
older API usages.

## Upgrading from *v1.4.5* to *v1.5.0*

* New functions for checking tag and type at the same time to make your
program more robust. Read the section "Repeated fields in messages" in
the new [Advanced Topics documentation](doc/advanced.md).

## Upgrading from *v1.4.4* to *v1.4.5*

* The macro `PROTOZERO_DO_NOT_USE_BARE_POINTER` is not used any more. If you
Expand Down
57 changes: 55 additions & 2 deletions doc/advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ If `protozero/version.hpp` is included, the following macros are set:
The behaviour of Protozero can be changed by defining the following macros.
They have to be set before including any of the Protozero headers.

## `PROTOZERO_STRICT_API`
### `PROTOZERO_STRICT_API`

If this is set, you will get some extra warnings or errors during compilation
if you are using an old (deprecated) interface to Protozero. Enable this if
you want to make sure your code will work with future versions of Protozero.

## `PROTOZERO_USE_VIEW`
### `PROTOZERO_USE_VIEW`

Protozero uses the class `protozero::data_view` as the return type of the
`pbf_reader::get_view()` method and a few other functions take a
Expand Down Expand Up @@ -71,6 +71,59 @@ not-packed) repeated fields with the same tag and their contents must be
concatenated. It is your responsibility to do this, Protozero doesn't do that
for you.

### Using `tag_and_type()`

The `tag_and_type()` free function and the method of the same name on the
`pbf_reader` and `pbf_message` classes can be used to access both packed and
unpacked repeated fields. (It can also be used to check that you have the
right type of encoding for other fields.)

Here is the outline:

```cpp
enum class ExampleMsg : protozero::pbf_tag_type {
repeated_uint32_x = 1
};

std::string data = ...
pbf_message<ExampleMsg> message{data};
while (message.next()) {
switch (message.tag_and_type()) {
case tag_and_type(ExampleMsg::repeated_uint32_x, pbf_wire_type::length_delimited): {
auto xit = message.get_packed_uint32();
... // handle the repeated field when it is packed
}
break;
case tag_and_type(ExampleMsg::repeated_uint32_x, pbf_wire_type::varint): {
auto x = message.get_uint32();
... // handle the repeated field when it is not packed
}
break;
default:
message.skip();
}
}
```
All this works on `pbf_reader` in the same way as with `pbf_message` with the
usual difference that `pbf_reader` takes a numeric field tag and `pbf_message`
an enum field.
If you only want to check for one specific tag and type you can use the
two-argument version of `pbf_reader::next()`. In this case `17` is the field
tag we are looking for:
```cpp
std::string data = ...
pbf_reader message{data};
while (message.next(17, pbf_wire_type::varint)) {
auto foo = message.get_int32();
...
}
```

See the test under `test/t/tag_and_type/` for a complete example.


## Reserving memory when writing messages

Expand Down

0 comments on commit 412476c

Please sign in to comment.