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