PageRenderTime 26ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/src/google/protobuf/compiler/cpp/cpp_string_field.cc

https://bitbucket.org/Abd4llA/test
C++ | 384 lines | 287 code | 43 blank | 54 comment | 18 complexity | f8bb45996f7d65745333a8a0a707d876 MD5 | raw file
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // http://code.google.com/p/protobuf/
  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/compiler/cpp/cpp_string_field.h>
  34. #include <google/protobuf/compiler/cpp/cpp_helpers.h>
  35. #include <google/protobuf/io/printer.h>
  36. #include <google/protobuf/wire_format_inl.h>
  37. #include <google/protobuf/descriptor.pb.h>
  38. #include <google/protobuf/stubs/strutil.h>
  39. namespace google {
  40. namespace protobuf {
  41. namespace compiler {
  42. namespace cpp {
  43. using internal::WireFormat;
  44. namespace {
  45. // TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of
  46. // repeat code between this and the other field types.
  47. void SetStringVariables(const FieldDescriptor* descriptor,
  48. map<string, string>* variables) {
  49. (*variables)["name"] = FieldName(descriptor);
  50. (*variables)["default"] =
  51. "\"" + CEscape(descriptor->default_value_string()) + "\"";
  52. (*variables)["index"] = SimpleItoa(descriptor->index());
  53. (*variables)["number"] = SimpleItoa(descriptor->number());
  54. (*variables)["classname"] = ClassName(FieldScope(descriptor), false);
  55. (*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type());
  56. (*variables)["tag_size"] = SimpleItoa(
  57. WireFormat::TagSize(descriptor->number(), descriptor->type()));
  58. }
  59. } // namespace
  60. // ===================================================================
  61. StringFieldGenerator::
  62. StringFieldGenerator(const FieldDescriptor* descriptor)
  63. : descriptor_(descriptor) {
  64. SetStringVariables(descriptor, &variables_);
  65. }
  66. StringFieldGenerator::~StringFieldGenerator() {}
  67. void StringFieldGenerator::
  68. GeneratePrivateMembers(io::Printer* printer) const {
  69. printer->Print(variables_,
  70. "::std::string* $name$_;\n"
  71. "static const ::std::string _default_$name$_;\n");
  72. }
  73. void StringFieldGenerator::
  74. GenerateAccessorDeclarations(io::Printer* printer) const {
  75. // If we're using StringFieldGenerator for a field with a ctype, it's
  76. // because that ctype isn't actually implemented. In particular, this is
  77. // true of ctype=CORD and ctype=STRING_PIECE in the open source release.
  78. // We aren't releasing Cord because it has too many Google-specific
  79. // dependencies and we aren't releasing StringPiece because it's hardly
  80. // useful outside of Google and because it would get confusing to have
  81. // multiple instances of the StringPiece class in different libraries (PCRE
  82. // already includes it for their C++ bindings, which came from Google).
  83. //
  84. // In any case, we make all the accessors private while still actually
  85. // using a string to represent the field internally. This way, we can
  86. // guarantee that if we do ever implement the ctype, it won't break any
  87. // existing users who might be -- for whatever reason -- already using .proto
  88. // files that applied the ctype. The field can still be accessed via the
  89. // reflection interface since the reflection interface is independent of
  90. // the string's underlying representation.
  91. if (descriptor_->options().has_ctype()) {
  92. printer->Outdent();
  93. printer->Print(
  94. " private:\n"
  95. " // Hidden due to unknown ctype option.\n");
  96. printer->Indent();
  97. }
  98. printer->Print(variables_,
  99. "inline const ::std::string& $name$() const;\n"
  100. "inline void set_$name$(const ::std::string& value);\n"
  101. "inline void set_$name$(const char* value);\n");
  102. if (descriptor_->type() == FieldDescriptor::TYPE_BYTES) {
  103. printer->Print(variables_,
  104. "inline void set_$name$(const void* value, size_t size);\n");
  105. }
  106. printer->Print(variables_,
  107. "inline ::std::string* mutable_$name$();\n");
  108. if (descriptor_->options().has_ctype()) {
  109. printer->Outdent();
  110. printer->Print(" public:\n");
  111. printer->Indent();
  112. }
  113. }
  114. void StringFieldGenerator::
  115. GenerateInlineAccessorDefinitions(io::Printer* printer) const {
  116. printer->Print(variables_,
  117. "inline const ::std::string& $classname$::$name$() const {\n"
  118. " return *$name$_;\n"
  119. "}\n"
  120. "inline void $classname$::set_$name$(const ::std::string& value) {\n"
  121. " _set_bit($index$);\n"
  122. " if ($name$_ == &_default_$name$_) {\n"
  123. " $name$_ = new ::std::string;\n"
  124. " }\n"
  125. " $name$_->assign(value);\n"
  126. "}\n"
  127. "inline void $classname$::set_$name$(const char* value) {\n"
  128. " _set_bit($index$);\n"
  129. " if ($name$_ == &_default_$name$_) {\n"
  130. " $name$_ = new ::std::string;\n"
  131. " }\n"
  132. " $name$_->assign(value);\n"
  133. "}\n");
  134. if (descriptor_->type() == FieldDescriptor::TYPE_BYTES) {
  135. printer->Print(variables_,
  136. "inline void $classname$::set_$name$(const void* value, size_t size) {\n"
  137. " _set_bit($index$);\n"
  138. " if ($name$_ == &_default_$name$_) {\n"
  139. " $name$_ = new ::std::string;\n"
  140. " }\n"
  141. " $name$_->assign(reinterpret_cast<const char*>(value), size);\n"
  142. "}\n");
  143. }
  144. printer->Print(variables_,
  145. "inline ::std::string* $classname$::mutable_$name$() {\n"
  146. " _set_bit($index$);\n"
  147. " if ($name$_ == &_default_$name$_) {\n");
  148. if (descriptor_->has_default_value()) {
  149. printer->Print(variables_,
  150. " $name$_ = new ::std::string(_default_$name$_);\n");
  151. } else {
  152. printer->Print(variables_,
  153. " $name$_ = new ::std::string;\n");
  154. }
  155. printer->Print(variables_,
  156. " }\n"
  157. " return $name$_;\n"
  158. "}\n");
  159. }
  160. void StringFieldGenerator::
  161. GenerateNonInlineAccessorDefinitions(io::Printer* printer) const {
  162. if (descriptor_->has_default_value()) {
  163. printer->Print(variables_,
  164. "const ::std::string $classname$::_default_$name$_($default$);");
  165. } else {
  166. printer->Print(variables_,
  167. "const ::std::string $classname$::_default_$name$_;");
  168. }
  169. }
  170. void StringFieldGenerator::
  171. GenerateClearingCode(io::Printer* printer) const {
  172. if (descriptor_->has_default_value()) {
  173. printer->Print(variables_,
  174. "if ($name$_ != &_default_$name$_) {\n"
  175. " $name$_->assign(_default_$name$_);\n"
  176. "}\n");
  177. } else {
  178. printer->Print(variables_,
  179. "if ($name$_ != &_default_$name$_) {\n"
  180. " $name$_->clear();\n"
  181. "}\n");
  182. }
  183. }
  184. void StringFieldGenerator::
  185. GenerateMergingCode(io::Printer* printer) const {
  186. printer->Print(variables_, "set_$name$(from.$name$());\n");
  187. }
  188. void StringFieldGenerator::
  189. GenerateInitializer(io::Printer* printer) const {
  190. printer->Print(variables_,
  191. ",\n$name$_(const_cast< ::std::string*>(&_default_$name$_))");
  192. }
  193. void StringFieldGenerator::
  194. GenerateDestructorCode(io::Printer* printer) const {
  195. printer->Print(variables_,
  196. "if ($name$_ != &_default_$name$_) {\n"
  197. " delete $name$_;\n"
  198. "}\n");
  199. }
  200. void StringFieldGenerator::
  201. GenerateMergeFromCodedStream(io::Printer* printer) const {
  202. printer->Print(variables_,
  203. "DO_(::google::protobuf::internal::WireFormat::Read$declared_type$("
  204. "input, mutable_$name$()));\n");
  205. }
  206. void StringFieldGenerator::
  207. GenerateSerializeWithCachedSizes(io::Printer* printer) const {
  208. printer->Print(variables_,
  209. "DO_(::google::protobuf::internal::WireFormat::Write$declared_type$("
  210. "$number$, this->$name$(), output));\n");
  211. }
  212. void StringFieldGenerator::
  213. GenerateByteSize(io::Printer* printer) const {
  214. printer->Print(variables_,
  215. "total_size += $tag_size$ +\n"
  216. " ::google::protobuf::internal::WireFormat::$declared_type$Size(this->$name$());\n");
  217. }
  218. // ===================================================================
  219. RepeatedStringFieldGenerator::
  220. RepeatedStringFieldGenerator(const FieldDescriptor* descriptor)
  221. : descriptor_(descriptor) {
  222. SetStringVariables(descriptor, &variables_);
  223. }
  224. RepeatedStringFieldGenerator::~RepeatedStringFieldGenerator() {}
  225. void RepeatedStringFieldGenerator::
  226. GeneratePrivateMembers(io::Printer* printer) const {
  227. printer->Print(variables_,
  228. "::google::protobuf::RepeatedPtrField< ::std::string> $name$_;\n");
  229. }
  230. void RepeatedStringFieldGenerator::
  231. GenerateAccessorDeclarations(io::Printer* printer) const {
  232. // See comment above about unknown ctypes.
  233. if (descriptor_->options().has_ctype()) {
  234. printer->Outdent();
  235. printer->Print(
  236. " private:\n"
  237. " // Hidden due to unknown ctype option.\n");
  238. printer->Indent();
  239. }
  240. printer->Print(variables_,
  241. "inline const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() const;\n"
  242. "inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_$name$();\n"
  243. "inline const ::std::string& $name$(int index) const;\n"
  244. "inline ::std::string* mutable_$name$(int index);\n"
  245. "inline void set_$name$(int index, const ::std::string& value);\n"
  246. "inline void set_$name$(int index, const char* value);\n"
  247. "inline ::std::string* add_$name$();\n"
  248. "inline void add_$name$(const ::std::string& value);\n"
  249. "inline void add_$name$(const char* value);\n");
  250. if (descriptor_->type() == FieldDescriptor::TYPE_BYTES) {
  251. printer->Print(variables_,
  252. "inline void set_$name$(int index, const void* value, size_t size);\n"
  253. "inline void add_$name$(const void* value, size_t size);\n");
  254. }
  255. if (descriptor_->options().has_ctype()) {
  256. printer->Outdent();
  257. printer->Print(" public:\n");
  258. printer->Indent();
  259. }
  260. }
  261. void RepeatedStringFieldGenerator::
  262. GenerateInlineAccessorDefinitions(io::Printer* printer) const {
  263. printer->Print(variables_,
  264. "inline const ::google::protobuf::RepeatedPtrField< ::std::string>&\n"
  265. "$classname$::$name$() const {\n"
  266. " return $name$_;\n"
  267. "}\n"
  268. "inline ::google::protobuf::RepeatedPtrField< ::std::string>*\n"
  269. "$classname$::mutable_$name$() {\n"
  270. " return &$name$_;\n"
  271. "}\n"
  272. "inline const ::std::string& $classname$::$name$(int index) const {\n"
  273. " return $name$_.Get(index);\n"
  274. "}\n"
  275. "inline ::std::string* $classname$::mutable_$name$(int index) {\n"
  276. " return $name$_.Mutable(index);\n"
  277. "}\n"
  278. "inline void $classname$::set_$name$(int index, const ::std::string& value) {\n"
  279. " $name$_.Mutable(index)->assign(value);\n"
  280. "}\n"
  281. "inline void $classname$::set_$name$(int index, const char* value) {\n"
  282. " $name$_.Mutable(index)->assign(value);\n"
  283. "}\n"
  284. "inline ::std::string* $classname$::add_$name$() {\n"
  285. " return $name$_.Add();\n"
  286. "}\n"
  287. "inline void $classname$::add_$name$(const ::std::string& value) {\n"
  288. " $name$_.Add()->assign(value);\n"
  289. "}\n"
  290. "inline void $classname$::add_$name$(const char* value) {\n"
  291. " $name$_.Add()->assign(value);\n"
  292. "}\n");
  293. if (descriptor_->type() == FieldDescriptor::TYPE_BYTES) {
  294. printer->Print(variables_,
  295. "inline void "
  296. "$classname$::set_$name$(int index, const void* value, size_t size) {\n"
  297. " $name$_.Mutable(index)->assign(\n"
  298. " reinterpret_cast<const char*>(value), size);\n"
  299. "}\n"
  300. "inline void $classname$::add_$name$(const void* value, size_t size) {\n"
  301. " $name$_.Add()->assign(reinterpret_cast<const char*>(value), size);\n"
  302. "}\n");
  303. }
  304. }
  305. void RepeatedStringFieldGenerator::
  306. GenerateClearingCode(io::Printer* printer) const {
  307. printer->Print(variables_, "$name$_.Clear();\n");
  308. }
  309. void RepeatedStringFieldGenerator::
  310. GenerateMergingCode(io::Printer* printer) const {
  311. printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
  312. }
  313. void RepeatedStringFieldGenerator::
  314. GenerateInitializer(io::Printer* printer) const {
  315. // Not needed for repeated fields.
  316. }
  317. void RepeatedStringFieldGenerator::
  318. GenerateMergeFromCodedStream(io::Printer* printer) const {
  319. printer->Print(variables_,
  320. "DO_(::google::protobuf::internal::WireFormat::Read$declared_type$(\n"
  321. " input, add_$name$()));\n");
  322. }
  323. void RepeatedStringFieldGenerator::
  324. GenerateSerializeWithCachedSizes(io::Printer* printer) const {
  325. printer->Print(variables_,
  326. "DO_(::google::protobuf::internal::WireFormat::Write$declared_type$("
  327. "$number$, this->$name$(i), output));\n");
  328. }
  329. void RepeatedStringFieldGenerator::
  330. GenerateByteSize(io::Printer* printer) const {
  331. printer->Print(variables_,
  332. "total_size += $tag_size$ * $name$_size();\n"
  333. "for (int i = 0; i < $name$_size(); i++) {\n"
  334. " total_size += ::google::protobuf::internal::WireFormat::$declared_type$Size(\n"
  335. " this->$name$(i));\n"
  336. "}\n");
  337. }
  338. } // namespace cpp
  339. } // namespace compiler
  340. } // namespace protobuf
  341. } // namespace google