2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2014 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_CONFIG_HDF_H_
18 #define incl_HPHP_CONFIG_HDF_H_
25 #include <boost/container/flat_set.hpp>
27 #include "hphp/util/exception.h"
28 #include "hphp/util/hash-map-typedefs.h"
29 #include "hphp/util/functional.h"
30 #include "hphp/neo/neo_hdf.h"
33 ///////////////////////////////////////////////////////////////////////////////
36 * A super-fast hierarchical data structure, wrapped around ClearSilver's HDF
37 * data format: http://www.clearsilver.net/docs/man_hdf.hdf
39 * HDF is a serialization format that emphasizes cleanness and simplicity when
40 * representing hierarchical data. It's designed to be fast parsing and
41 * accessing. One example is,
45 * IP.1 = 192.168.100.100
46 * IP.2 = 192.168.100.101
49 class HdfRaw
; // reference counting HDF* raw pointer, implmented in .cpp file
55 Hdf(); // create an empty HDF tree
56 explicit Hdf(const char *filename
); // open the specified file
57 explicit Hdf(const std::string
&filename
); // open the specified file
58 explicit Hdf(const Hdf
*hdf
, const char *name
); // constructing a sub-node
59 Hdf(const Hdf
&hdf
); // make a copy by reference
60 explicit Hdf(HDF
*hdf
); // attaching a raw pointer
64 * Close current and make a copy of the specified.
66 void assign(const Hdf
&hdf
);
69 * Copy specified without closing current.
71 void copy(const Hdf
&hdf
);
74 * Either close current file and open a new file, or append a file's content.
76 void open(const char *filename
);
77 void open(const std::string
&filename
) { open(filename
.c_str());}
78 void append(const char *filename
);
79 void append(const std::string
&filename
) { append(filename
.c_str());}
83 * Get a list of node names that are visited or not visited. Great for lint
84 * purpose, finding nodes that are invalid for configurations, for example.
85 * Use exclusion to skip checking certain node names. For example,
87 * LintExcludePatterns {
88 * * = FutureConfigName
94 * The pattern is NOT a full regex, but only the simple 3 as above.
96 * When visited = true, return a list of nodes that are visited.
98 void lint(std::vector
<std::string
> &names
,
99 const char *excludePatternNode
= "LintExcludePatterns",
100 bool visited
= false);
101 void setVisited(bool visited
= true);
104 * Read or dump this entire tree in HDF format.
106 void fromString(const char *input
);
107 const char *toString() const;
108 void write(const char *filename
) const;
109 void write(const std::string
&filename
) const { write(filename
.c_str());}
112 * Get this node's value. When node is not present or node's value is not
113 * parsable, return default value "defValue" instead.
115 * Boolean "false" is defined as one of these values and anything else is
116 * "true" (except absent node will take default value):
118 * 2. 0 (note: string "00" or longer are not "false").
119 * 3. string "false", "no" or "off" case-insensitively
121 * Numbers can also be specified in hex (0x prefix) or octal (0 prefix). For
122 * any values that are not entirely parsable to be a number, it will return
123 * default value instead.
125 bool getBool(bool defValue
= false) const;
126 const char *get(const char *defValue
= nullptr) const;
127 std::string
getString(const std::string
&defValue
= "") const;
128 char getByte (char defValue
= 0) const;
129 unsigned char getUByte (unsigned char defValue
= 0) const;
130 int16_t getInt16 (int16_t defValue
= 0) const;
131 uint16_t getUInt16(uint16_t defValue
= 0) const;
132 int32_t getInt32 (int32_t defValue
= 0) const;
133 uint32_t getUInt32(uint32_t defValue
= 0) const;
134 int64_t getInt64 (int64_t defValue
= 0) const;
135 uint64_t getUInt64(uint64_t defValue
= 0) const;
136 double getDouble(double defValue
= 0) const;
138 void get(std::vector
<std::string
> &values
) const;
139 void get(std::set
<std::string
> &values
) const;
140 void get(std::set
<std::string
, stdltistr
> &values
) const;
141 void get(boost::container::flat_set
<std::string
> &values
) const;
142 void get(std::map
<std::string
, std::string
> &values
) const;
143 void get(hphp_string_imap
<std::string
> &values
) const;
146 * Set this node's value.
148 void set(const char *value
);
149 void set(const std::string
&value
) { set(value
.c_str());}
150 void set(bool value
) { set(value
? "1" : "0");}
151 void set(char value
) { set((int64_t)value
);}
152 void set(unsigned char value
) { set((uint64_t)value
);}
153 void set(int16_t value
) { set((int64_t)value
);}
154 void set(uint16_t value
) { set((uint64_t)value
);}
155 void set(int32_t value
) { set((int64_t)value
);}
156 void set(uint32_t value
) { set((uint64_t)value
);}
157 void set(int64_t value
);
158 void set(uint64_t value
);
159 void set(double value
);
161 Hdf
&operator=(const char *value
) { set(value
); return *this;}
162 Hdf
&operator=(const std::string
&value
) { set(value
); return *this;}
163 Hdf
&operator=(bool value
) { set(value
); return *this;}
164 Hdf
&operator=(char value
) { set(value
); return *this;}
165 Hdf
&operator=(unsigned char value
) { set(value
); return *this;}
166 Hdf
&operator=(int16_t value
) { set(value
); return *this;}
167 Hdf
&operator=(uint16_t value
) { set(value
); return *this;}
168 Hdf
&operator=(int32_t value
) { set(value
); return *this;}
169 Hdf
&operator=(uint32_t value
) { set(value
); return *this;}
170 Hdf
&operator=(int64_t value
) { set(value
); return *this;}
171 Hdf
&operator=(uint64_t value
) { set(value
); return *this;}
172 Hdf
&operator=(double value
) { set(value
); return *this;}
173 Hdf
&operator=(const Hdf
&hdf
);
176 * Get this node's fully qualified path or just one-level node name.
178 std::string
getFullPath() const;
179 std::string
getName(bool markVisited
= true) const;
182 * Get this node's parent.
184 const Hdf
parent() const;
190 const Hdf
operator[](int name
) const;
191 const Hdf
operator[](const char *name
) const;
192 const Hdf
operator[](const std::string
&name
) const;
193 Hdf
operator[](int name
);
194 Hdf
operator[](const char *name
);
195 Hdf
operator[](const std::string
&name
);
198 * Note that this is different than getting a boolean value. If "name" is
199 * present, testing whether a subnode exists. Otherwise, testing myself is
203 bool exists(int name
) const;
204 bool exists(const char *name
) const;
205 bool exists(const std::string
&name
) const;
208 * Note that this is NOT testing existence, but reading a boolean value.
210 bool operator!() const { return !getBool();}
213 * Removes a sub-node from parent.
215 void remove(int name
) const;
216 void remove(const char *name
) const;
217 void remove(const std::string
&name
) const;
220 * Iterations. For example,
222 * for (Hdf hdf = parent.firstChild(); hdf.exists(); hdf = hdf.next()) {
225 * Please use "hdf.exists()" for testing than casting it to boolean.
227 Hdf
firstChild(bool markVisited
= true) const;
228 Hdf
next(bool markVisited
= true) const;
233 int compare(const char *v
) const;
234 int compare(const std::string
&v
) const;
235 int compare(char v
) const;
236 int compare(unsigned char v
) const;
237 int compare(int16_t v
) const;
238 int compare(uint16_t v
) const;
239 int compare(int32_t v
) const;
240 int compare(uint32_t v
) const;
241 int compare(int64_t v
) const;
242 int compare(uint64_t v
) const;
243 int compare(double v
) const;
245 bool operator==(const char *v
) const { return compare(v
) == 0;}
246 bool operator!=(const char *v
) const { return compare(v
) != 0;}
247 bool operator>=(const char *v
) const { return compare(v
) >= 0;}
248 bool operator<=(const char *v
) const { return compare(v
) <= 0;}
249 bool operator> (const char *v
) const { return compare(v
) > 0;}
250 bool operator< (const char *v
) const { return compare(v
) < 0;}
252 bool operator==(const std::string
&v
) const { return compare(v
) == 0;}
253 bool operator!=(const std::string
&v
) const { return compare(v
) != 0;}
254 bool operator>=(const std::string
&v
) const { return compare(v
) >= 0;}
255 bool operator<=(const std::string
&v
) const { return compare(v
) <= 0;}
256 bool operator> (const std::string
&v
) const { return compare(v
) > 0;}
257 bool operator< (const std::string
&v
) const { return compare(v
) < 0;}
259 bool operator==(char v
) const { return compare(v
) == 0;}
260 bool operator!=(char v
) const { return compare(v
) != 0;}
261 bool operator>=(char v
) const { return compare(v
) >= 0;}
262 bool operator<=(char v
) const { return compare(v
) <= 0;}
263 bool operator> (char v
) const { return compare(v
) > 0;}
264 bool operator< (char v
) const { return compare(v
) < 0;}
266 bool operator==(unsigned char v
) const { return compare(v
) == 0;}
267 bool operator!=(unsigned char v
) const { return compare(v
) != 0;}
268 bool operator>=(unsigned char v
) const { return compare(v
) >= 0;}
269 bool operator<=(unsigned char v
) const { return compare(v
) <= 0;}
270 bool operator> (unsigned char v
) const { return compare(v
) > 0;}
271 bool operator< (unsigned char v
) const { return compare(v
) < 0;}
273 bool operator==(int16_t v
) const { return compare(v
) == 0;}
274 bool operator!=(int16_t v
) const { return compare(v
) != 0;}
275 bool operator>=(int16_t v
) const { return compare(v
) >= 0;}
276 bool operator<=(int16_t v
) const { return compare(v
) <= 0;}
277 bool operator> (int16_t v
) const { return compare(v
) > 0;}
278 bool operator< (int16_t v
) const { return compare(v
) < 0;}
280 bool operator==(uint16_t v
) const { return compare(v
) == 0;}
281 bool operator!=(uint16_t v
) const { return compare(v
) != 0;}
282 bool operator>=(uint16_t v
) const { return compare(v
) >= 0;}
283 bool operator<=(uint16_t v
) const { return compare(v
) <= 0;}
284 bool operator> (uint16_t v
) const { return compare(v
) > 0;}
285 bool operator< (uint16_t v
) const { return compare(v
) < 0;}
287 bool operator==(int32_t v
) const { return compare(v
) == 0;}
288 bool operator!=(int32_t v
) const { return compare(v
) != 0;}
289 bool operator>=(int32_t v
) const { return compare(v
) >= 0;}
290 bool operator<=(int32_t v
) const { return compare(v
) <= 0;}
291 bool operator> (int32_t v
) const { return compare(v
) > 0;}
292 bool operator< (int32_t v
) const { return compare(v
) < 0;}
294 bool operator==(uint32_t v
) const { return compare(v
) == 0;}
295 bool operator!=(uint32_t v
) const { return compare(v
) != 0;}
296 bool operator>=(uint32_t v
) const { return compare(v
) >= 0;}
297 bool operator<=(uint32_t v
) const { return compare(v
) <= 0;}
298 bool operator> (uint32_t v
) const { return compare(v
) > 0;}
299 bool operator< (uint32_t v
) const { return compare(v
) < 0;}
301 bool operator==(int64_t v
) const { return compare(v
) == 0;}
302 bool operator!=(int64_t v
) const { return compare(v
) != 0;}
303 bool operator>=(int64_t v
) const { return compare(v
) >= 0;}
304 bool operator<=(int64_t v
) const { return compare(v
) <= 0;}
305 bool operator> (int64_t v
) const { return compare(v
) > 0;}
306 bool operator< (int64_t v
) const { return compare(v
) < 0;}
308 bool operator==(uint64_t v
) const { return compare(v
) == 0;}
309 bool operator!=(uint64_t v
) const { return compare(v
) != 0;}
310 bool operator>=(uint64_t v
) const { return compare(v
) >= 0;}
311 bool operator<=(uint64_t v
) const { return compare(v
) <= 0;}
312 bool operator> (uint64_t v
) const { return compare(v
) > 0;}
313 bool operator< (uint64_t v
) const { return compare(v
) < 0;}
315 bool operator==(double v
) const { return compare(v
) == 0;}
316 bool operator!=(double v
) const { return compare(v
) != 0;}
317 bool operator>=(double v
) const { return compare(v
) >= 0;}
318 bool operator<=(double v
) const { return compare(v
) <= 0;}
319 bool operator> (double v
) const { return compare(v
) > 0;}
320 bool operator< (double v
) const { return compare(v
) < 0;}
323 * Throw if there is an error from ClearSilver library.
325 static void CheckNeoError(NEOERR
*err
);
328 mutable HDF
*m_hdf
; // cached HDF pointer
329 HdfRaw
*m_rawp
; // raw pointer
330 std::string m_path
; // parent path
331 std::string m_name
; // my name
332 mutable char *m_dump
; // entire tree dump in HDF format
335 * There are only two different "modes" of an Hdf object: hdf_ being null or
336 * non-null. First case is when we proactively constructed an Hdf object by
337 * either opening a file or starting from scratch by calling Hdf(). Second
338 * case is when we attach a raw HDF*, almost exclusively used by iterations.
343 * Parse value as a signed integer and check to make sure it's within
344 * [-maxValue-1, maxValue]. If not, throw an HdfDataTypeException
345 * with specified type string. If node is absent, return default value.
347 int64_t getInt(int64_t defValue
, const char *type
, int64_t maxValue
) const;
350 * Parse value as a unsigned integer and check against mask to make sure
351 * it's in the specified range. If not, throw an HdfDataTypeException
352 * with specified type string. If node is absent, return default value.
354 uint64_t getUInt(uint64_t defValue
, const char *type
, uint64_t mask
) const;
357 * Implementation of parent() calls.
359 Hdf
parentImpl() const;
361 bool lintImpl(std::vector
<std::string
> &names
,
362 const std::vector
<std::string
> &excludes
, bool visited
);
366 * Base class of all exceptions Hdf class might throw.
368 class HdfException
: public Exception
{
370 HdfException(const char *fmt
, ...) ATTRIBUTE_PRINTF(2,3);
371 EXCEPTION_COMMON_IMPL(HdfException
);
375 * Trying to get a node's value, but it's not in the specified type.
377 class HdfDataTypeException
: public HdfException
{
379 HdfDataTypeException(const Hdf
*hdf
, const char *type
, const char *value
)
380 : HdfException("HDF node [%s]'s value \"%s\" is not %s",
381 hdf
->getFullPath().c_str(), value
, type
) {
383 EXCEPTION_COMMON_IMPL(HdfDataTypeException
);
387 * A node's value is not expected.
389 class HdfDataValueException
: public HdfException
{
391 explicit HdfDataValueException(const Hdf
*hdf
, const char *expected
= "")
392 : HdfException("HDF node [%s]'s value \"%s\" is not expected %s",
393 hdf
->getFullPath().c_str(), hdf
->get(""), expected
) {
395 EXCEPTION_COMMON_IMPL(HdfDataValueException
);
399 * Calling a function in wrong context.
401 class HdfInvalidOperation
: public HdfException
{
403 explicit HdfInvalidOperation(const char *operation
)
404 : HdfException("Invalid operation: %s", operation
) {
406 EXCEPTION_COMMON_IMPL(HdfInvalidOperation
);
409 ///////////////////////////////////////////////////////////////////////////////
412 #endif // incl_HPHP_CONFIG_HDF_H_