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_UTIL_INTERNAL_DATAPIECE_H__
32#define GOOGLE_PROTOBUF_UTIL_INTERNAL_DATAPIECE_H__
33
34#include <cstdint>
35#include <string>
36
37#include <google/protobuf/stubs/common.h>
38#include <google/protobuf/stubs/logging.h>
39#include <google/protobuf/type.pb.h>
40#include <google/protobuf/stubs/statusor.h>
41#include <google/protobuf/stubs/strutil.h>
42
43// Must be included last.
44#include <google/protobuf/port_def.inc>
45
46namespace google {
47namespace protobuf {
48namespace util {
49namespace converter {
50class ProtoWriter;
51
52// Container for a single piece of data together with its data type.
53//
54// For primitive types (int32, int64, uint32, uint64, double, float, bool),
55// the data is stored by value.
56//
57// For string, a StringPiece is stored. For Cord, a pointer to Cord is stored.
58// Just like StringPiece, the DataPiece class does not own the storage for
59// the actual string or Cord, so it is the user's responsibility to guarantee
60// that the underlying storage is still valid when the DataPiece is accessed.
61class PROTOBUF_EXPORT DataPiece {
62 public:
63 // Identifies data type of the value.
64 // These are the types supported by DataPiece.
65 enum Type {
66 TYPE_INT32 = 1,
67 TYPE_INT64 = 2,
68 TYPE_UINT32 = 3,
69 TYPE_UINT64 = 4,
70 TYPE_DOUBLE = 5,
71 TYPE_FLOAT = 6,
72 TYPE_BOOL = 7,
73 TYPE_ENUM = 8,
74 TYPE_STRING = 9,
75 TYPE_BYTES = 10,
76 TYPE_NULL = 11, // explicit NULL type
77 };
78
79 // Constructors and Destructor
80 explicit DataPiece(const int32_t value)
81 : type_(TYPE_INT32), i32_(value), use_strict_base64_decoding_(false) {}
82 explicit DataPiece(const int64_t value)
83 : type_(TYPE_INT64), i64_(value), use_strict_base64_decoding_(false) {}
84 explicit DataPiece(const uint32_t value)
85 : type_(TYPE_UINT32), u32_(value), use_strict_base64_decoding_(false) {}
86 explicit DataPiece(const uint64_t value)
87 : type_(TYPE_UINT64), u64_(value), use_strict_base64_decoding_(false) {}
88 explicit DataPiece(const double value)
89 : type_(TYPE_DOUBLE),
90 double_(value),
91 use_strict_base64_decoding_(false) {}
92 explicit DataPiece(const float value)
93 : type_(TYPE_FLOAT), float_(value), use_strict_base64_decoding_(false) {}
94 explicit DataPiece(const bool value)
95 : type_(TYPE_BOOL), bool_(value), use_strict_base64_decoding_(false) {}
96 DataPiece(StringPiece value, bool use_strict_base64_decoding)
97 : type_(TYPE_STRING),
98 str_(value),
99 use_strict_base64_decoding_(use_strict_base64_decoding) {}
100 // Constructor for bytes. The second parameter is not used.
101 DataPiece(StringPiece value, bool /*dummy*/, bool use_strict_base64_decoding)
102 : type_(TYPE_BYTES),
103 str_(value),
104 use_strict_base64_decoding_(use_strict_base64_decoding) {}
105
106 DataPiece(const DataPiece& r) : type_(r.type_) { InternalCopy(other: r); }
107
108 DataPiece& operator=(const DataPiece& x) {
109 InternalCopy(other: x);
110 return *this;
111 }
112
113 static DataPiece NullData() { return DataPiece(TYPE_NULL, 0); }
114
115 virtual ~DataPiece() {
116 }
117
118 // Accessors
119 Type type() const { return type_; }
120
121 bool use_strict_base64_decoding() { return use_strict_base64_decoding_; }
122
123 StringPiece str() const {
124 GOOGLE_LOG_IF(DFATAL, type_ != TYPE_STRING) << "Not a string type.";
125 return str_;
126 }
127
128
129 // Parses, casts or converts the value stored in the DataPiece into an int32.
130 util::StatusOr<int32_t> ToInt32() const;
131
132 // Parses, casts or converts the value stored in the DataPiece into a uint32.
133 util::StatusOr<uint32_t> ToUint32() const;
134
135 // Parses, casts or converts the value stored in the DataPiece into an int64.
136 util::StatusOr<int64_t> ToInt64() const;
137
138 // Parses, casts or converts the value stored in the DataPiece into a uint64.
139 util::StatusOr<uint64_t> ToUint64() const;
140
141 // Parses, casts or converts the value stored in the DataPiece into a double.
142 util::StatusOr<double> ToDouble() const;
143
144 // Parses, casts or converts the value stored in the DataPiece into a float.
145 util::StatusOr<float> ToFloat() const;
146
147 // Parses, casts or converts the value stored in the DataPiece into a bool.
148 util::StatusOr<bool> ToBool() const;
149
150 // Parses, casts or converts the value stored in the DataPiece into a string.
151 util::StatusOr<std::string> ToString() const;
152
153 // Tries to convert the value contained in this datapiece to string. If the
154 // conversion fails, it returns the default_string.
155 std::string ValueAsStringOrDefault(StringPiece default_string) const;
156
157 util::StatusOr<std::string> ToBytes() const;
158
159 private:
160 friend class ProtoWriter;
161
162 // Disallow implicit constructor.
163 DataPiece();
164
165 // Helper to create NULL or ENUM types.
166 DataPiece(Type type, int32_t val)
167 : type_(type), i32_(val), use_strict_base64_decoding_(false) {}
168
169 // Same as the ToEnum() method above but with additional flag to ignore
170 // unknown enum values.
171 util::StatusOr<int> ToEnum(const google::protobuf::Enum* enum_type,
172 bool use_lower_camel_for_enums,
173 bool case_insensitive_enum_parsing,
174 bool ignore_unknown_enum_values,
175 bool* is_unknown_enum_value) const;
176
177 // For numeric conversion between
178 // int32, int64, uint32, uint64, double, float and bool
179 template <typename To>
180 util::StatusOr<To> GenericConvert() const;
181
182 // For conversion from string to
183 // int32, int64, uint32, uint64, double, float and bool
184 template <typename To>
185 util::StatusOr<To> StringToNumber(bool (*func)(StringPiece, To*)) const;
186
187 // Decodes a base64 string. Returns true on success.
188 bool DecodeBase64(StringPiece src, std::string* dest) const;
189
190 // Helper function to initialize this DataPiece with 'other'.
191 void InternalCopy(const DataPiece& other);
192
193 // Data type for this piece of data.
194 Type type_;
195
196 // Stored piece of data.
197 union {
198 int32_t i32_;
199 int64_t i64_;
200 uint32_t u32_;
201 uint64_t u64_;
202 double double_;
203 float float_;
204 bool bool_;
205 StringPiece str_;
206 };
207
208 // Uses a stricter version of base64 decoding for byte fields.
209 bool use_strict_base64_decoding_;
210};
211
212} // namespace converter
213} // namespace util
214} // namespace protobuf
215} // namespace google
216
217#include <google/protobuf/port_undef.inc>
218
219#endif // GOOGLE_PROTOBUF_UTIL_INTERNAL_DATAPIECE_H__
220