PageRenderTime 46ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/jni-build/jni/include/google/protobuf/src/google/protobuf/io/printer.cc

https://gitlab.com/zharfi/GunSafety
C++ | 284 lines | 203 code | 33 blank | 48 comment | 27 complexity | 2eb72775d6d7e7ae27f60579c70fc837 MD5 | raw file
  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. // Author: kenton@google.com (Kenton Varda)
  31. // Based on original Protocol Buffers design by
  32. // Sanjay Ghemawat, Jeff Dean, and others.
  33. #include <google/protobuf/io/printer.h>
  34. #include <google/protobuf/io/zero_copy_stream.h>
  35. #include <google/protobuf/stubs/logging.h>
  36. #include <google/protobuf/stubs/common.h>
  37. namespace google {
  38. namespace protobuf {
  39. namespace io {
  40. Printer::Printer(ZeroCopyOutputStream* output, char variable_delimiter)
  41. : variable_delimiter_(variable_delimiter),
  42. output_(output),
  43. buffer_(NULL),
  44. buffer_size_(0),
  45. at_start_of_line_(true),
  46. failed_(false) {
  47. }
  48. Printer::~Printer() {
  49. // Only BackUp() if we have called Next() at least once and never failed.
  50. if (buffer_size_ > 0 && !failed_) {
  51. output_->BackUp(buffer_size_);
  52. }
  53. }
  54. void Printer::Print(const map<string, string>& variables, const char* text) {
  55. int size = strlen(text);
  56. int pos = 0; // The number of bytes we've written so far.
  57. for (int i = 0; i < size; i++) {
  58. if (text[i] == '\n') {
  59. // Saw newline. If there is more text, we may need to insert an indent
  60. // here. So, write what we have so far, including the '\n'.
  61. WriteRaw(text + pos, i - pos + 1);
  62. pos = i + 1;
  63. // Setting this true will cause the next WriteRaw() to insert an indent
  64. // first.
  65. at_start_of_line_ = true;
  66. } else if (text[i] == variable_delimiter_) {
  67. // Saw the start of a variable name.
  68. // Write what we have so far.
  69. WriteRaw(text + pos, i - pos);
  70. pos = i + 1;
  71. // Find closing delimiter.
  72. const char* end = strchr(text + pos, variable_delimiter_);
  73. if (end == NULL) {
  74. GOOGLE_LOG(DFATAL) << " Unclosed variable name.";
  75. end = text + pos;
  76. }
  77. int endpos = end - text;
  78. string varname(text + pos, endpos - pos);
  79. if (varname.empty()) {
  80. // Two delimiters in a row reduce to a literal delimiter character.
  81. WriteRaw(&variable_delimiter_, 1);
  82. } else {
  83. // Replace with the variable's value.
  84. map<string, string>::const_iterator iter = variables.find(varname);
  85. if (iter == variables.end()) {
  86. GOOGLE_LOG(DFATAL) << " Undefined variable: " << varname;
  87. } else {
  88. WriteRaw(iter->second.data(), iter->second.size());
  89. }
  90. }
  91. // Advance past this variable.
  92. i = endpos;
  93. pos = endpos + 1;
  94. }
  95. }
  96. // Write the rest.
  97. WriteRaw(text + pos, size - pos);
  98. }
  99. void Printer::Print(const char* text) {
  100. static map<string, string> empty;
  101. Print(empty, text);
  102. }
  103. void Printer::Print(const char* text,
  104. const char* variable, const string& value) {
  105. map<string, string> vars;
  106. vars[variable] = value;
  107. Print(vars, text);
  108. }
  109. void Printer::Print(const char* text,
  110. const char* variable1, const string& value1,
  111. const char* variable2, const string& value2) {
  112. map<string, string> vars;
  113. vars[variable1] = value1;
  114. vars[variable2] = value2;
  115. Print(vars, text);
  116. }
  117. void Printer::Print(const char* text,
  118. const char* variable1, const string& value1,
  119. const char* variable2, const string& value2,
  120. const char* variable3, const string& value3) {
  121. map<string, string> vars;
  122. vars[variable1] = value1;
  123. vars[variable2] = value2;
  124. vars[variable3] = value3;
  125. Print(vars, text);
  126. }
  127. void Printer::Print(const char* text,
  128. const char* variable1, const string& value1,
  129. const char* variable2, const string& value2,
  130. const char* variable3, const string& value3,
  131. const char* variable4, const string& value4) {
  132. map<string, string> vars;
  133. vars[variable1] = value1;
  134. vars[variable2] = value2;
  135. vars[variable3] = value3;
  136. vars[variable4] = value4;
  137. Print(vars, text);
  138. }
  139. void Printer::Print(const char* text,
  140. const char* variable1, const string& value1,
  141. const char* variable2, const string& value2,
  142. const char* variable3, const string& value3,
  143. const char* variable4, const string& value4,
  144. const char* variable5, const string& value5) {
  145. map<string, string> vars;
  146. vars[variable1] = value1;
  147. vars[variable2] = value2;
  148. vars[variable3] = value3;
  149. vars[variable4] = value4;
  150. vars[variable5] = value5;
  151. Print(vars, text);
  152. }
  153. void Printer::Print(const char* text,
  154. const char* variable1, const string& value1,
  155. const char* variable2, const string& value2,
  156. const char* variable3, const string& value3,
  157. const char* variable4, const string& value4,
  158. const char* variable5, const string& value5,
  159. const char* variable6, const string& value6) {
  160. map<string, string> vars;
  161. vars[variable1] = value1;
  162. vars[variable2] = value2;
  163. vars[variable3] = value3;
  164. vars[variable4] = value4;
  165. vars[variable5] = value5;
  166. vars[variable6] = value6;
  167. Print(vars, text);
  168. }
  169. void Printer::Print(const char* text,
  170. const char* variable1, const string& value1,
  171. const char* variable2, const string& value2,
  172. const char* variable3, const string& value3,
  173. const char* variable4, const string& value4,
  174. const char* variable5, const string& value5,
  175. const char* variable6, const string& value6,
  176. const char* variable7, const string& value7) {
  177. map<string, string> vars;
  178. vars[variable1] = value1;
  179. vars[variable2] = value2;
  180. vars[variable3] = value3;
  181. vars[variable4] = value4;
  182. vars[variable5] = value5;
  183. vars[variable6] = value6;
  184. vars[variable7] = value7;
  185. Print(vars, text);
  186. }
  187. void Printer::Print(const char* text,
  188. const char* variable1, const string& value1,
  189. const char* variable2, const string& value2,
  190. const char* variable3, const string& value3,
  191. const char* variable4, const string& value4,
  192. const char* variable5, const string& value5,
  193. const char* variable6, const string& value6,
  194. const char* variable7, const string& value7,
  195. const char* variable8, const string& value8) {
  196. map<string, string> vars;
  197. vars[variable1] = value1;
  198. vars[variable2] = value2;
  199. vars[variable3] = value3;
  200. vars[variable4] = value4;
  201. vars[variable5] = value5;
  202. vars[variable6] = value6;
  203. vars[variable7] = value7;
  204. vars[variable8] = value8;
  205. Print(vars, text);
  206. }
  207. void Printer::Indent() {
  208. indent_ += " ";
  209. }
  210. void Printer::Outdent() {
  211. if (indent_.empty()) {
  212. GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent().";
  213. return;
  214. }
  215. indent_.resize(indent_.size() - 2);
  216. }
  217. void Printer::PrintRaw(const string& data) {
  218. WriteRaw(data.data(), data.size());
  219. }
  220. void Printer::PrintRaw(const char* data) {
  221. if (failed_) return;
  222. WriteRaw(data, strlen(data));
  223. }
  224. void Printer::WriteRaw(const char* data, int size) {
  225. if (failed_) return;
  226. if (size == 0) return;
  227. if (at_start_of_line_ && (size > 0) && (data[0] != '\n')) {
  228. // Insert an indent.
  229. at_start_of_line_ = false;
  230. WriteRaw(indent_.data(), indent_.size());
  231. if (failed_) return;
  232. }
  233. while (size > buffer_size_) {
  234. // Data exceeds space in the buffer. Copy what we can and request a
  235. // new buffer.
  236. memcpy(buffer_, data, buffer_size_);
  237. data += buffer_size_;
  238. size -= buffer_size_;
  239. void* void_buffer;
  240. failed_ = !output_->Next(&void_buffer, &buffer_size_);
  241. if (failed_) return;
  242. buffer_ = reinterpret_cast<char*>(void_buffer);
  243. }
  244. // Buffer is big enough to receive the data; copy it.
  245. memcpy(buffer_, data, size);
  246. buffer_ += size;
  247. buffer_size_ -= size;
  248. }
  249. } // namespace io
  250. } // namespace protobuf
  251. } // namespace google