diff options
Diffstat (limited to 'src/google/protobuf/io/printer.cc')
-rw-r--r-- | src/google/protobuf/io/printer.cc | 76 |
1 files changed, 52 insertions, 24 deletions
diff --git a/src/google/protobuf/io/printer.cc b/src/google/protobuf/io/printer.cc index 7532b098..de67cef1 100644 --- a/src/google/protobuf/io/printer.cc +++ b/src/google/protobuf/io/printer.cc @@ -70,8 +70,8 @@ Printer::~Printer() { } bool Printer::GetSubstitutionRange(const char* varname, - pair<size_t, size_t>* range) { - map<string, pair<size_t, size_t> >::const_iterator iter = + std::pair<size_t, size_t>* range) { + std::map<string, std::pair<size_t, size_t> >::const_iterator iter = substitutions_.find(varname); if (iter == substitutions_.end()) { GOOGLE_LOG(DFATAL) << " Undefined variable in annotation: " << varname; @@ -87,12 +87,12 @@ bool Printer::GetSubstitutionRange(const char* varname, } void Printer::Annotate(const char* begin_varname, const char* end_varname, - const string& file_path, const vector<int>& path) { + const string& file_path, const std::vector<int>& path) { if (annotation_collector_ == NULL) { // Can't generate signatures with this Printer. return; } - pair<size_t, size_t> begin, end; + std::pair<size_t, size_t> begin, end; if (!GetSubstitutionRange(begin_varname, &begin) || !GetSubstitutionRange(end_varname, &end)) { return; @@ -106,10 +106,12 @@ void Printer::Annotate(const char* begin_varname, const char* end_varname, } } -void Printer::Print(const map<string, string>& variables, const char* text) { +void Printer::Print(const std::map<string, string>& variables, + const char* text) { int size = strlen(text); int pos = 0; // The number of bytes we've written so far. substitutions_.clear(); + line_start_variables_.clear(); for (int i = 0; i < size; i++) { if (text[i] == '\n') { @@ -121,6 +123,7 @@ void Printer::Print(const map<string, string>& variables, const char* text) { // Setting this true will cause the next WriteRaw() to insert an indent // first. at_start_of_line_ = true; + line_start_variables_.clear(); } else if (text[i] == variable_delimiter_) { // Saw the start of a variable name. @@ -143,15 +146,19 @@ void Printer::Print(const map<string, string>& variables, const char* text) { WriteRaw(&variable_delimiter_, 1); } else { // Replace with the variable's value. - map<string, string>::const_iterator iter = variables.find(varname); + std::map<string, string>::const_iterator iter = variables.find(varname); if (iter == variables.end()) { GOOGLE_LOG(DFATAL) << " Undefined variable: " << varname; } else { - size_t begin = offset_; + if (at_start_of_line_ && iter->second.empty()) { + line_start_variables_.push_back(varname); + } WriteRaw(iter->second.data(), iter->second.size()); - pair<map<string, pair<size_t, size_t> >::iterator, bool> inserted = - substitutions_.insert( - std::make_pair(varname, std::make_pair(begin, offset_))); + std::pair<std::map<string, std::pair<size_t, size_t> >::iterator, + bool> + inserted = substitutions_.insert(std::make_pair( + varname, + std::make_pair(offset_ - iter->second.size(), offset_))); if (!inserted.second) { // This variable was used multiple times. Make its span have // negative length so we can detect it if it gets used in an @@ -172,13 +179,13 @@ void Printer::Print(const map<string, string>& variables, const char* text) { } void Printer::Print(const char* text) { - static map<string, string> empty; + static std::map<string, string> empty; Print(empty, text); } void Printer::Print(const char* text, const char* variable, const string& value) { - map<string, string> vars; + std::map<string, string> vars; vars[variable] = value; Print(vars, text); } @@ -186,7 +193,7 @@ void Printer::Print(const char* text, void Printer::Print(const char* text, const char* variable1, const string& value1, const char* variable2, const string& value2) { - map<string, string> vars; + std::map<string, string> vars; vars[variable1] = value1; vars[variable2] = value2; Print(vars, text); @@ -196,7 +203,7 @@ void Printer::Print(const char* text, const char* variable1, const string& value1, const char* variable2, const string& value2, const char* variable3, const string& value3) { - map<string, string> vars; + std::map<string, string> vars; vars[variable1] = value1; vars[variable2] = value2; vars[variable3] = value3; @@ -208,7 +215,7 @@ void Printer::Print(const char* text, const char* variable2, const string& value2, const char* variable3, const string& value3, const char* variable4, const string& value4) { - map<string, string> vars; + std::map<string, string> vars; vars[variable1] = value1; vars[variable2] = value2; vars[variable3] = value3; @@ -222,7 +229,7 @@ void Printer::Print(const char* text, const char* variable3, const string& value3, const char* variable4, const string& value4, const char* variable5, const string& value5) { - map<string, string> vars; + std::map<string, string> vars; vars[variable1] = value1; vars[variable2] = value2; vars[variable3] = value3; @@ -238,7 +245,7 @@ void Printer::Print(const char* text, const char* variable4, const string& value4, const char* variable5, const string& value5, const char* variable6, const string& value6) { - map<string, string> vars; + std::map<string, string> vars; vars[variable1] = value1; vars[variable2] = value2; vars[variable3] = value3; @@ -256,7 +263,7 @@ void Printer::Print(const char* text, const char* variable5, const string& value5, const char* variable6, const string& value6, const char* variable7, const string& value7) { - map<string, string> vars; + std::map<string, string> vars; vars[variable1] = value1; vars[variable2] = value2; vars[variable3] = value3; @@ -276,7 +283,7 @@ void Printer::Print(const char* text, const char* variable6, const string& value6, const char* variable7, const string& value7, const char* variable8, const string& value8) { - map<string, string> vars; + std::map<string, string> vars; vars[variable1] = value1; vars[variable2] = value2; vars[variable3] = value3; @@ -317,17 +324,38 @@ void Printer::WriteRaw(const char* data, int size) { if (at_start_of_line_ && (size > 0) && (data[0] != '\n')) { // Insert an indent. at_start_of_line_ = false; - WriteRaw(indent_.data(), indent_.size()); + CopyToBuffer(indent_.data(), indent_.size()); if (failed_) return; + // Fix up empty variables (e.g., "{") that should be annotated as + // coming after the indent. + for (std::vector<string>::iterator i = line_start_variables_.begin(); + i != line_start_variables_.end(); ++i) { + substitutions_[*i].first += indent_.size(); + substitutions_[*i].second += indent_.size(); + } } + // If we're going to write any data, clear line_start_variables_, since + // we've either updated them in the block above or they no longer refer to + // the current line. + line_start_variables_.clear(); + + CopyToBuffer(data, size); +} + +void Printer::CopyToBuffer(const char* data, int size) { + if (failed_) return; + if (size == 0) return; + while (size > buffer_size_) { // Data exceeds space in the buffer. Copy what we can and request a // new buffer. - memcpy(buffer_, data, buffer_size_); - offset_ += buffer_size_; - data += buffer_size_; - size -= buffer_size_; + if (buffer_size_ > 0) { + memcpy(buffer_, data, buffer_size_); + offset_ += buffer_size_; + data += buffer_size_; + size -= buffer_size_; + } void* void_buffer; failed_ = !output_->Next(&void_buffer, &buffer_size_); if (failed_) return; |