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#ifndef GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__
32#define GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__
33
34#include <string>
35#include <utility>
36
37#include <google/protobuf/port.h>
38#include <google/protobuf/stubs/strutil.h>
39
40// Must be included last.
41#include <google/protobuf/port_def.inc>
42
43#ifdef SWIG
44#error "You cannot SWIG proto headers"
45#endif
46
47namespace google {
48namespace protobuf {
49
50class Arena;
51
52namespace internal {
53
54// InlinedStringField wraps a std::string instance and exposes an API similar to
55// ArenaStringPtr's wrapping of a std::string* instance. As std::string is
56// never allocated on the Arena, we expose only the *NoArena methods of
57// ArenaStringPtr.
58//
59// default_value parameters are taken for consistency with ArenaStringPtr, but
60// are not used for most methods. With inlining, these should be removed from
61// the generated binary.
62class PROTOBUF_EXPORT InlinedStringField {
63 public:
64 InlinedStringField() PROTOBUF_ALWAYS_INLINE;
65 explicit InlinedStringField(const std::string& default_value);
66
67 void AssignWithDefault(const std::string* default_value,
68 const InlinedStringField& from) PROTOBUF_ALWAYS_INLINE;
69
70 void ClearToEmpty(const std::string* default_value,
71 Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE {
72 ClearToEmptyNoArena(default_value);
73 }
74 void ClearNonDefaultToEmpty() PROTOBUF_ALWAYS_INLINE {
75 ClearNonDefaultToEmptyNoArena();
76 }
77 void ClearToEmptyNoArena(const std::string* /*default_value*/)
78 PROTOBUF_ALWAYS_INLINE {
79 ClearNonDefaultToEmptyNoArena();
80 }
81 void ClearNonDefaultToEmptyNoArena() PROTOBUF_ALWAYS_INLINE;
82
83 void ClearToDefault(const std::string* default_value,
84 Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE {
85 ClearToDefaultNoArena(default_value);
86 }
87 void ClearToDefaultNoArena(const std::string* default_value)
88 PROTOBUF_ALWAYS_INLINE;
89
90 void Destroy(const std::string* default_value,
91 Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE {
92 DestroyNoArena(default_value);
93 }
94 void DestroyNoArena(const std::string* default_value) PROTOBUF_ALWAYS_INLINE;
95
96 const std::string& Get() const PROTOBUF_ALWAYS_INLINE { return GetNoArena(); }
97 const std::string& GetNoArena() const PROTOBUF_ALWAYS_INLINE;
98
99 std::string* Mutable(const std::string* default_value,
100 Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE {
101 return MutableNoArena(default_value);
102 }
103 std::string* MutableNoArena(const std::string* default_value)
104 PROTOBUF_ALWAYS_INLINE;
105
106 std::string* Release(const std::string* default_value, Arena* /*arena*/) {
107 return ReleaseNoArena(default_value);
108 }
109 std::string* ReleaseNonDefault(const std::string* default_value,
110 Arena* /*arena*/) {
111 return ReleaseNonDefaultNoArena(default_value);
112 }
113 std::string* ReleaseNoArena(const std::string* default_value) {
114 return ReleaseNonDefaultNoArena(default_value);
115 }
116 std::string* ReleaseNonDefaultNoArena(const std::string* default_value);
117
118 void Set(const std::string* default_value, StringPiece value,
119 Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE {
120 SetNoArena(default_value, value);
121 }
122 void SetLite(const std::string* default_value, StringPiece value,
123 Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE {
124 SetNoArena(default_value, value);
125 }
126 void SetNoArena(const std::string* default_value,
127 StringPiece value) PROTOBUF_ALWAYS_INLINE;
128
129 void Set(const std::string* default_value, const std::string& value,
130 Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE {
131 SetNoArena(default_value, value);
132 }
133 void SetLite(const std::string* default_value, const std::string& value,
134 Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE {
135 SetNoArena(default_value, value);
136 }
137 void SetNoArena(const std::string* default_value,
138 const std::string& value) PROTOBUF_ALWAYS_INLINE;
139
140 void SetNoArena(const std::string* default_value,
141 std::string&& value) PROTOBUF_ALWAYS_INLINE;
142 void SetAllocated(const std::string* default_value, std::string* value,
143 Arena* /*arena*/) {
144 SetAllocatedNoArena(default_value, value);
145 }
146 void SetAllocatedNoArena(const std::string* default_value,
147 std::string* value);
148 void Swap(InlinedStringField* from) PROTOBUF_ALWAYS_INLINE;
149 std::string* UnsafeMutablePointer();
150 void UnsafeSetDefault(const std::string* default_value);
151 std::string* UnsafeArenaRelease(const std::string* default_value,
152 Arena* arena);
153 void UnsafeArenaSetAllocated(const std::string* default_value,
154 std::string* value, Arena* arena);
155
156 bool IsDefault(const std::string* /*default_value*/) { return false; }
157
158 private:
159 std::string value_;
160};
161
162inline InlinedStringField::InlinedStringField() {}
163
164inline InlinedStringField::InlinedStringField(const std::string& default_value)
165 : value_(default_value) {}
166
167inline void InlinedStringField::AssignWithDefault(
168 const std::string* /*default_value*/, const InlinedStringField& from) {
169 value_ = from.value_;
170}
171
172inline const std::string& InlinedStringField::GetNoArena() const {
173 return value_;
174}
175
176inline std::string* InlinedStringField::MutableNoArena(const std::string*) {
177 return &value_;
178}
179
180inline void InlinedStringField::SetAllocatedNoArena(
181 const std::string* default_value, std::string* value) {
182 if (value == NULL) {
183 value_.assign(*default_value);
184 } else {
185 value_.assign(std::move(*value));
186 delete value;
187 }
188}
189
190inline void InlinedStringField::DestroyNoArena(const std::string*) {
191 // This is invoked from the generated message's ArenaDtor, which is used to
192 // clean up objects not allocated on the Arena.
193 this->~InlinedStringField();
194}
195
196inline void InlinedStringField::ClearNonDefaultToEmptyNoArena() {
197 value_.clear();
198}
199
200inline void InlinedStringField::ClearToDefaultNoArena(
201 const std::string* default_value) {
202 value_.assign(*default_value);
203}
204
205inline std::string* InlinedStringField::ReleaseNonDefaultNoArena(
206 const std::string* default_value) {
207 std::string* released = new std::string(*default_value);
208 value_.swap(*released);
209 return released;
210}
211
212inline void InlinedStringField::SetNoArena(const std::string* /*default_value*/,
213 StringPiece value) {
214 value_.assign(value.data(), value.length());
215}
216
217inline void InlinedStringField::SetNoArena(const std::string* /*default_value*/,
218 const std::string& value) {
219 value_.assign(value);
220}
221
222inline void InlinedStringField::SetNoArena(const std::string* /*default_value*/,
223 std::string&& value) {
224 value_.assign(std::move(value));
225}
226
227inline void InlinedStringField::Swap(InlinedStringField* from) {
228 value_.swap(from->value_);
229}
230
231inline std::string* InlinedStringField::UnsafeMutablePointer() {
232 return &value_;
233}
234
235inline void InlinedStringField::UnsafeSetDefault(
236 const std::string* default_value) {
237 value_.assign(*default_value);
238}
239
240inline std::string* InlinedStringField::UnsafeArenaRelease(
241 const std::string* default_value, Arena* /*arena*/) {
242 return ReleaseNoArena(default_value);
243}
244
245inline void InlinedStringField::UnsafeArenaSetAllocated(
246 const std::string* default_value, std::string* value, Arena* /*arena*/) {
247 if (value == NULL) {
248 value_.assign(*default_value);
249 } else {
250 value_.assign(*value);
251 }
252}
253
254} // namespace internal
255} // namespace protobuf
256} // namespace google
257
258#include <google/protobuf/port_undef.inc>
259
260#endif // GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__
261