1 2 #ifndef UPBC_COMMON_H 3 #define UPBC_COMMON_H 4 5 #include <vector> 6 7 #include "absl/strings/substitute.h" 8 #include "google/protobuf/descriptor.h" 9 #include "google/protobuf/io/zero_copy_stream.h" 10 11 namespace upbc { 12 13 class Output { 14 public: Output(google::protobuf::io::ZeroCopyOutputStream * stream)15 Output(google::protobuf::io::ZeroCopyOutputStream* stream) 16 : stream_(stream) {} ~Output()17 ~Output() { stream_->BackUp((int)size_); } 18 19 template <class... Arg> operator()20 void operator()(absl::string_view format, const Arg&... arg) { 21 Write(absl::Substitute(format, arg...)); 22 } 23 24 private: Write(absl::string_view data)25 void Write(absl::string_view data) { 26 while (!data.empty()) { 27 RefreshOutput(); 28 size_t to_write = std::min(data.size(), size_); 29 memcpy(ptr_, data.data(), to_write); 30 data.remove_prefix(to_write); 31 ptr_ += to_write; 32 size_ -= to_write; 33 } 34 } 35 RefreshOutput()36 void RefreshOutput() { 37 while (size_ == 0) { 38 void *ptr; 39 int size; 40 if (!stream_->Next(&ptr, &size)) { 41 fprintf(stderr, "upbc: Failed to write to to output\n"); 42 abort(); 43 } 44 ptr_ = static_cast<char*>(ptr); 45 size_ = size; 46 } 47 } 48 49 google::protobuf::io::ZeroCopyOutputStream* stream_; 50 char *ptr_ = nullptr; 51 size_t size_ = 0; 52 }; 53 54 std::string StripExtension(absl::string_view fname); 55 std::string ToCIdent(absl::string_view str); 56 std::string ToPreproc(absl::string_view str); 57 void EmitFileWarning(const google::protobuf::FileDescriptor* file, 58 Output& output); 59 std::vector<const google::protobuf::Descriptor*> SortedMessages( 60 const google::protobuf::FileDescriptor* file); 61 std::string MessageInit(const google::protobuf::Descriptor* descriptor); 62 std::string MessageName(const google::protobuf::Descriptor* descriptor); 63 64 } // namespace upbc 65 66 # endif // UPBC_COMMON_H 67