13 #ifndef __STOUT_PROTOBUF_HPP__ 14 #define __STOUT_PROTOBUF_HPP__ 23 #include <sys/types.h> 26 #include <type_traits> 29 #include <google/protobuf/descriptor.h> 30 #include <google/protobuf/descriptor.pb.h> 31 #include <google/protobuf/message.h> 32 #include <google/protobuf/reflection.h> 33 #include <google/protobuf/repeated_field.h> 35 #include <google/protobuf/io/zero_copy_stream_impl.h> 74 if (!message.IsInitialized()) {
75 return Error(message.InitializationErrorString() +
76 " is required but not initialized");
80 uint32_t
size = message.ByteSize();
81 std::string bytes((
char*) &size,
sizeof(size));
85 return Error(
"Failed to write size: " + result.
error());
99 return Error(
"Failed to duplicate handle: " + dup.error());
102 int crt = dup->crt();
104 if (!message.SerializeToFileDescriptor(crt)) {
106 return Error(
"Failed to write/serialize message");
110 if (!message.SerializeToFileDescriptor(fd)) {
111 return Error(
"Failed to write/serialize message");
122 template <
typename T>
124 int_fd fd,
const google::protobuf::RepeatedPtrField<T>& messages)
126 foreach (
const T& message, messages) {
139 template <
typename T>
144 O_WRONLY | O_CREAT | O_TRUNC |
O_CLOEXEC,
148 return Error(
"Failed to open file '" + path +
"': " + fd.
error());
153 if (sync && write.isSome()) {
163 if (write.isSome() && close.isError()) {
165 "Failed to close '" +
stringify(fd.
get()) +
"':" + close.error());
175 const std::string&
path,
176 const google::protobuf::Message& message,
181 O_WRONLY | O_CREAT | O_APPEND |
O_CLOEXEC,
185 return Error(
"Failed to open file '" + path +
"': " + fd.
error());
190 if (sync && write.isSome()) {
199 if (write.isSome() && close.isError()) {
201 "Failed to close '" +
stringify(fd.
get()) +
"':" + close.error());
208 template <
typename T>
212 (void) static_cast<google::protobuf::Message*>(&t);
219 google::protobuf::io::ArrayInputStream stream(
221 static_cast<int>(value.size()));
222 if (!t.ParseFromZeroCopyStream(&stream)) {
223 return Error(
"Failed to deserialize " + t.GetDescriptor()->full_name());
229 template <
typename T>
232 (void) static_cast<const google::protobuf::Message*>(&t);
235 if (!t.SerializeToString(&value)) {
236 return Error(
"Failed to serialize " + t.GetDescriptor()->full_name());
248 template <
typename T>
262 offset = lseek.
get();
272 return Error(
"Failed to read size: " + result.
error());
273 }
else if (result.
isNone()) {
275 }
else if (result->size() <
sizeof(
size)) {
285 "Failed to read size: hit EOF unexpectedly, possible corruption");
289 memcpy((
void*)&size, (
void*)result->data(),
sizeof(
size));
301 return Error(
"Failed to read message: " + result.
error());
302 }
else if (result.
isNone() || result->size() <
size) {
311 return Error(
"Failed to read message of size " +
stringify(size) +
312 " bytes: hit EOF unexpectedly, possible corruption");
318 const std::string& data = result.
get();
326 google::protobuf::io::ArrayInputStream stream(
328 static_cast<int>(data.size()));
330 if (!message.ParseFromZeroCopyStream(&stream)) {
335 return Error(
"Failed to deserialize message");
348 template <
typename T>
352 int_fd fd,
bool ignorePartial,
bool undoFailed)
354 google::protobuf::RepeatedPtrField<T> result;
359 }
else if (message.
isNone()) {
362 result.Add()->CopyFrom(message.
get());
382 template <
typename T>
391 template <
typename T>
400 return Error(
"Failed to open file '" + path +
"': " + fd.
error());
418 google::protobuf::Message* message,
422 struct Parser : boost::static_visitor<Try<Nothing>>
424 Parser(google::protobuf::Message* _message,
425 const google::protobuf::FieldDescriptor* _field)
427 reflection(message->GetReflection()),
432 switch (field->type()) {
433 case google::protobuf::FieldDescriptor::TYPE_MESSAGE:
434 if (field->is_map()) {
436 const std::string&
name,
439 google::protobuf::Message* entry =
440 reflection->AddMessage(message, field);
453 const google::protobuf::FieldDescriptor* key_field =
454 entry->GetDescriptor()->FindFieldByNumber(1);
459 boost::apply_visitor(
Parser(entry, key_field), key);
465 const google::protobuf::FieldDescriptor* value_field =
466 entry->GetDescriptor()->FindFieldByNumber(2);
468 apply = boost::apply_visitor(
Parser(entry, value_field), value);
473 }
else if (field->is_repeated()) {
479 return parse(reflection->AddMessage(message, field), object);
481 return parse(reflection->MutableMessage(message, field), object);
485 return Error(
"Not expecting a JSON object for field '" +
486 field->name() +
"'");
493 switch (field->type()) {
494 case google::protobuf::FieldDescriptor::TYPE_STRING:
495 if (field->is_repeated()) {
496 reflection->AddString(message, field,
string.value);
498 reflection->SetString(message, field,
string.value);
501 case google::protobuf::FieldDescriptor::TYPE_BYTES: {
504 return Error(
"Failed to base64 decode bytes field" 505 " '" + field->name() +
"': " + decode.
error());
508 if (field->is_repeated()) {
509 reflection->AddString(message, field, decode.
get());
511 reflection->SetString(message, field, decode.
get());
515 case google::protobuf::FieldDescriptor::TYPE_ENUM: {
516 const google::protobuf::EnumValueDescriptor* descriptor =
517 field->enum_type()->FindValueByName(
string.value);
519 if (descriptor ==
nullptr) {
520 if (field->is_required()) {
521 return Error(
"Failed to find enum for '" +
string.value +
"'");
535 if (field->is_repeated()) {
536 reflection->AddEnum(message, field, descriptor);
538 reflection->SetEnum(message, field, descriptor);
542 case google::protobuf::FieldDescriptor::TYPE_DOUBLE:
543 case google::protobuf::FieldDescriptor::TYPE_FLOAT: {
544 if (
string.value ==
"Infinity") {
546 std::numeric_limits<double>::infinity()));
547 }
else if (
string.value ==
"-Infinity") {
549 -std::numeric_limits<double>::infinity()));
554 "Failed to parse '" +
string.value +
"' as a JSON number " 555 "for field '" + field->name() +
"': " + number.
error());
561 case google::protobuf::FieldDescriptor::TYPE_INT64:
562 case google::protobuf::FieldDescriptor::TYPE_SINT64:
563 case google::protobuf::FieldDescriptor::TYPE_SFIXED64:
564 case google::protobuf::FieldDescriptor::TYPE_UINT64:
565 case google::protobuf::FieldDescriptor::TYPE_FIXED64:
566 case google::protobuf::FieldDescriptor::TYPE_INT32:
567 case google::protobuf::FieldDescriptor::TYPE_SINT32:
568 case google::protobuf::FieldDescriptor::TYPE_SFIXED32:
569 case google::protobuf::FieldDescriptor::TYPE_UINT32:
570 case google::protobuf::FieldDescriptor::TYPE_FIXED32: {
574 "Failed to parse '" +
string.value +
"' as a JSON number " 575 "for field '" + field->name() +
"': " + number.
error());
580 case google::protobuf::FieldDescriptor::TYPE_BOOL: {
582 if (
boolean.isError()) {
584 "Failed to parse '" +
string.value +
"' as a JSON boolean " 585 "for field '" + field->name() +
"': " +
boolean.error());
591 return Error(
"Not expecting a JSON string for field '" +
592 field->name() +
"'");
599 switch (field->type()) {
600 case google::protobuf::FieldDescriptor::TYPE_DOUBLE:
601 if (field->is_repeated()) {
602 reflection->AddDouble(message, field, number.
as<
double>());
604 reflection->SetDouble(message, field, number.
as<
double>());
607 case google::protobuf::FieldDescriptor::TYPE_FLOAT:
608 if (field->is_repeated()) {
609 reflection->AddFloat(message, field, number.
as<
float>());
611 reflection->SetFloat(message, field, number.
as<
float>());
614 case google::protobuf::FieldDescriptor::TYPE_INT64:
615 case google::protobuf::FieldDescriptor::TYPE_SINT64:
616 case google::protobuf::FieldDescriptor::TYPE_SFIXED64:
617 if (field->is_repeated()) {
618 reflection->AddInt64(message, field, number.
as<int64_t>());
620 reflection->SetInt64(message, field, number.
as<int64_t>());
623 case google::protobuf::FieldDescriptor::TYPE_UINT64:
624 case google::protobuf::FieldDescriptor::TYPE_FIXED64:
625 if (field->is_repeated()) {
626 reflection->AddUInt64(message, field, number.
as<uint64_t>());
628 reflection->SetUInt64(message, field, number.
as<uint64_t>());
631 case google::protobuf::FieldDescriptor::TYPE_INT32:
632 case google::protobuf::FieldDescriptor::TYPE_SINT32:
633 case google::protobuf::FieldDescriptor::TYPE_SFIXED32:
634 if (field->is_repeated()) {
635 reflection->AddInt32(message, field, number.
as<int32_t>());
637 reflection->SetInt32(message, field, number.
as<int32_t>());
640 case google::protobuf::FieldDescriptor::TYPE_UINT32:
641 case google::protobuf::FieldDescriptor::TYPE_FIXED32:
642 if (field->is_repeated()) {
643 reflection->AddUInt32(message, field, number.
as<uint32_t>());
645 reflection->SetUInt32(message, field, number.
as<uint32_t>());
649 return Error(
"Not expecting a JSON number for field '" +
650 field->name() +
"'");
657 if (!field->is_repeated()) {
658 return Error(
"Not expecting a JSON array for field '" +
659 field->name() +
"'");
664 boost::apply_visitor(
Parser(message, field), value);
676 switch (field->type()) {
677 case google::protobuf::FieldDescriptor::TYPE_BOOL:
678 if (field->is_repeated()) {
679 reflection->AddBool(message, field,
boolean.value);
681 reflection->SetBool(message, field,
boolean.value);
685 return Error(
"Not expecting a JSON boolean for field '" +
686 field->name() +
"'");
700 google::protobuf::Message* message;
701 const google::protobuf::Reflection* reflection;
702 const google::protobuf::FieldDescriptor* field;
707 google::protobuf::Message* message,
713 const google::protobuf::FieldDescriptor* field =
714 message->GetDescriptor()->FindFieldByName(name);
716 if (field !=
nullptr) {
718 boost::apply_visitor(
Parser(message, field), value);
733 template <
typename T>
738 static_assert(std::is_convertible<T*, google::protobuf::Message*>::value,
739 "T must be a protobuf message");
741 const JSON::Object*
object = boost::get<JSON::Object>(&value);
742 if (
object ==
nullptr) {
743 return Error(
"Expecting a JSON object");
753 if (!message.IsInitialized()) {
754 return Error(
"Missing required fields: " +
755 message.InitializationErrorString());
768 template <
typename T>
774 static_assert(std::is_convertible<T*, google::protobuf::Message*>::value,
775 "T must be a protobuf message");
777 const JSON::Array* array = boost::get<JSON::Array>(&value);
778 if (array ==
nullptr) {
779 return Error(
"Expecting a JSON array");
782 google::protobuf::RepeatedPtrField<T> collection;
783 collection.Reserve(static_cast<int>(array->
values.size()));
792 collection.Add()->CopyFrom(message.
get());
809 template <
typename T>
835 using google::protobuf::FieldDescriptor;
837 const google::protobuf::Message& message =
protobuf;
839 const google::protobuf::Descriptor* descriptor = message.GetDescriptor();
840 const google::protobuf::Reflection* reflection = message.GetReflection();
846 int fieldCount = descriptor->field_count();
847 std::vector<const FieldDescriptor*> fields;
848 fields.reserve(fieldCount);
849 for (
int i = 0; i < fieldCount; ++i) {
850 const FieldDescriptor* field = descriptor->field(i);
851 if (field->is_repeated()) {
852 if (reflection->FieldSize(message, field) > 0) {
854 fields.push_back(field);
857 reflection->HasField(message, field) ||
858 (field->has_default_value() && !field->options().deprecated())) {
860 fields.push_back(field);
864 foreach (
const FieldDescriptor* field, fields) {
865 if (field->is_repeated() && !field->is_map()) {
869 int fieldSize = reflection->FieldSize(message, field);
870 for (
int i = 0; i < fieldSize; ++i) {
871 switch (field->cpp_type()) {
872 case FieldDescriptor::CPPTYPE_BOOL:
874 reflection->GetRepeatedBool(message, field, i));
876 case FieldDescriptor::CPPTYPE_INT32:
878 reflection->GetRepeatedInt32(message, field, i));
880 case FieldDescriptor::CPPTYPE_INT64:
882 reflection->GetRepeatedInt64(message, field, i));
884 case FieldDescriptor::CPPTYPE_UINT32:
886 reflection->GetRepeatedUInt32(message, field, i));
888 case FieldDescriptor::CPPTYPE_UINT64:
890 reflection->GetRepeatedUInt64(message, field, i));
892 case FieldDescriptor::CPPTYPE_FLOAT:
894 reflection->GetRepeatedFloat(message, field, i));
896 case FieldDescriptor::CPPTYPE_DOUBLE:
898 reflection->GetRepeatedDouble(message, field, i));
900 case FieldDescriptor::CPPTYPE_MESSAGE:
902 reflection->GetRepeatedMessage(message, field, i)));
904 case FieldDescriptor::CPPTYPE_ENUM:
906 reflection->GetRepeatedEnum(message, field, i)->name());
908 case FieldDescriptor::CPPTYPE_STRING:
909 const std::string& s = reflection->GetRepeatedStringReference(
910 message, field, i,
nullptr);
911 if (field->type() == FieldDescriptor::TYPE_BYTES) {
921 auto writeField = [&writer](
922 const std::string& fieldName,
923 const google::protobuf::Reflection* reflection,
924 const google::protobuf::Message& message,
925 const FieldDescriptor* field) {
926 switch (field->cpp_type()) {
927 case FieldDescriptor::CPPTYPE_BOOL:
928 writer->
field(fieldName, reflection->GetBool(message, field));
930 case FieldDescriptor::CPPTYPE_INT32:
931 writer->
field(fieldName, reflection->GetInt32(message, field));
933 case FieldDescriptor::CPPTYPE_INT64:
934 writer->
field(fieldName, reflection->GetInt64(message, field));
936 case FieldDescriptor::CPPTYPE_UINT32:
937 writer->
field(fieldName, reflection->GetUInt32(message, field));
939 case FieldDescriptor::CPPTYPE_UINT64:
940 writer->
field(fieldName, reflection->GetUInt64(message, field));
942 case FieldDescriptor::CPPTYPE_FLOAT:
943 writer->
field(fieldName, reflection->GetFloat(message, field));
945 case FieldDescriptor::CPPTYPE_DOUBLE:
946 writer->
field(fieldName, reflection->GetDouble(message, field));
948 case FieldDescriptor::CPPTYPE_MESSAGE:
950 fieldName,
Protobuf(reflection->GetMessage(message, field)));
952 case FieldDescriptor::CPPTYPE_ENUM:
954 fieldName, reflection->GetEnum(message, field)->name());
956 case FieldDescriptor::CPPTYPE_STRING:
957 const std::string& s =
958 reflection->GetStringReference(message, field,
nullptr);
959 if (field->type() == FieldDescriptor::TYPE_BYTES) {
962 writer->
field(fieldName, s);
968 if (!field->is_repeated()) {
969 writeField(field->name(), reflection, message, field);
971 CHECK(field->is_map());
974 [&field, &reflection, &message, &writeField](
977 const auto& mapEntry,
978 reflection->GetRepeatedFieldRef<google::protobuf::Message>(
980 const google::protobuf::Descriptor* mapEntryDescriptor =
981 mapEntry.GetDescriptor();
982 const google::protobuf::Reflection* mapEntryReflection =
983 mapEntry.GetReflection();
986 CHECK_EQ(mapEntryDescriptor->field_count(), 2);
988 const FieldDescriptor* keyField = mapEntryDescriptor->field(0);
989 const FieldDescriptor* valueField =
990 mapEntryDescriptor->field(1);
992 switch (keyField->cpp_type()) {
993 case FieldDescriptor::CPPTYPE_BOOL:
996 mapEntryReflection->GetBool(mapEntry, keyField)),
1001 case FieldDescriptor::CPPTYPE_INT32:
1004 mapEntryReflection->GetInt32(mapEntry, keyField)),
1009 case FieldDescriptor::CPPTYPE_INT64:
1012 mapEntryReflection->GetInt64(mapEntry, keyField)),
1017 case FieldDescriptor::CPPTYPE_UINT32:
1020 mapEntryReflection->GetUInt32(mapEntry, keyField)),
1025 case FieldDescriptor::CPPTYPE_UINT64:
1028 mapEntryReflection->GetUInt64(mapEntry, keyField)),
1033 case FieldDescriptor::CPPTYPE_STRING:
1034 if (keyField->type() == FieldDescriptor::TYPE_BYTES) {
1036 <<
"Unexpected key field type in protobuf Map: " 1037 << keyField->type_name();
1041 mapEntryReflection->GetStringReference(
1042 mapEntry, keyField,
nullptr),
1047 case FieldDescriptor::CPPTYPE_FLOAT:
1048 case FieldDescriptor::CPPTYPE_DOUBLE:
1049 case FieldDescriptor::CPPTYPE_MESSAGE:
1050 case FieldDescriptor::CPPTYPE_ENUM:
1051 LOG(FATAL) <<
"Unexpected key field type in protobuf Map: " 1052 << keyField->cpp_type_name();
1068 const google::protobuf::Descriptor* descriptor = message.GetDescriptor();
1069 const google::protobuf::Reflection* reflection = message.GetReflection();
1071 auto value_for_field = [](
1072 const google::protobuf::Message& message,
1073 const google::protobuf::FieldDescriptor* field) ->
JSON::Value {
1074 const google::protobuf::Reflection* reflection = message.GetReflection();
1076 switch (field->type()) {
1077 case google::protobuf::FieldDescriptor::TYPE_DOUBLE:
1078 return JSON::Number(reflection->GetDouble(message, field));
1079 case google::protobuf::FieldDescriptor::TYPE_FLOAT:
1080 return JSON::Number(reflection->GetFloat(message, field));
1081 case google::protobuf::FieldDescriptor::TYPE_INT64:
1082 case google::protobuf::FieldDescriptor::TYPE_SINT64:
1083 case google::protobuf::FieldDescriptor::TYPE_SFIXED64:
1084 return JSON::Number(reflection->GetInt64(message, field));
1085 case google::protobuf::FieldDescriptor::TYPE_UINT64:
1086 case google::protobuf::FieldDescriptor::TYPE_FIXED64:
1087 return JSON::Number(reflection->GetUInt64(message, field));
1088 case google::protobuf::FieldDescriptor::TYPE_INT32:
1089 case google::protobuf::FieldDescriptor::TYPE_SINT32:
1090 case google::protobuf::FieldDescriptor::TYPE_SFIXED32:
1091 return JSON::Number(reflection->GetInt32(message, field));
1092 case google::protobuf::FieldDescriptor::TYPE_UINT32:
1093 case google::protobuf::FieldDescriptor::TYPE_FIXED32:
1094 return JSON::Number(reflection->GetUInt32(message, field));
1095 case google::protobuf::FieldDescriptor::TYPE_BOOL:
1096 if (reflection->GetBool(message, field)) {
1102 case google::protobuf::FieldDescriptor::TYPE_STRING:
1103 return JSON::String(reflection->GetString(message, field));
1104 case google::protobuf::FieldDescriptor::TYPE_BYTES:
1107 case google::protobuf::FieldDescriptor::TYPE_MESSAGE:
1108 return protobuf(reflection->GetMessage(message, field));
1109 case google::protobuf::FieldDescriptor::TYPE_ENUM:
1110 return JSON::String(reflection->GetEnum(message, field)->name());
1111 case google::protobuf::FieldDescriptor::TYPE_GROUP:
1114 ABORT(
"Unhandled protobuf field type: " +
1125 std::vector<const google::protobuf::FieldDescriptor*> fields;
1126 fields.reserve(descriptor->field_count());
1127 for (
int i = 0; i < descriptor->field_count(); i++) {
1128 const google::protobuf::FieldDescriptor* field = descriptor->field(i);
1129 if (field->is_repeated()) {
1130 if (reflection->FieldSize(message, descriptor->field(i)) > 0) {
1132 fields.push_back(field);
1135 reflection->HasField(message, field) ||
1136 (field->has_default_value() && !field->options().deprecated())) {
1138 fields.push_back(field);
1142 foreach (
const google::protobuf::FieldDescriptor* field, fields) {
1143 if (field->is_map()) {
1146 int fieldSize = reflection->FieldSize(message, field);
1147 for (
int i = 0; i < fieldSize; ++i) {
1148 const google::protobuf::Message& entry =
1149 reflection->GetRepeatedMessage(message, field, i);
1162 const google::protobuf::FieldDescriptor* key_field =
1163 entry.GetDescriptor()->FindFieldByNumber(1);
1165 const google::protobuf::FieldDescriptor* value_field =
1166 entry.GetDescriptor()->FindFieldByNumber(2);
1168 JSON::Value key = value_for_field(entry, key_field);
1177 map.
values[
name] = value_for_field(entry, value_field);
1179 object.values[field->name()] =
map;
1180 }
else if (field->is_repeated()) {
1182 int fieldSize = reflection->FieldSize(message, field);
1183 array.
values.reserve(fieldSize);
1184 for (
int i = 0; i < fieldSize; ++i) {
1185 switch (field->type()) {
1186 case google::protobuf::FieldDescriptor::TYPE_DOUBLE:
1188 reflection->GetRepeatedDouble(message, field, i)));
1190 case google::protobuf::FieldDescriptor::TYPE_FLOAT:
1192 reflection->GetRepeatedFloat(message, field, i)));
1194 case google::protobuf::FieldDescriptor::TYPE_INT64:
1195 case google::protobuf::FieldDescriptor::TYPE_SINT64:
1196 case google::protobuf::FieldDescriptor::TYPE_SFIXED64:
1198 reflection->GetRepeatedInt64(message, field, i)));
1200 case google::protobuf::FieldDescriptor::TYPE_UINT64:
1201 case google::protobuf::FieldDescriptor::TYPE_FIXED64:
1203 reflection->GetRepeatedUInt64(message, field, i)));
1205 case google::protobuf::FieldDescriptor::TYPE_INT32:
1206 case google::protobuf::FieldDescriptor::TYPE_SINT32:
1207 case google::protobuf::FieldDescriptor::TYPE_SFIXED32:
1209 reflection->GetRepeatedInt32(message, field, i)));
1211 case google::protobuf::FieldDescriptor::TYPE_UINT32:
1212 case google::protobuf::FieldDescriptor::TYPE_FIXED32:
1214 reflection->GetRepeatedUInt32(message, field, i)));
1216 case google::protobuf::FieldDescriptor::TYPE_BOOL:
1217 if (reflection->GetRepeatedBool(message, field, i)) {
1223 case google::protobuf::FieldDescriptor::TYPE_STRING:
1225 reflection->GetRepeatedString(message, field, i)));
1227 case google::protobuf::FieldDescriptor::TYPE_BYTES:
1229 reflection->GetRepeatedString(message, field, i))));
1231 case google::protobuf::FieldDescriptor::TYPE_MESSAGE:
1233 reflection->GetRepeatedMessage(message, field, i)));
1235 case google::protobuf::FieldDescriptor::TYPE_ENUM:
1237 reflection->GetRepeatedEnum(message, field, i)->name()));
1239 case google::protobuf::FieldDescriptor::TYPE_GROUP:
1242 ABORT(
"Unhandled protobuf field type: " +
1246 object.values[field->name()] = array;
1248 object.
values[field->name()] = value_for_field(message, field);
1256 template <
typename T>
1259 static_assert(std::is_convertible<T*, google::protobuf::Message*>::value,
1260 "T must be a protobuf message");
1263 array.
values.reserve(repeated.size());
1264 foreach (
const T& elem, repeated) {
1273 #endif // __STOUT_PROTOBUF_HPP__ T as() const
Definition: json.hpp:120
Try< std::string > decode(const std::string &s)
Decode a string that is Base64-encoded with the standard Base64 alphabet.
Definition: base64.hpp:183
Try< Nothing > operator()(const JSON::Object &object) const
Definition: protobuf.hpp:430
bool isNone() const
Definition: result.hpp:113
Definition: nothing.hpp:16
Definition: errorbase.hpp:36
#define ABORT(...)
Definition: abort.hpp:40
Try< Bytes > size(const std::string &path, const FollowSymlink follow=FollowSymlink::FOLLOW_SYMLINK)
Definition: stat.hpp:130
const mode_t S_IRGRP
Definition: windows.hpp:313
T & get()&
Definition: try.hpp:80
ssize_t write(const int_fd &fd, const void *data, size_t size)
Definition: write.hpp:72
Result< Classifier > decode(const Netlink< struct rtnl_cls > &cls)
Try< Nothing > operator()(const JSON::Number &number) const
Definition: protobuf.hpp:597
Definition: protobuf.hpp:734
static Result< T > error(const std::string &message)
Definition: result.hpp:54
Try< google::protobuf::RepeatedPtrField< T > > operator()(const JSON::Value &value)
Definition: protobuf.hpp:771
const mode_t S_IWUSR
Definition: windows.hpp:306
Result< google::protobuf::RepeatedPtrField< T > > operator()(int_fd fd, bool ignorePartial, bool undoFailed)
Definition: protobuf.hpp:351
Try< T > operator()(const JSON::Value &value)
Definition: protobuf.hpp:736
Try< int_fd > open(const std::string &path, int oflag, mode_t mode=0)
Definition: open.hpp:35
Definition: protobuf.hpp:422
std::string encode(const std::string &s)
Encode a string to Base64 with the standard Base64 alphabet.
Definition: base64.hpp:170
Try< Nothing > operator()(const JSON::String &string) const
Definition: protobuf.hpp:491
Try< Nothing > write(const std::string &path, const T &t, bool sync=false)
Definition: protobuf.hpp:140
const mode_t S_IRUSR
Definition: windows.hpp:305
Try< std::string > serialize(const T &t)
Definition: protobuf.hpp:230
std::map< std::string, Value > values
Definition: json.hpp:194
bool is() const
Definition: json.hpp:338
Try< Nothing > write(int_fd fd, const google::protobuf::Message &message)
Definition: protobuf.hpp:72
constexpr int O_CLOEXEC
Definition: open.hpp:41
Try< Nothing > operator()(const JSON::Array &array) const
Definition: protobuf.hpp:655
void field(const std::string &key, const T &value)
Definition: jsonify.hpp:347
Definition: protobuf.hpp:249
Try< Nothing > close(int fd)
Definition: close.hpp:24
Try< Nothing > append(const std::string &path, const google::protobuf::Message &message, bool sync=false)
Definition: protobuf.hpp:174
Try< off_t > lseek(int_fd fd, off_t offset, int whence)
Definition: lseek.hpp:25
Option< T > max(const Option< T > &left, const Option< T > &right)
Definition: option.hpp:214
Try< Nothing > operator()(const JSON::Boolean &boolean) const
Definition: protobuf.hpp:674
const T & as() const &
Definition: json.hpp:353
Definition: jsonify.hpp:326
Try< T > deserialize(const std::string &value)
Definition: protobuf.hpp:209
void json(ObjectWriter *writer, const Protobuf &protobuf)
Definition: protobuf.hpp:833
#define foreachpair(KEY, VALUE, ELEMS)
Definition: foreach.hpp:51
std::vector< Value > values
Definition: json.hpp:203
Result< T > read(int_fd fd, bool ignorePartial=false, bool undoFailed=false)
Definition: protobuf.hpp:383
Definition: protobuf.hpp:61
Result< T > operator()(int_fd fd, bool ignorePartial, bool undoFailed)
Definition: protobuf.hpp:251
static Try error(const E &e)
Definition: try.hpp:43
JSON::Proxy jsonify(const T &)
Definition: jsonify.hpp:702
#define UNREACHABLE()
Definition: unreachable.hpp:22
Try< Nothing > fsync(int fd)
Definition: fsync.hpp:29
Result< std::string > read(int_fd fd, size_t size)
Definition: read.hpp:55
Parser(google::protobuf::Message *_message, const google::protobuf::FieldDescriptor *_field)
Definition: protobuf.hpp:424
Try< Nothing > operator()(const JSON::Null &) const
Definition: protobuf.hpp:691
Iterable< V > map(F &&f, const Iterable< U, Us... > &input)
Definition: lambda.hpp:46
Definition: protobuf.hpp:821
Try< Nothing > parse(google::protobuf::Message *message, const JSON::Object &object)
Definition: protobuf.hpp:706
Definition: attributes.hpp:24
bool isError() const
Definition: try.hpp:78
T & get()&
Definition: result.hpp:116
Object protobuf(const google::protobuf::Message &message)
Definition: protobuf.hpp:1064
bool isError() const
Definition: result.hpp:114
Type utilities for the protobuf library that are not specific to particular protobuf classes...
Definition: type_utils.hpp:552
int int_fd
Definition: int_fd.hpp:35
std::string stringify(int flags)
Array protobuf(const google::protobuf::RepeatedPtrField< T > &repeated)
Definition: protobuf.hpp:1257
const mode_t S_IROTH
Definition: windows.hpp:321
constexpr const char * name
Definition: shell.hpp:41
Definition: representation.hpp:72
Definition: jsonify.hpp:296
Try< int > dup(int fd)
Definition: dup.hpp:23