protobuf bytes is represented as a std::string in the c++ world. There is a dilemma "Should I give up move semantics and use std::vector<T>?". Now don't worry! This repository gives you a new c++ class correspondent to protobuf bytes, which is able to use move semantics and mimic std::vector<T> apis!
To use protobuf_bytes, add the followings to your WORKSPACE file.
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
    name = "protobuf_bytes",
    sha256 = "<sha256>",
    strip_prefix = "protobuf_bytes-<commit>",
    urls = [
        "https://github.com/chokobole/protobuf_bytes/archive/<commit>.tar.gz",
    ],
)
load("@protobuf_bytes//bazel:protobuf_bytes_deps.bzl", "protobuf_bytes_deps")
protobuf_bytes_deps()
load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains")
rules_proto_dependencies()
rules_proto_toolchains()Import the bytes.proto and use like below.
import "protobuf_bytes/bytes.proto";
message FooMessage {
  protobuf_bytes.BytesMessage bytes = 1;
}Then, in your BUILD files, import and use the rules.
load("@protobuf_bytes//bazel:protobuf_bytes_cc.bzl", "protobuf_bytes_copts")
load("@rules_proto//proto:defs.bzl", "proto_library")
proto_library(
    name = "[name]_proto",
    srcs = ["[name].proto"],
    deps = ["@protobuf_bytes//:bytes_proto"],
)
cc_proto_library(
    name = "[name]_cc_proto",
    deps = [":[name]_proto"],
)
cc_library(
    name = "[name]",
    copts = protobuf_bytes_copts(),
    deps = [
      ":[name]_cc_proto",
      "@protobuf_bytes",
    ]
)please read protobuf_bytes/js/README.md.
please read protobuf_bytes/py/README.md.
You can find the full code examples/pointcloud.cc!
#include <iostream>
#include "protobuf_bytes/cc/bytes.h"
struct Point {
  int x;
  int y;
  Point(int x, int y) : x(x), y(y) {}
};
int main() {
  protobuf_bytes::Bytes bytes;
  bytes.set_type(BYTES_TYPE_8U_C3);
  protobuf_bytes::Bytes::View<Point> view = bytes.AsView<Point>();
  view.emplace_back(1, 2);
  view.emplace_back(3, 4);
  protobuf_bytes::BytesMessage message = bytes.ToBytesMessage(false);  // It's using move!
  std::cout << message.DebugString() << std::endl;
}BytesMessages has members type anad data.
message BytesMessage {
  enum ElementType {
    ELEMENT_TYPE_CUSTOM = 0;
    ELEMENT_TYPE_8U = 1;
    ELEMENT_TYPE_8S = 2;
    ELEMENT_TYPE_16U = 3;
    ELEMENT_TYPE_16S = 4;
    ELEMENT_TYPE_32U = 5;
    ELEMENT_TYPE_32S = 6;
    ELEMENT_TYPE_64U = 7;
    ELEMENT_TYPE_64S = 8;
    ELEMENT_TYPE_32F = 9;
    ELEMENT_TYPE_64F = 10;
  };
  enum ChannelType {
    CHANNEL_TYPE_CUSTOM = 0;
    CHANNEL_TYPE_C1 = 1;
    CHANNEL_TYPE_C2 = 2;
    CHANNEL_TYPE_C3 = 3;
    CHANNEL_TYPE_C4 = 4;
  };
  uint32 type = 1;
  bytes data = 2;
}type is the combination of ElementType and ChannelType like below.
// bytes_internal.h
constexpr uint32_t MakeBytesType(BytesMessage::ElementType element_type,
                                 BytesMessage::ChannelType channel_type) {
  return (static_cast<uint32_t>(element_type) << 16) |
         static_cast<uint32_t>(channel_type);
}There are predefined types.
BYTES_TYPE_8U_C1 // ELEMENT_TYPE_8U + CHANNEL_TYPE_C1
BYTES_TYPE_8U_C2 // ELEMENT_TYPE_8U + CHANNEL_TYPE_C2
BYTES_TYPE_8U_C3 // ELEMENT_TYPE_8U + CHANNEL_TYPE_C3
BYTES_TYPE_8U_C4 // ELEMENT_TYPE_8U + CHANNEL_TYPE_C4
...
BYTES_TYPE_64F_C1 // ELEMENT_TYPE_64F + CHANNEL_TYPE_C1
BYTES_TYPE_64F_C2 // ELEMENT_TYPE_64F + CHANNEL_TYPE_C2
BYTES_TYPE_64F_C3 // ELEMENT_TYPE_64F + CHANNEL_TYPE_C3
BYTES_TYPE_64F_C4 // ELEMENT_TYPE_64F + CHANNEL_TYPE_C4If you want to use mimicking std::vector<T>, you should call Bytes::ConstView<T> Bytes::AsConstView<T>() or Bytes::View<T> Bytes::AsView<T>(). One is readonly version and the other is writable version.
protobuf_bytes::Bytes bytes;
bytes.AsView<Point>();  // can modify
bytes.AsConstView<Point>();  // can't modifyTo serialize, you have to call BytesMessage Bytes::ToBytesMessage(bool copy = true) method.
protobuf_bytes::Bytes bytes;
bytes.ToBytesMessage();  // copy
bytes.ToBytesMessage(false);  // moveTo deserialize, there are overloaded 2 methods bool Bytes::FromBytesMessage(const BytesMessage& message) and bool Bytes::FromBytesMessage(BytesMessage&& message). Currenlty it just returns true.
protobuf_bytes::Bytes bytes;
protobuf_bytes::BytesMessage message;
bytes.FromBytesMessage(message);  // copy
bytes.FromBytesMessage(std::move(message));  // moveTo cast T* or const T*, you have to call template method T cast().
protobuf_bytes::Bytes bytes;
Point* ptr = bytes.cast<Point*>();
const Point* cptr = bytes.cast<const Point*>();There are opened std::string methods for the member data of Bytes class.
size_t size() const noexcept;
bool empty() const noexcept;
void reserve(size_t n);
void resize(size_t n);
void shrink_to_fit();
void clear();
void swap(Bytes& other);