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

/src/cpp/cpp_string_field.cc

http://protoc-gen-luabind.googlecode.com/
C++ | 453 lines | 359 code | 42 blank | 52 comment | 27 complexity | 14cd267be75cde6964c3af87bc66b688 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 "cpp/cpp_string_field.h"
  34. #include "cpp/cpp_helpers.h"
  35. #include <google/protobuf/io/printer.h>
  36. #include <google/protobuf/descriptor.pb.h>
  37. #include <google/protobuf/stubs/strutil.h>
  38. namespace google {
  39. namespace protobuf {
  40. namespace compiler {
  41. namespace cpp {
  42. namespace {
  43. void SetStringVariables(const FieldDescriptor* descriptor,
  44. map<string, string>* variables) {
  45. SetCommonFieldVariables(descriptor, variables);
  46. (*variables)["default"] = DefaultValue(descriptor);
  47. (*variables)["default_variable"] = descriptor->default_value_string().empty()
  48. ? "::google::protobuf::internal::kEmptyString"
  49. : "_default_" + FieldName(descriptor) + "_";
  50. (*variables)["pointer_type"] =
  51. descriptor->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char";
  52. }
  53. } // namespace
  54. // ===================================================================
  55. StringFieldGenerator::
  56. StringFieldGenerator(const FieldDescriptor* descriptor)
  57. : descriptor_(descriptor) {
  58. SetStringVariables(descriptor, &variables_);
  59. }
  60. StringFieldGenerator::~StringFieldGenerator() {}
  61. void StringFieldGenerator::
  62. GeneratePrivateMembers(io::Printer* printer) const {
  63. printer->Print(variables_, "::std::string* $name$_;\n");
  64. if (!descriptor_->default_value_string().empty()) {
  65. printer->Print(variables_, "static const ::std::string $default_variable$;\n");
  66. }
  67. }
  68. void StringFieldGenerator::
  69. GenerateAccessorDeclarations(io::Printer* printer) const {
  70. // If we're using StringFieldGenerator for a field with a ctype, it's
  71. // because that ctype isn't actually implemented. In particular, this is
  72. // true of ctype=CORD and ctype=STRING_PIECE in the open source release.
  73. // We aren't releasing Cord because it has too many Google-specific
  74. // dependencies and we aren't releasing StringPiece because it's hardly
  75. // useful outside of Google and because it would get confusing to have
  76. // multiple instances of the StringPiece class in different libraries (PCRE
  77. // already includes it for their C++ bindings, which came from Google).
  78. //
  79. // In any case, we make all the accessors private while still actually
  80. // using a string to represent the field internally. This way, we can
  81. // guarantee that if we do ever implement the ctype, it won't break any
  82. // existing users who might be -- for whatever reason -- already using .proto
  83. // files that applied the ctype. The field can still be accessed via the
  84. // reflection interface since the reflection interface is independent of
  85. // the string's underlying representation.
  86. if (descriptor_->options().ctype() != FieldOptions::STRING) {
  87. printer->Outdent();
  88. printer->Print(
  89. " private:\n"
  90. " // Hidden due to unknown ctype option.\n");
  91. printer->Indent();
  92. }
  93. printer->Print(variables_,
  94. "inline const ::std::string& $name$() const$deprecation$;\n"
  95. "inline void set_$name$(const ::std::string& value)$deprecation$;\n"
  96. "inline void set_$name$(const char* value)$deprecation$;\n"
  97. "inline void set_$name$(const $pointer_type$* value, size_t size)"
  98. "$deprecation$;\n"
  99. "inline ::std::string* mutable_$name$()$deprecation$;\n"
  100. "inline ::std::string* release_$name$()$deprecation$;\n");
  101. if (descriptor_->options().ctype() != FieldOptions::STRING) {
  102. printer->Outdent();
  103. printer->Print(" public:\n");
  104. printer->Indent();
  105. }
  106. }
  107. void StringFieldGenerator::
  108. GenerateInlineAccessorDefinitions(io::Printer* printer) const {
  109. printer->Print(variables_,
  110. "inline const ::std::string& $classname$::$name$() const {\n"
  111. " return *$name$_;\n"
  112. "}\n"
  113. "inline void $classname$::set_$name$(const ::std::string& value) {\n"
  114. " set_has_$name$();\n"
  115. " if ($name$_ == &$default_variable$) {\n"
  116. " $name$_ = new ::std::string;\n"
  117. " }\n"
  118. " $name$_->assign(value);\n"
  119. "}\n"
  120. "inline void $classname$::set_$name$(const char* value) {\n"
  121. " set_has_$name$();\n"
  122. " if ($name$_ == &$default_variable$) {\n"
  123. " $name$_ = new ::std::string;\n"
  124. " }\n"
  125. " $name$_->assign(value);\n"
  126. "}\n"
  127. "inline "
  128. "void $classname$::set_$name$(const $pointer_type$* value, size_t size) {\n"
  129. " set_has_$name$();\n"
  130. " if ($name$_ == &$default_variable$) {\n"
  131. " $name$_ = new ::std::string;\n"
  132. " }\n"
  133. " $name$_->assign(reinterpret_cast<const char*>(value), size);\n"
  134. "}\n"
  135. "inline ::std::string* $classname$::mutable_$name$() {\n"
  136. " set_has_$name$();\n"
  137. " if ($name$_ == &$default_variable$) {\n");
  138. if (descriptor_->default_value_string().empty()) {
  139. printer->Print(variables_,
  140. " $name$_ = new ::std::string;\n");
  141. } else {
  142. printer->Print(variables_,
  143. " $name$_ = new ::std::string($default_variable$);\n");
  144. }
  145. printer->Print(variables_,
  146. " }\n"
  147. " return $name$_;\n"
  148. "}\n"
  149. "inline ::std::string* $classname$::release_$name$() {\n"
  150. " clear_has_$name$();\n"
  151. " if ($name$_ == &$default_variable$) {\n"
  152. " return NULL;\n"
  153. " } else {\n"
  154. " ::std::string* temp = $name$_;\n"
  155. " $name$_ = const_cast< ::std::string*>(&$default_variable$);\n"
  156. " return temp;\n"
  157. " }\n"
  158. "}\n");
  159. }
  160. void StringFieldGenerator::
  161. GenerateNonInlineAccessorDefinitions(io::Printer* printer) const {
  162. if (!descriptor_->default_value_string().empty()) {
  163. printer->Print(variables_,
  164. "const ::std::string $classname$::$default_variable$($default$);\n");
  165. }
  166. }
  167. void StringFieldGenerator::
  168. GenerateClearingCode(io::Printer* printer) const {
  169. if (descriptor_->default_value_string().empty()) {
  170. printer->Print(variables_,
  171. "if ($name$_ != &$default_variable$) {\n"
  172. " $name$_->clear();\n"
  173. "}\n");
  174. } else {
  175. printer->Print(variables_,
  176. "if ($name$_ != &$default_variable$) {\n"
  177. " $name$_->assign($default_variable$);\n"
  178. "}\n");
  179. }
  180. }
  181. void StringFieldGenerator::
  182. GenerateMergingCode(io::Printer* printer) const {
  183. printer->Print(variables_, "set_$name$(from.$name$());\n");
  184. }
  185. void StringFieldGenerator::
  186. GenerateSwappingCode(io::Printer* printer) const {
  187. printer->Print(variables_, "std::swap($name$_, other->$name$_);\n");
  188. }
  189. void StringFieldGenerator::
  190. GenerateConstructorCode(io::Printer* printer) const {
  191. printer->Print(variables_,
  192. "$name$_ = const_cast< ::std::string*>(&$default_variable$);\n");
  193. }
  194. void StringFieldGenerator::
  195. GenerateDestructorCode(io::Printer* printer) const {
  196. printer->Print(variables_,
  197. "if ($name$_ != &$default_variable$) {\n"
  198. " delete $name$_;\n"
  199. "}\n");
  200. }
  201. void StringFieldGenerator::
  202. GenerateMergeFromCodedStream(io::Printer* printer) const {
  203. printer->Print(variables_,
  204. "DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n"
  205. " input, this->mutable_$name$()));\n");
  206. if (HasUtf8Verification(descriptor_->file()) &&
  207. descriptor_->type() == FieldDescriptor::TYPE_STRING) {
  208. printer->Print(variables_,
  209. "::google::protobuf::internal::WireFormat::VerifyUTF8String(\n"
  210. " this->$name$().data(), this->$name$().length(),\n"
  211. " ::google::protobuf::internal::WireFormat::PARSE);\n");
  212. }
  213. }
  214. void StringFieldGenerator::
  215. GenerateSerializeWithCachedSizes(io::Printer* printer) const {
  216. if (HasUtf8Verification(descriptor_->file()) &&
  217. descriptor_->type() == FieldDescriptor::TYPE_STRING) {
  218. printer->Print(variables_,
  219. "::google::protobuf::internal::WireFormat::VerifyUTF8String(\n"
  220. " this->$name$().data(), this->$name$().length(),\n"
  221. " ::google::protobuf::internal::WireFormat::SERIALIZE);\n");
  222. }
  223. printer->Print(variables_,
  224. "::google::protobuf::internal::WireFormatLite::Write$declared_type$(\n"
  225. " $number$, this->$name$(), output);\n");
  226. }
  227. void StringFieldGenerator::
  228. GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
  229. if (HasUtf8Verification(descriptor_->file()) &&
  230. descriptor_->type() == FieldDescriptor::TYPE_STRING) {
  231. printer->Print(variables_,
  232. "::google::protobuf::internal::WireFormat::VerifyUTF8String(\n"
  233. " this->$name$().data(), this->$name$().length(),\n"
  234. " ::google::protobuf::internal::WireFormat::SERIALIZE);\n");
  235. }
  236. printer->Print(variables_,
  237. "target =\n"
  238. " ::google::protobuf::internal::WireFormatLite::Write$declared_type$ToArray(\n"
  239. " $number$, this->$name$(), target);\n");
  240. }
  241. void StringFieldGenerator::
  242. GenerateByteSize(io::Printer* printer) const {
  243. printer->Print(variables_,
  244. "total_size += $tag_size$ +\n"
  245. " ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n"
  246. " this->$name$());\n");
  247. }
  248. // ===================================================================
  249. RepeatedStringFieldGenerator::
  250. RepeatedStringFieldGenerator(const FieldDescriptor* descriptor)
  251. : descriptor_(descriptor) {
  252. SetStringVariables(descriptor, &variables_);
  253. }
  254. RepeatedStringFieldGenerator::~RepeatedStringFieldGenerator() {}
  255. void RepeatedStringFieldGenerator::
  256. GeneratePrivateMembers(io::Printer* printer) const {
  257. printer->Print(variables_,
  258. "::google::protobuf::RepeatedPtrField< ::std::string > $name$_;\n");
  259. }
  260. void RepeatedStringFieldGenerator::
  261. GenerateAccessorDeclarations(io::Printer* printer) const {
  262. // See comment above about unknown ctypes.
  263. if (descriptor_->options().ctype() != FieldOptions::STRING) {
  264. printer->Outdent();
  265. printer->Print(
  266. " private:\n"
  267. " // Hidden due to unknown ctype option.\n");
  268. printer->Indent();
  269. }
  270. printer->Print(variables_,
  271. "inline const ::std::string& $name$(int index) const$deprecation$;\n"
  272. "inline ::std::string* mutable_$name$(int index)$deprecation$;\n"
  273. "inline void set_$name$(int index, const ::std::string& value)$deprecation$;\n"
  274. "inline void set_$name$(int index, const char* value)$deprecation$;\n"
  275. "inline "
  276. "void set_$name$(int index, const $pointer_type$* value, size_t size)"
  277. "$deprecation$;\n"
  278. "inline ::std::string* add_$name$()$deprecation$;\n"
  279. "inline void add_$name$(const ::std::string& value)$deprecation$;\n"
  280. "inline void add_$name$(const char* value)$deprecation$;\n"
  281. "inline void add_$name$(const $pointer_type$* value, size_t size)"
  282. "$deprecation$;\n");
  283. printer->Print(variables_,
  284. "inline const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() const"
  285. "$deprecation$;\n"
  286. "inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_$name$()"
  287. "$deprecation$;\n");
  288. if (descriptor_->options().ctype() != FieldOptions::STRING) {
  289. printer->Outdent();
  290. printer->Print(" public:\n");
  291. printer->Indent();
  292. }
  293. }
  294. void RepeatedStringFieldGenerator::
  295. GenerateInlineAccessorDefinitions(io::Printer* printer) const {
  296. printer->Print(variables_,
  297. "inline const ::std::string& $classname$::$name$(int index) const {\n"
  298. " return $name$_.Get(index);\n"
  299. "}\n"
  300. "inline ::std::string* $classname$::mutable_$name$(int index) {\n"
  301. " return $name$_.Mutable(index);\n"
  302. "}\n"
  303. "inline void $classname$::set_$name$(int index, const ::std::string& value) {\n"
  304. " $name$_.Mutable(index)->assign(value);\n"
  305. "}\n"
  306. "inline void $classname$::set_$name$(int index, const char* value) {\n"
  307. " $name$_.Mutable(index)->assign(value);\n"
  308. "}\n"
  309. "inline void "
  310. "$classname$::set_$name$"
  311. "(int index, const $pointer_type$* value, size_t size) {\n"
  312. " $name$_.Mutable(index)->assign(\n"
  313. " reinterpret_cast<const char*>(value), size);\n"
  314. "}\n"
  315. "inline ::std::string* $classname$::add_$name$() {\n"
  316. " return $name$_.Add();\n"
  317. "}\n"
  318. "inline void $classname$::add_$name$(const ::std::string& value) {\n"
  319. " $name$_.Add()->assign(value);\n"
  320. "}\n"
  321. "inline void $classname$::add_$name$(const char* value) {\n"
  322. " $name$_.Add()->assign(value);\n"
  323. "}\n"
  324. "inline void "
  325. "$classname$::add_$name$(const $pointer_type$* value, size_t size) {\n"
  326. " $name$_.Add()->assign(reinterpret_cast<const char*>(value), size);\n"
  327. "}\n");
  328. printer->Print(variables_,
  329. "inline const ::google::protobuf::RepeatedPtrField< ::std::string>&\n"
  330. "$classname$::$name$() const {\n"
  331. " return $name$_;\n"
  332. "}\n"
  333. "inline ::google::protobuf::RepeatedPtrField< ::std::string>*\n"
  334. "$classname$::mutable_$name$() {\n"
  335. " return &$name$_;\n"
  336. "}\n");
  337. }
  338. void RepeatedStringFieldGenerator::
  339. GenerateClearingCode(io::Printer* printer) const {
  340. printer->Print(variables_, "$name$_.Clear();\n");
  341. }
  342. void RepeatedStringFieldGenerator::
  343. GenerateMergingCode(io::Printer* printer) const {
  344. printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
  345. }
  346. void RepeatedStringFieldGenerator::
  347. GenerateSwappingCode(io::Printer* printer) const {
  348. printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n");
  349. }
  350. void RepeatedStringFieldGenerator::
  351. GenerateConstructorCode(io::Printer* printer) const {
  352. // Not needed for repeated fields.
  353. }
  354. void RepeatedStringFieldGenerator::
  355. GenerateMergeFromCodedStream(io::Printer* printer) const {
  356. printer->Print(variables_,
  357. "DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n"
  358. " input, this->add_$name$()));\n");
  359. if (HasUtf8Verification(descriptor_->file()) &&
  360. descriptor_->type() == FieldDescriptor::TYPE_STRING) {
  361. printer->Print(variables_,
  362. "::google::protobuf::internal::WireFormat::VerifyUTF8String(\n"
  363. " this->$name$(0).data(), this->$name$(0).length(),\n"
  364. " ::google::protobuf::internal::WireFormat::PARSE);\n");
  365. }
  366. }
  367. void RepeatedStringFieldGenerator::
  368. GenerateSerializeWithCachedSizes(io::Printer* printer) const {
  369. printer->Print(variables_,
  370. "for (int i = 0; i < this->$name$_size(); i++) {\n");
  371. if (HasUtf8Verification(descriptor_->file()) &&
  372. descriptor_->type() == FieldDescriptor::TYPE_STRING) {
  373. printer->Print(variables_,
  374. "::google::protobuf::internal::WireFormat::VerifyUTF8String(\n"
  375. " this->$name$(i).data(), this->$name$(i).length(),\n"
  376. " ::google::protobuf::internal::WireFormat::SERIALIZE);\n");
  377. }
  378. printer->Print(variables_,
  379. " ::google::protobuf::internal::WireFormatLite::Write$declared_type$(\n"
  380. " $number$, this->$name$(i), output);\n"
  381. "}\n");
  382. }
  383. void RepeatedStringFieldGenerator::
  384. GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
  385. printer->Print(variables_,
  386. "for (int i = 0; i < this->$name$_size(); i++) {\n");
  387. if (HasUtf8Verification(descriptor_->file()) &&
  388. descriptor_->type() == FieldDescriptor::TYPE_STRING) {
  389. printer->Print(variables_,
  390. " ::google::protobuf::internal::WireFormat::VerifyUTF8String(\n"
  391. " this->$name$(i).data(), this->$name$(i).length(),\n"
  392. " ::google::protobuf::internal::WireFormat::SERIALIZE);\n");
  393. }
  394. printer->Print(variables_,
  395. " target = ::google::protobuf::internal::WireFormatLite::\n"
  396. " Write$declared_type$ToArray($number$, this->$name$(i), target);\n"
  397. "}\n");
  398. }
  399. void RepeatedStringFieldGenerator::
  400. GenerateByteSize(io::Printer* printer) const {
  401. printer->Print(variables_,
  402. "total_size += $tag_size$ * this->$name$_size();\n"
  403. "for (int i = 0; i < this->$name$_size(); i++) {\n"
  404. " total_size += ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n"
  405. " this->$name$(i));\n"
  406. "}\n");
  407. }
  408. } // namespace cpp
  409. } // namespace compiler
  410. } // namespace protobuf
  411. } // namespace google