{"id":15048029,"url":"https://github.com/chokobole/protobuf_bytes","last_synced_at":"2025-10-08T23:04:42.585Z","repository":{"id":50658970,"uuid":"229657413","full_name":"chokobole/protobuf_bytes","owner":"chokobole","description":"Now don't worry about copy when using protobuf!","archived":false,"fork":false,"pushed_at":"2019-12-28T13:02:21.000Z","size":51,"stargazers_count":2,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-19T06:57:35.545Z","etag":null,"topics":["bazel-support","cpp","cpp-library","cpp14","cpp14-library","move","protobuf","protobuf-bytes"],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chokobole.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-12-23T01:50:57.000Z","updated_at":"2022-07-31T11:44:44.000Z","dependencies_parsed_at":"2022-09-10T00:40:21.822Z","dependency_job_id":null,"html_url":"https://github.com/chokobole/protobuf_bytes","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chokobole%2Fprotobuf_bytes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chokobole%2Fprotobuf_bytes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chokobole%2Fprotobuf_bytes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chokobole%2Fprotobuf_bytes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chokobole","download_url":"https://codeload.github.com/chokobole/protobuf_bytes/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254388040,"owners_count":22062972,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bazel-support","cpp","cpp-library","cpp14","cpp14-library","move","protobuf","protobuf-bytes"],"created_at":"2024-09-24T21:07:10.167Z","updated_at":"2025-10-08T23:04:37.558Z","avatar_url":"https://github.com/chokobole.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Protobuf Bytes\n\n`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\u003cT\u003e`?\". 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\u003cT\u003e` apis!\n\n## Contents\n- [Protobuf Bytes](#protobuf-bytes)\n  - [Contents](#contents)\n  - [How to use](#how-to-use)\n    - [bazel](#bazel)\n    - [nodeJS](#nodejs)\n    - [python](#python)\n  - [Examples](#examples)\n  - [Usages](#usages)\n    - [Type](#type)\n    - [View](#view)\n    - [Serialization / Deserialization](#serialization--deserialization)\n    - [Cast to pointer](#cast-to-pointer)\n    - [std::string methods](#stdstring-methods)\n\n## How to use\n\n### bazel\n\nTo use `protobuf_bytes`, add the followings to your `WORKSPACE` file.\n\n```python\nload(\"@bazel_tools//tools/build_defs/repo:http.bzl\", \"http_archive\")\n\nhttp_archive(\n    name = \"protobuf_bytes\",\n    sha256 = \"\u003csha256\u003e\",\n    strip_prefix = \"protobuf_bytes-\u003ccommit\u003e\",\n    urls = [\n        \"https://github.com/chokobole/protobuf_bytes/archive/\u003ccommit\u003e.tar.gz\",\n    ],\n)\n\nload(\"@protobuf_bytes//bazel:protobuf_bytes_deps.bzl\", \"protobuf_bytes_deps\")\n\nprotobuf_bytes_deps()\n\nload(\"@rules_proto//proto:repositories.bzl\", \"rules_proto_dependencies\", \"rules_proto_toolchains\")\nrules_proto_dependencies()\nrules_proto_toolchains()\n```\n\nImport the `bytes.proto` and use like below.\n\n```protobuf\nimport \"protobuf_bytes/bytes.proto\";\n\nmessage FooMessage {\n  protobuf_bytes.BytesMessage bytes = 1;\n}\n```\n\nThen, in your `BUILD` files, import and use the rules.\n\n```python\nload(\"@protobuf_bytes//bazel:protobuf_bytes_cc.bzl\", \"protobuf_bytes_copts\")\nload(\"@rules_proto//proto:defs.bzl\", \"proto_library\")\n\nproto_library(\n    name = \"[name]_proto\",\n    srcs = [\"[name].proto\"],\n    deps = [\"@protobuf_bytes//:bytes_proto\"],\n)\n\ncc_proto_library(\n    name = \"[name]_cc_proto\",\n    deps = [\":[name]_proto\"],\n)\n\ncc_library(\n    name = \"[name]\",\n    copts = protobuf_bytes_copts(),\n    deps = [\n      \":[name]_cc_proto\",\n      \"@protobuf_bytes\",\n    ]\n)\n```\n\n### nodeJS\n\nplease read [protobuf_bytes/js/README.md](protobuf_bytes/js/README.md).\n\n### python\n\nplease read [protobuf_bytes/py/README.md](protobuf_bytes/py/README.md).\n\n## Examples\n\nYou can find the full code [examples/pointcloud.cc](examples/pointcloud.cc)!\n\n```c++\n#include \u003ciostream\u003e\n\n#include \"protobuf_bytes/cc/bytes.h\"\n\nstruct Point {\n  int x;\n  int y;\n\n  Point(int x, int y) : x(x), y(y) {}\n};\n\nint main() {\n  protobuf_bytes::Bytes bytes;\n  bytes.set_type(BYTES_TYPE_8U_C3);\n  protobuf_bytes::Bytes::View\u003cPoint\u003e view = bytes.AsView\u003cPoint\u003e();\n  view.emplace_back(1, 2);\n  view.emplace_back(3, 4);\n  protobuf_bytes::BytesMessage message = bytes.ToBytesMessage(false);  // It's using move!\n  std::cout \u003c\u003c message.DebugString() \u003c\u003c std::endl;\n}\n```\n\n## Usages\n\n### Type\n\n`BytesMessages` has members `type` anad `data`.\n\n```protobuf\nmessage BytesMessage {\n  enum ElementType {\n    ELEMENT_TYPE_CUSTOM = 0;\n    ELEMENT_TYPE_8U = 1;\n    ELEMENT_TYPE_8S = 2;\n    ELEMENT_TYPE_16U = 3;\n    ELEMENT_TYPE_16S = 4;\n    ELEMENT_TYPE_32U = 5;\n    ELEMENT_TYPE_32S = 6;\n    ELEMENT_TYPE_64U = 7;\n    ELEMENT_TYPE_64S = 8;\n    ELEMENT_TYPE_32F = 9;\n    ELEMENT_TYPE_64F = 10;\n  };\n  enum ChannelType {\n    CHANNEL_TYPE_CUSTOM = 0;\n    CHANNEL_TYPE_C1 = 1;\n    CHANNEL_TYPE_C2 = 2;\n    CHANNEL_TYPE_C3 = 3;\n    CHANNEL_TYPE_C4 = 4;\n  };\n  uint32 type = 1;\n  bytes data = 2;\n}\n```\n\n`type` is the combination of `ElementType` and `ChannelType` like below.\n\n```c++\n// bytes_internal.h\nconstexpr uint32_t MakeBytesType(BytesMessage::ElementType element_type,\n                                 BytesMessage::ChannelType channel_type) {\n  return (static_cast\u003cuint32_t\u003e(element_type) \u003c\u003c 16) |\n         static_cast\u003cuint32_t\u003e(channel_type);\n}\n```\n\nThere are predefined `type`s.\n\n```c++\nBYTES_TYPE_8U_C1 // ELEMENT_TYPE_8U + CHANNEL_TYPE_C1\nBYTES_TYPE_8U_C2 // ELEMENT_TYPE_8U + CHANNEL_TYPE_C2\nBYTES_TYPE_8U_C3 // ELEMENT_TYPE_8U + CHANNEL_TYPE_C3\nBYTES_TYPE_8U_C4 // ELEMENT_TYPE_8U + CHANNEL_TYPE_C4\n...\nBYTES_TYPE_64F_C1 // ELEMENT_TYPE_64F + CHANNEL_TYPE_C1\nBYTES_TYPE_64F_C2 // ELEMENT_TYPE_64F + CHANNEL_TYPE_C2\nBYTES_TYPE_64F_C3 // ELEMENT_TYPE_64F + CHANNEL_TYPE_C3\nBYTES_TYPE_64F_C4 // ELEMENT_TYPE_64F + CHANNEL_TYPE_C4\n```\n\n### View\n\nIf you want to use mimicking `std::vector\u003cT\u003e`, you should call `Bytes::ConstView\u003cT\u003e Bytes::AsConstView\u003cT\u003e()` or `Bytes::View\u003cT\u003e Bytes::AsView\u003cT\u003e()`. One is readonly version and the other is writable version.\n\n```c++\nprotobuf_bytes::Bytes bytes;\nbytes.AsView\u003cPoint\u003e();  // can modify\nbytes.AsConstView\u003cPoint\u003e();  // can't modify\n```\n\n### Serialization / Deserialization\n\nTo serialize, you have to call `BytesMessage Bytes::ToBytesMessage(bool copy = true)` method.\n\n```c++\nprotobuf_bytes::Bytes bytes;\nbytes.ToBytesMessage();  // copy\nbytes.ToBytesMessage(false);  // move\n```\n\nTo deserialize, there are overloaded 2 methods `bool Bytes::FromBytesMessage(const BytesMessage\u0026 message)` and `bool Bytes::FromBytesMessage(BytesMessage\u0026\u0026 message)`. Currenlty it just returns `true`.\n\n```c++\nprotobuf_bytes::Bytes bytes;\nprotobuf_bytes::BytesMessage message;\nbytes.FromBytesMessage(message);  // copy\nbytes.FromBytesMessage(std::move(message));  // move\n```\n\n### Cast to pointer\n\nTo cast `T*` or `const T*`, you have to call template method `T cast()`.\n\n```c++\nprotobuf_bytes::Bytes bytes;\nPoint* ptr = bytes.cast\u003cPoint*\u003e();\nconst Point* cptr = bytes.cast\u003cconst Point*\u003e();\n```\n\n### std::string methods\n\nThere are opened `std::string` methods for the member `data` of `Bytes` class.\n\n```c++\nsize_t size() const noexcept;\n\nbool empty() const noexcept;\n\nvoid reserve(size_t n);\n\nvoid resize(size_t n);\n\nvoid shrink_to_fit();\n\nvoid clear();\n\nvoid swap(Bytes\u0026 other);\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchokobole%2Fprotobuf_bytes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchokobole%2Fprotobuf_bytes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchokobole%2Fprotobuf_bytes/lists"}