LCOV - code coverage report
Current view: top level - third_party/protobuf/src/google/protobuf/io - printer.cc (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 80 129 62.0 %
Date: 2015-10-10 Functions: 11 17 64.7 %

          Line data    Source code
       1             : // Protocol Buffers - Google's data interchange format
       2             : // Copyright 2008 Google Inc.  All rights reserved.
       3             : // https://developers.google.com/protocol-buffers/
       4             : //
       5             : // Redistribution and use in source and binary forms, with or without
       6             : // modification, are permitted provided that the following conditions are
       7             : // met:
       8             : //
       9             : //     * Redistributions of source code must retain the above copyright
      10             : // notice, this list of conditions and the following disclaimer.
      11             : //     * Redistributions in binary form must reproduce the above
      12             : // copyright notice, this list of conditions and the following disclaimer
      13             : // in the documentation and/or other materials provided with the
      14             : // distribution.
      15             : //     * Neither the name of Google Inc. nor the names of its
      16             : // contributors may be used to endorse or promote products derived from
      17             : // this software without specific prior written permission.
      18             : //
      19             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      20             : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      21             : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      22             : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      23             : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      24             : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      25             : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      26             : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      27             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      28             : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      29             : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      30             : 
      31             : // Author: kenton@google.com (Kenton Varda)
      32             : //  Based on original Protocol Buffers design by
      33             : //  Sanjay Ghemawat, Jeff Dean, and others.
      34             : 
      35             : #include <google/protobuf/io/printer.h>
      36             : #include <google/protobuf/io/zero_copy_stream.h>
      37             : #include <google/protobuf/stubs/logging.h>
      38             : #include <google/protobuf/stubs/common.h>
      39             : 
      40             : namespace google {
      41             : namespace protobuf {
      42             : namespace io {
      43             : 
      44         146 : Printer::Printer(ZeroCopyOutputStream* output, char variable_delimiter)
      45             :   : variable_delimiter_(variable_delimiter),
      46             :     output_(output),
      47             :     buffer_(NULL),
      48             :     buffer_size_(0),
      49             :     at_start_of_line_(true),
      50         292 :     failed_(false) {
      51         146 : }
      52             : 
      53         292 : Printer::~Printer() {
      54             :   // Only BackUp() if we have called Next() at least once and never failed.
      55         146 :   if (buffer_size_ > 0 && !failed_) {
      56         140 :     output_->BackUp(buffer_size_);
      57             :   }
      58         146 : }
      59             : 
      60      166866 : void Printer::Print(const map<string, string>& variables, const char* text) {
      61      166866 :   int size = strlen(text);
      62      166866 :   int pos = 0;  // The number of bytes we've written so far.
      63             : 
      64     9129024 :   for (int i = 0; i < size; i++) {
      65     8962158 :     if (text[i] == '\n') {
      66             :       // Saw newline.  If there is more text, we may need to insert an indent
      67             :       // here.  So, write what we have so far, including the '\n'.
      68      405447 :       WriteRaw(text + pos, i - pos + 1);
      69      405447 :       pos = i + 1;
      70             : 
      71             :       // Setting this true will cause the next WriteRaw() to insert an indent
      72             :       // first.
      73      405447 :       at_start_of_line_ = true;
      74             : 
      75     8556711 :     } else if (text[i] == variable_delimiter_) {
      76             :       // Saw the start of a variable name.
      77             : 
      78             :       // Write what we have so far.
      79      454761 :       WriteRaw(text + pos, i - pos);
      80      454761 :       pos = i + 1;
      81             : 
      82             :       // Find closing delimiter.
      83      909522 :       const char* end = strchr(text + pos, variable_delimiter_);
      84      454761 :       if (end == NULL) {
      85           0 :         GOOGLE_LOG(DFATAL) << " Unclosed variable name.";
      86           0 :         end = text + pos;
      87             :       }
      88      454761 :       int endpos = end - text;
      89             : 
      90      454761 :       string varname(text + pos, endpos - pos);
      91      454761 :       if (varname.empty()) {
      92             :         // Two delimiters in a row reduce to a literal delimiter character.
      93           0 :         WriteRaw(&variable_delimiter_, 1);
      94             :       } else {
      95             :         // Replace with the variable's value.
      96      454761 :         map<string, string>::const_iterator iter = variables.find(varname);
      97      454761 :         if (iter == variables.end()) {
      98           0 :           GOOGLE_LOG(DFATAL) << " Undefined variable: " << varname;
      99             :         } else {
     100     1364283 :           WriteRaw(iter->second.data(), iter->second.size());
     101             :         }
     102             :       }
     103             : 
     104             :       // Advance past this variable.
     105      454761 :       i = endpos;
     106      454761 :       pos = endpos + 1;
     107             :     }
     108             :   }
     109             : 
     110             :   // Write the rest.
     111      166866 :   WriteRaw(text + pos, size - pos);
     112      166866 : }
     113             : 
     114       49541 : void Printer::Print(const char* text) {
     115       49555 :   static map<string, string> empty;
     116       49541 :   Print(empty, text);
     117       49541 : }
     118             : 
     119       43038 : void Printer::Print(const char* text,
     120             :                     const char* variable, const string& value) {
     121             :   map<string, string> vars;
     122       86076 :   vars[variable] = value;
     123       43038 :   Print(vars, text);
     124       43038 : }
     125             : 
     126        8814 : void Printer::Print(const char* text,
     127             :                     const char* variable1, const string& value1,
     128             :                     const char* variable2, const string& value2) {
     129             :   map<string, string> vars;
     130       17628 :   vars[variable1] = value1;
     131       17628 :   vars[variable2] = value2;
     132        8814 :   Print(vars, text);
     133        8814 : }
     134             : 
     135         582 : void Printer::Print(const char* text,
     136             :                     const char* variable1, const string& value1,
     137             :                     const char* variable2, const string& value2,
     138             :                     const char* variable3, const string& value3) {
     139             :   map<string, string> vars;
     140        1164 :   vars[variable1] = value1;
     141        1164 :   vars[variable2] = value2;
     142        1164 :   vars[variable3] = value3;
     143         582 :   Print(vars, text);
     144         582 : }
     145             : 
     146         397 : void Printer::Print(const char* text,
     147             :                     const char* variable1, const string& value1,
     148             :                     const char* variable2, const string& value2,
     149             :                     const char* variable3, const string& value3,
     150             :                     const char* variable4, const string& value4) {
     151             :   map<string, string> vars;
     152         794 :   vars[variable1] = value1;
     153         794 :   vars[variable2] = value2;
     154         794 :   vars[variable3] = value3;
     155         794 :   vars[variable4] = value4;
     156         397 :   Print(vars, text);
     157         397 : }
     158             : 
     159           0 : void Printer::Print(const char* text,
     160             :                     const char* variable1, const string& value1,
     161             :                     const char* variable2, const string& value2,
     162             :                     const char* variable3, const string& value3,
     163             :                     const char* variable4, const string& value4,
     164             :                     const char* variable5, const string& value5) {
     165             :   map<string, string> vars;
     166           0 :   vars[variable1] = value1;
     167           0 :   vars[variable2] = value2;
     168           0 :   vars[variable3] = value3;
     169           0 :   vars[variable4] = value4;
     170           0 :   vars[variable5] = value5;
     171           0 :   Print(vars, text);
     172           0 : }
     173             : 
     174           0 : void Printer::Print(const char* text,
     175             :                     const char* variable1, const string& value1,
     176             :                     const char* variable2, const string& value2,
     177             :                     const char* variable3, const string& value3,
     178             :                     const char* variable4, const string& value4,
     179             :                     const char* variable5, const string& value5,
     180             :                     const char* variable6, const string& value6) {
     181             :   map<string, string> vars;
     182           0 :   vars[variable1] = value1;
     183           0 :   vars[variable2] = value2;
     184           0 :   vars[variable3] = value3;
     185           0 :   vars[variable4] = value4;
     186           0 :   vars[variable5] = value5;
     187           0 :   vars[variable6] = value6;
     188           0 :   Print(vars, text);
     189           0 : }
     190             : 
     191           0 : void Printer::Print(const char* text,
     192             :                     const char* variable1, const string& value1,
     193             :                     const char* variable2, const string& value2,
     194             :                     const char* variable3, const string& value3,
     195             :                     const char* variable4, const string& value4,
     196             :                     const char* variable5, const string& value5,
     197             :                     const char* variable6, const string& value6,
     198             :                     const char* variable7, const string& value7) {
     199             :   map<string, string> vars;
     200           0 :   vars[variable1] = value1;
     201           0 :   vars[variable2] = value2;
     202           0 :   vars[variable3] = value3;
     203           0 :   vars[variable4] = value4;
     204           0 :   vars[variable5] = value5;
     205           0 :   vars[variable6] = value6;
     206           0 :   vars[variable7] = value7;
     207           0 :   Print(vars, text);
     208           0 : }
     209             : 
     210           0 : void Printer::Print(const char* text,
     211             :                     const char* variable1, const string& value1,
     212             :                     const char* variable2, const string& value2,
     213             :                     const char* variable3, const string& value3,
     214             :                     const char* variable4, const string& value4,
     215             :                     const char* variable5, const string& value5,
     216             :                     const char* variable6, const string& value6,
     217             :                     const char* variable7, const string& value7,
     218             :                     const char* variable8, const string& value8) {
     219             :   map<string, string> vars;
     220           0 :   vars[variable1] = value1;
     221           0 :   vars[variable2] = value2;
     222           0 :   vars[variable3] = value3;
     223           0 :   vars[variable4] = value4;
     224           0 :   vars[variable5] = value5;
     225           0 :   vars[variable6] = value6;
     226           0 :   vars[variable7] = value7;
     227           0 :   vars[variable8] = value8;
     228           0 :   Print(vars, text);
     229           0 : }
     230             : 
     231       18832 : void Printer::Indent() {
     232       18832 :   indent_ += "  ";
     233       18832 : }
     234             : 
     235       18832 : void Printer::Outdent() {
     236       37664 :   if (indent_.empty()) {
     237           0 :     GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent().";
     238       18832 :     return;
     239             :   }
     240             : 
     241       18832 :   indent_.resize(indent_.size() - 2);
     242             : }
     243             : 
     244           0 : void Printer::PrintRaw(const string& data) {
     245           0 :   WriteRaw(data.data(), data.size());
     246           0 : }
     247             : 
     248           0 : void Printer::PrintRaw(const char* data) {
     249           0 :   if (failed_) return;
     250           0 :   WriteRaw(data, strlen(data));
     251             : }
     252             : 
     253     1858861 : void Printer::WriteRaw(const char* data, int size) {
     254     1858861 :   if (failed_) return;
     255     1858861 :   if (size == 0) return;
     256             : 
     257     1349229 :   if (at_start_of_line_ && (size > 0) && (data[0] != '\n')) {
     258             :     // Insert an indent.
     259      377026 :     at_start_of_line_ = false;
     260      754052 :     WriteRaw(indent_.data(), indent_.size());
     261      377026 :     if (failed_) return;
     262             :   }
     263             : 
     264     1350946 :   while (size > buffer_size_) {
     265             :     // Data exceeds space in the buffer.  Copy what we can and request a
     266             :     // new buffer.
     267        1717 :     memcpy(buffer_, data, buffer_size_);
     268        1717 :     data += buffer_size_;
     269        1717 :     size -= buffer_size_;
     270             :     void* void_buffer;
     271        1717 :     failed_ = !output_->Next(&void_buffer, &buffer_size_);
     272        1717 :     if (failed_) return;
     273        1717 :     buffer_ = reinterpret_cast<char*>(void_buffer);
     274             :   }
     275             : 
     276             :   // Buffer is big enough to receive the data; copy it.
     277     1349229 :   memcpy(buffer_, data, size);
     278     1349229 :   buffer_ += size;
     279     1349229 :   buffer_size_ -= size;
     280             : }
     281             : 
     282             : }  // namespace io
     283             : }  // namespace protobuf
     284             : }  // namespace google

Generated by: LCOV version 1.10