• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
46 namespace google {
47 namespace protobuf {
48 namespace util {
49 namespace converter {
50 class 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.
61 class 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
DataPiece(const int32_t value)80   explicit DataPiece(const int32_t value)
81       : type_(TYPE_INT32), i32_(value), use_strict_base64_decoding_(false) {}
DataPiece(const int64_t value)82   explicit DataPiece(const int64_t value)
83       : type_(TYPE_INT64), i64_(value), use_strict_base64_decoding_(false) {}
DataPiece(const uint32_t value)84   explicit DataPiece(const uint32_t value)
85       : type_(TYPE_UINT32), u32_(value), use_strict_base64_decoding_(false) {}
DataPiece(const uint64_t value)86   explicit DataPiece(const uint64_t value)
87       : type_(TYPE_UINT64), u64_(value), use_strict_base64_decoding_(false) {}
DataPiece(const double value)88   explicit DataPiece(const double value)
89       : type_(TYPE_DOUBLE),
90         double_(value),
91         use_strict_base64_decoding_(false) {}
DataPiece(const float value)92   explicit DataPiece(const float value)
93       : type_(TYPE_FLOAT), float_(value), use_strict_base64_decoding_(false) {}
DataPiece(const bool value)94   explicit DataPiece(const bool value)
95       : type_(TYPE_BOOL), bool_(value), use_strict_base64_decoding_(false) {}
DataPiece(StringPiece value,bool use_strict_base64_decoding)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.
DataPiece(StringPiece value,bool,bool use_strict_base64_decoding)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 
DataPiece(const DataPiece & r)106   DataPiece(const DataPiece& r) : type_(r.type_) { InternalCopy(r); }
107 
108   DataPiece& operator=(const DataPiece& x) {
109     InternalCopy(x);
110     return *this;
111   }
112 
NullData()113   static DataPiece NullData() { return DataPiece(TYPE_NULL, 0); }
114 
~DataPiece()115   virtual ~DataPiece() {
116   }
117 
118   // Accessors
type()119   Type type() const { return type_; }
120 
use_strict_base64_decoding()121   bool use_strict_base64_decoding() { return use_strict_base64_decoding_; }
122 
str()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.
DataPiece(Type type,int32_t val)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