~ps10gel/ubuntu/xenial/trafficserver/6.2.0

« back to all changes in this revision

Viewing changes to lib/tsconfig/TsValue.h

  • Committer: Bazaar Package Importer
  • Author(s): Arno Toell
  • Date: 2011-01-13 11:49:18 UTC
  • Revision ID: james.westby@ubuntu.com-20110113114918-vu422h8dknrgkj15
Tags: upstream-2.1.5-unstable
ImportĀ upstreamĀ versionĀ 2.1.5-unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# if ! defined(TS_CONFIG_VALUE_HEADER)
 
2
# define TS_CONFIG_VALUE_HEADER
 
3
 
 
4
/** @file
 
5
 
 
6
    TS Configuration API definition.
 
7
 
 
8
    Copyright 2010 Network Geographics, Inc.
 
9
 
 
10
    Licensed under the Apache License, Version 2.0 (the "License");
 
11
    you may not use this file except in compliance with the License.
 
12
    You may obtain a copy of the License at
 
13
 
 
14
       http://www.apache.org/licenses/LICENSE-2.0
 
15
 
 
16
    Unless required by applicable law or agreed to in writing, software
 
17
    distributed under the License is distributed on an "AS IS" BASIS,
 
18
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
19
    See the License for the specific language governing permissions and
 
20
    limitations under the License.
 
21
 */
 
22
 
 
23
# include <TsBuffer.h>
 
24
# include <NumericType.h>
 
25
# include <IntrusivePtr.h>
 
26
# include <Errata.h>
 
27
# include <vector>
 
28
 
 
29
namespace ts { namespace config {
 
30
 
 
31
// Forward declares.
 
32
class Value;
 
33
class Path;
 
34
 
 
35
namespace detail {
 
36
  /** Class to provide a "pseudo bool" value.
 
37
      This is used as the return type for the positive logical operator
 
38
      (the converse of @c operator! ). This makes a class directly
 
39
      usable in logical expressions. It is like a pointer but @b not
 
40
      convertible to anything else, and so avoiding any undesirable
 
41
      automatic conversions and the resulting ambiguities.
 
42
  */
 
43
  struct PseudoBool {
 
44
    typedef bool (PseudoBool::*Type)() const; ///< The type itself.
 
45
    bool operator ! () const; ///< A method to use for the @c true value.
 
46
    static Type const TRUE; ///< The @c true equivalent.
 
47
    static Type const FALSE; ///< The @c false equivalent.
 
48
  };
 
49
}
 
50
 
 
51
/// Type of value.
 
52
enum ValueType {
 
53
  VoidValue, ///< No value, invalid.
 
54
  ListValue, ///< List of values.
 
55
  GroupValue, ///< Group of values.
 
56
  StringValue, ///< Text string.
 
57
  IntegerValue, ///< Integer.
 
58
  PathValue, ///< Path.
 
59
  // Update N_VALUE_TYPES if you change the last enum value !!
 
60
};
 
61
/// Number of value types.
 
62
static size_t const N_VALUE_TYPES = PathValue + 1;
 
63
 
 
64
/** A path to a value in a configuration.
 
65
 */
 
66
class Path {
 
67
  friend class Value;
 
68
protected:
 
69
  class ImplType : public IntrusivePtrCounter {
 
70
    friend class Path;
 
71
  public:
 
72
    ImplType(); ///< Constructor.
 
73
  protected:
 
74
    /** Container for path elements.
 
75
        We are subtle with our elements, which can be either a string
 
76
        or a numeric index. By convention, if the pointer in the buffer is
 
77
        @c NULL, then the size is a numeric index. Otherwise it's a name.
 
78
    */
 
79
    typedef std::vector<ConstBuffer> Elements;
 
80
    Elements _elements; ///< Path elements.
 
81
  };
 
82
public:
 
83
  typedef Path self; ///< Self reference type.
 
84
 
 
85
  Path(); ///< Default constructor.
 
86
 
 
87
  /// Append a string tag to the path.
 
88
  self& append(
 
89
    ConstBuffer const& tag ///< Text of tag.
 
90
  );
 
91
  /// Append a numeric index to the path.
 
92
  self& append(
 
93
    size_t idx ///< Index.
 
94
  );
 
95
  /// Reset to default constructed state.
 
96
  self& reset();
 
97
 
 
98
  /// Get the number of elements in this path.
 
99
  size_t count() const;
 
100
 
 
101
  /// Access an element by @a index.
 
102
  ConstBuffer const& operator [] (
 
103
    size_t index ///< Element index.
 
104
  ) const;
 
105
 
 
106
  /** Parser for path text.
 
107
      This is restartable so a path can be parsed in pieces.
 
108
      @internal Sadly, FLEX is just too much overhead to be useful here.
 
109
  */
 
110
  class Parser {
 
111
  public:
 
112
    typedef Parser self; ///< Self reference type.
 
113
 
 
114
    Parser(); ///< Default constructor.
 
115
    /** Construct with input.
 
116
 
 
117
        This default constructs the Parser then calls @c setInput with
 
118
        @a text. It is provided as a convenience as that will be the
 
119
        common use case.
 
120
 
 
121
        @see setInput.
 
122
    */
 
123
    Parser(
 
124
      ConstBuffer const& text ///< Input text.
 
125
    );
 
126
 
 
127
    /** Set the input @a text.
 
128
        Parsing state is reset and the next parsing call will
 
129
        start at the beginning of @a text.
 
130
    */
 
131
    self& setInput(
 
132
      ConstBuffer const& text ///< Input buffer.
 
133
    );
 
134
 
 
135
    /// Parsing result.
 
136
    enum Result {
 
137
      ERROR, ///< Bad input.
 
138
      TAG, ///< Path tag.
 
139
      INDEX, ///< Path index.
 
140
      EOP, ///< End Of Path.
 
141
    };
 
142
 
 
143
    /** Parse the next element in the path.
 
144
 
 
145
        @a cbuff may be @c NULL in which case no data about elements
 
146
        is available.  In general this should be called until @c EOP
 
147
        or @c ERROR is returned, each call returning the next element.
 
148
 
 
149
        @return A parse @c Result.
 
150
        - TAG: A tag was found. The start and length are stored in @a cbuff.
 
151
        - INDEX: An index was found. The value is in @a cbuff._size.
 
152
        - EOP: No more path elements were found. Do not continue parsing.
 
153
        - ERROR: A syntax error was encountered. See the errata for detail. Do not continue parsing.
 
154
    */
 
155
    Rv<Result> parse(
 
156
      ConstBuffer* cbuff = 0 ///< [out] Parsed path element.
 
157
    );
 
158
 
 
159
    /// Check if input is available.
 
160
    bool hasInput() const;
 
161
 
 
162
  protected:
 
163
    ConstBuffer _input; ///< Current input buffer.
 
164
    char const* _c; ///< Next input character.
 
165
  };
 
166
protected:
 
167
  typedef IntrusivePtr<ImplType> ImplPtr; ///< Smart pointer to implementation.
 
168
  ImplPtr _ptr; ///< Our instance.
 
169
  /// Force an implementation instance and return a pointer to it.
 
170
  ImplType* instance();
 
171
};
 
172
 
 
173
namespace detail {
 
174
  /// Null buffer, handy in several places.
 
175
  extern Buffer const NULL_BUFFER;
 
176
  /// Null buffer, handy in several places.
 
177
  extern ConstBuffer const NULL_CONST_BUFFER;
 
178
  /// Index type for value items in the global table.
 
179
  typedef NumericType<size_t, struct ValueIndexTag> ValueIndex;
 
180
  /// Index value that presents NULL (invalid value).
 
181
  static ValueIndex const NULL_VALUE_INDEX = static_cast<ValueIndex::raw_type>(-1);
 
182
  /// Numeric type for configuration generation.
 
183
  typedef NumericType<size_t, struct GenerationTag> Generation;
 
184
 
 
185
  /** Value type properties.
 
186
      These are used as bit masks on elements of an array.
 
187
  */
 
188
  static unsigned int const IS_VALID = 1;
 
189
  static unsigned int const IS_LITERAL = 1<<1;
 
190
  static unsigned int const IS_CONTAINER = 1<<2;
 
191
 
 
192
  /// Value type property table.
 
193
  extern unsigned int const Type_Property[N_VALUE_TYPES];
 
194
 
 
195
  /** A value in the configuration.
 
196
      This is used in a global table so it handles all types of Values.
 
197
      Members that are not used for scalars are designed to be @c NULL
 
198
      pointers in that case.
 
199
  */
 
200
  class ValueItem {
 
201
    // Apparently the C++ standard, 7.3.1.2, states that unqualified
 
202
    // friend classes only considers the current namespace, not any
 
203
    // outer ones. So we have to fully qualify this. Blech.
 
204
    friend class ts::config::Value;
 
205
    friend class ValueTable;
 
206
  public:
 
207
    /// Default constructor.
 
208
    ValueItem();
 
209
    /// Construct empty item of a specific type.
 
210
    ValueItem(ValueType type);
 
211
    /// Get item type.
 
212
    ValueType getType() const;
 
213
  protected:
 
214
    ValueType _type;      ///< Type of value.
 
215
    ValueIndex _parent;   ///< Table index of parent value.
 
216
    ConstBuffer _text;    ///< Text of value (if scalar).
 
217
    ConstBuffer _name;    ///< Local name of value, if available.
 
218
    size_t _local_index;  ///< Index among siblings.
 
219
    int _srcLine;         ///< Source line.
 
220
    int _srcColumn;       ///< Source column.
 
221
 
 
222
    /// Container for children of this item.
 
223
    typedef std::vector<ValueIndex> ChildGroup;
 
224
    /// Child items of this item.
 
225
    ChildGroup _children;
 
226
    /// Path if present.
 
227
    Path _path;
 
228
 
 
229
    // This is for optimizing named access at some point in the future.
 
230
    /// Hold a child item name in a table for fast lookup.
 
231
    struct Name {
 
232
      ConstBuffer _text; ///< Text of name.
 
233
      ValueIndex _index; ///< Index of child.
 
234
    };
 
235
    /// Container for child names.
 
236
    typedef std::vector<Name> NameGroup;
 
237
    /** Child names, if appropriate.
 
238
        This is faulted in when needed, if this value is an aggregate with
 
239
        named children. The list must be sorted on name so that it can be binary
 
240
        searched for performance.
 
241
    */
 
242
    NameGroup _names;
 
243
  };
 
244
 
 
245
  class ValueTable;
 
246
 
 
247
  /** Table of configuration values.
 
248
      This holds all the values for a specific configuration.
 
249
  */
 
250
  class ValueTableImpl : public IntrusivePtrCounter {
 
251
    friend class ValueTable;
 
252
  public:
 
253
    typedef ValueTableImpl self; ///< Self reference type.
 
254
 
 
255
    ValueTableImpl(); ///< Constructor.
 
256
    ~ValueTableImpl(); ///< Destructor.
 
257
  protected:
 
258
    /// Container for value items.
 
259
    typedef std::vector<ValueItem> ItemTable;
 
260
    ItemTable _values; ///< All configuration values.
 
261
    Generation _generation; ///< Generation number of configuration.
 
262
    /// A group of buffers.
 
263
    typedef std::vector<Buffer> BufferGroup;
 
264
    /** Locally allocated buffers.
 
265
        These are freed when this object is destroyed.
 
266
    */
 
267
    BufferGroup _buffers;
 
268
 
 
269
    static ValueItem NULL_ITEM; ///< Null item for invalid access return.
 
270
  };
 
271
 
 
272
  /** Wrapper class for a table of configuration values.
 
273
      @internal Really, this should be merged in to Configuration. The original
 
274
      differences have evolved out of the implementation.
 
275
  */
 
276
  class ValueTable {
 
277
  public:
 
278
    typedef ValueTable self; ///< Self reference type.
 
279
    typedef ValueTableImpl ImplType; ///< Implementation type.
 
280
 
 
281
    /// Table size.
 
282
    /// @return The number of value items in the table.
 
283
    size_t size() const;
 
284
    /// Generation.
 
285
    /// @return The generation number.
 
286
    Generation generation() const;
 
287
 
 
288
    /// Const access by index.
 
289
    /// @return The value item at index @a idx.
 
290
    ValueItem const& operator [] (
 
291
      ValueIndex idx ///< Index of item.
 
292
    ) const;
 
293
    /// Access by index.
 
294
    /// @return The value item at index @a idx.
 
295
    ValueItem& operator [] (
 
296
      ValueIndex idx ///< Index of item.
 
297
    );
 
298
 
 
299
    /// Force the existence of the root item in the table.
 
300
    /// @return @c this object.
 
301
    self& forceRootItem();
 
302
    /** Create a new item (value) with optional @a name
 
303
        The table must contain @a parent. If @a name is omitted, the item
 
304
        has an empty name.
 
305
        @return Index of the new value item.
 
306
    */
 
307
    Rv<ValueIndex> make(
 
308
      ValueIndex parent, ///< Index of parent for item.
 
309
      ValueType type, ///< Type of item.
 
310
      ConstBuffer const& name = NULL_BUFFER ///< Name (may be empty).
 
311
    );
 
312
 
 
313
    /// Test for not table existence.
 
314
    /// @return @c false if the implementation instance exists, @c true if not.
 
315
    bool operator ! () const;
 
316
    /// Test for table existence.
 
317
    /// @return @c true if the implementation instance exists, @c false if not.
 
318
    operator PseudoBool::Type() const;
 
319
    /// Reset to default constructed state.
 
320
    /// @return @c this object.
 
321
    self& reset();
 
322
 
 
323
    /** Allocate a local buffer.
 
324
        This buffer will persist until the implementation instance
 
325
        is destoyed.
 
326
        @return The allocated buffer.
 
327
    */
 
328
    Buffer alloc(size_t n);
 
329
  protected:
 
330
    typedef IntrusivePtr<ImplType> ImplPtr; ///< Smart pointer to implementation instance.
 
331
    ImplPtr _ptr; ///< Implementation instance.
 
332
 
 
333
    /// Force an implementation instance and return a pointer to it.
 
334
    ImplType* instance();
 
335
  };
 
336
} // namespace detail
 
337
 
 
338
/** Container for a configuration.
 
339
    This is a wrapper class that holds a shared reference to a configuration.
 
340
*/
 
341
class Configuration {
 
342
  friend class Value;
 
343
public:
 
344
  typedef Configuration self; ///< Self reference type.
 
345
 
 
346
  /** Check if configuration is (not) valid.
 
347
      @return @c true if this configuration is invalid, @c false otherwise.
 
348
  */
 
349
  bool operator ! () const;
 
350
  /** Check if the configuration is valid.
 
351
      @return The equivalent of @c true if this does @b not contain a value,
 
352
      the equivalent of @c false if it does.
 
353
  */
 
354
  operator detail::PseudoBool::Type () const;
 
355
  /** Get the root @c Value of the configuration.
 
356
      The root is always a group and has no name.
 
357
      @return The root value.
 
358
  */
 
359
  Value getRoot() const;
 
360
 
 
361
  /// Get the number of child values on the root value.
 
362
  size_t childCount() const;
 
363
  /** Root value child access by @a index
 
364
      @return The child or a @c Void value if there is no child with @a name.
 
365
  */
 
366
  Value operator [] (
 
367
    size_t idx ///< Index of child value.
 
368
  ) const;
 
369
  /** Root value child access by @a name.
 
370
      @return The child or a @c Void value if there is no child with @a name.
 
371
  */
 
372
  Value operator [] (
 
373
    ConstBuffer const& name
 
374
  ) const;
 
375
  /** Root value child access by @a name.
 
376
      @return The child or a @c Void value if there is no child with @a name.
 
377
  */
 
378
  Value operator [] (
 
379
    char const* name ///< Null terminated string.
 
380
  ) const;
 
381
 
 
382
  /** Find a value.
 
383
      @return The value if found, an void valid if not.
 
384
  */
 
385
  Value find(
 
386
    char const* path ///< configuration path to value.
 
387
  );
 
388
  /** Load a configuration from a file.
 
389
 
 
390
      @note Check the returned errata for problems during configuration
 
391
      load. It is probably not a good idea to use the configuration in
 
392
      any error are reported.
 
393
      @return A new @c Configuration and errata.
 
394
  */
 
395
  static Rv<self> loadFromPath(
 
396
    char const* path ///< file system path.
 
397
  );
 
398
  /** Allocate a local buffer of size @a n.
 
399
      This buffer will persist until the implementation instance
 
400
      is destroyed.
 
401
      @return The allocated buffer.
 
402
  */
 
403
  Buffer alloc(
 
404
    size_t n ///< requested size of buffer.
 
405
  );
 
406
protected:
 
407
  detail::ValueTable _table; ///< Table of values from the configuration.
 
408
};
 
409
 
 
410
/** This holds a value from the configuration.
 
411
 
 
412
    @internal It is critical that none of the type specific subclasses define any data members
 
413
    so that instances can be freely converted to and from this base class.
 
414
*/
 
415
class Value {
 
416
  friend class Configuration;
 
417
public:
 
418
  typedef Value self; ///< Self reference type.
 
419
  /// Default constructors.
 
420
  /// Creates an @c NULL instance.
 
421
  Value();
 
422
  /// Destructor.
 
423
  ~Value();
 
424
 
 
425
  /// Get the type of value.
 
426
  ValueType getType() const;
 
427
  /// Test if this is a valid value.
 
428
  /// @return @c true if this contains a value, @c false otherwise.
 
429
  bool hasValue() const;
 
430
  /** Operator form of @c hasValue.
 
431
      @see hasValue
 
432
      @return @c true if this does @b not contain a value, @c false if it does.
 
433
  */
 
434
  bool operator ! () const;
 
435
  /** Logical form of @c hasValue for use in logical expressions.
 
436
      @see hasValue
 
437
      @return The equivalent of @c true if this does @b not contain a value,
 
438
      the equivalent of @c false if it does.
 
439
  */
 
440
  operator detail::PseudoBool::Type () const;
 
441
 
 
442
  /** Get the value text.
 
443
      @return The text in the configuration file for this item if the item
 
444
      is a scalar, an empty buffer otherwise.
 
445
  */
 
446
  ConstBuffer const& getText() const;
 
447
  /// Set the @a text for this value.
 
448
  self& setText(
 
449
    ConstBuffer const& text
 
450
  );
 
451
 
 
452
  /** Get local name.
 
453
      This gets the local name of the value. That is the name by which it
 
454
      is known to its parent container.
 
455
 
 
456
      @internal Only works for groups now. It should be made to work
 
457
      for lists. This would require allocating strings for each index,
 
458
      which should be shared across values. For instance, all values
 
459
      at index 1 should return the same string "1", not separately
 
460
      allocated for each value.
 
461
   */
 
462
  ConstBuffer const& getName() const;
 
463
  /** Get local index.
 
464
      This gets the local index for the value. This is the index which,
 
465
      if used on the parent, would yield this value.
 
466
      @return The local index.
 
467
   */
 
468
  size_t getIndex() const;
 
469
 
 
470
  /// Test for a literal value.
 
471
  /// @return @c true if the value is a literal,
 
472
  /// @c false if it is a container or invalid.
 
473
  bool isLiteral() const;
 
474
  /// Test for value container.
 
475
  /// @return @c true if the value is a container (can have child values),
 
476
  /// @c false otherwise.
 
477
  bool isContainer() const;
 
478
  /// Get the parent value.
 
479
  Value getParent() const;
 
480
  /// Test if this is the root value for the configuration.
 
481
  bool isRoot() const;
 
482
 
 
483
  /// Get the number of child values.
 
484
  size_t childCount() const;
 
485
  /** Child access by @a index
 
486
      @return The child or a @c Void value if there is no child with @a name.
 
487
  */
 
488
  Value operator [] (
 
489
    size_t idx ///< Index of child value.
 
490
  ) const;
 
491
  /** Child access by @a name.
 
492
      @return The child or a @c Void value if there is no child with @a name.
 
493
  */
 
494
  Value operator [] (
 
495
    ConstBuffer const& name
 
496
  ) const;
 
497
  /** Child access by @a name.
 
498
      @return The child or a @c Void value if there is no child with @a name.
 
499
  */
 
500
  Value operator [] (
 
501
    char const* name ///< Null terminated string.
 
502
  ) const;
 
503
 
 
504
  /** @name Creating child values.
 
505
 
 
506
      These methods all take an optional @a name argument. This is
 
507
      required if @c this is a @c Group and ignored if @c this is a @c
 
508
      List.
 
509
 
 
510
      These methods will fail if
 
511
      - @c this is not a container.
 
512
      - @c this is a @c Group and no @a name is provided.
 
513
 
 
514
      @note Currently for groups, duplicate names are not
 
515
      detected. The duplicates will be inaccessible by name but can
 
516
      still be found by index. This is a problem but I am still
 
517
      pondering the appropriate solution.
 
518
 
 
519
      @see isContainer
 
520
      @return The new value, or an invalid value plus errata on failure.
 
521
 
 
522
      @internal I original had this as a single method, but changed to
 
523
      separate per type.  Overall less ugly because we can get the
 
524
      arguments more useful.
 
525
  */
 
526
  //@{
 
527
  /// Create a @c String value.
 
528
  Rv<Value> makeString(
 
529
    ConstBuffer const& text, ///< String content.
 
530
    ConstBuffer const& name = detail::NULL_BUFFER///< Optional name of value.
 
531
  );
 
532
  /// Create an @c Integer value.
 
533
  Rv<Value> makeInteger(
 
534
    ConstBuffer const& text, ///< Text of number.
 
535
    ConstBuffer const& name = detail::NULL_BUFFER///< Optional name of value.
 
536
  );
 
537
  /// Create a @c Group value.
 
538
  Rv<Value> makeGroup(
 
539
    ConstBuffer const& name = detail::NULL_BUFFER///< Optional name of value.
 
540
  );
 
541
  /// Create a @c List value.
 
542
  Rv<Value> makeList(
 
543
    ConstBuffer const& name = detail::NULL_BUFFER///< Optional name of value.
 
544
  );
 
545
  /// Create a @c Path value.
 
546
  Rv<Value> makePath(
 
547
    Path const& path, ///< Path.
 
548
    ConstBuffer const& name = detail::NULL_BUFFER///< Optional name of value.
 
549
  );
 
550
  /// Create a child by type.
 
551
  /// Client must fill in any other required elements.
 
552
  Rv<Value> makeChild(
 
553
    ValueType type, ///< Type of child.
 
554
    ConstBuffer const& name = detail::NULL_BUFFER///< Optional name of value.
 
555
  );
 
556
  //@}
 
557
 
 
558
  /** Find a value.
 
559
      @return The value if found, an void valid if not.
 
560
  */
 
561
  Value find(
 
562
    ConstBuffer const& path ///< Path relative to this value.
 
563
  );
 
564
  /** Find a value.
 
565
      @return The value if found, an void valid if not.
 
566
  */
 
567
  Value find(
 
568
    char const* path ///< Path relative to this value.
 
569
  );
 
570
  /** Find a value using a precondensed path.
 
571
      @return The value if found, an void valid if not.
 
572
  */
 
573
  Value find(
 
574
    Path const& path ///< Path relative to this value.
 
575
  );
 
576
 
 
577
  /** Reset to default constructed state.
 
578
      @note This wrapper is reset, the value in the configuration is unchanged.
 
579
      @return @c this object.
 
580
  */
 
581
  self& reset();
 
582
 
 
583
  /// Set source line.
 
584
  /// @return @c this object.
 
585
  self& setSourceLine(
 
586
    int line ///< Line in source stream.
 
587
  );
 
588
  /// Set source column.
 
589
  /// @return @c this object.
 
590
  self& setSourceColumn(
 
591
    int col ///< Column in source stream.
 
592
  );
 
593
  /// Set the source location.
 
594
  self& setSource(
 
595
    int line, ///< Line in source stream.
 
596
    int col ///< Column in source stream.
 
597
  );
 
598
  /// Get source line.
 
599
  /// @return The line in the source stream for this value.
 
600
  int getSourceLine() const;
 
601
  /// Get source column.
 
602
  /// @return The column in the source stream for this value.
 
603
  int getSourceColumn() const;
 
604
 
 
605
protected:
 
606
  // Note: We store an index and not a pointer because a pointer will go stale
 
607
  // if any items are added or removed from the underlying table.
 
608
  // Also, by storing the configuration, we hold it in memory as long as a Value
 
609
  // is in client hands.
 
610
  Configuration _config; ///< The configuration for this value.
 
611
  detail::ValueIndex _vidx; ///< Index of item.
 
612
 
 
613
  static Buffer const NULL_BUFFER; ///< Empty buffer to return on method failures.
 
614
 
 
615
  /// Construct from raw data.
 
616
  Value(
 
617
    Configuration cfg, ///< Source configuration.
 
618
    detail::ValueIndex vidx  ///< Index of value.
 
619
  );
 
620
 
 
621
  /** Get raw item pointer.
 
622
      @note This pointer is unstable and must be recomputed on each method invocation.
 
623
      @return The item pointer or @c NULL if this value is invalid.
 
624
  */
 
625
  detail::ValueItem* item();
 
626
  /** Get constant raw item pointer.
 
627
      @note This pointer is unstable and must be recomputed on each method invocation.
 
628
      @return The item pointer or @c NULL if this value is invalid.
 
629
  */
 
630
  detail::ValueItem const* item() const;
 
631
};
 
632
 
 
633
// Inline methods.
 
634
namespace detail {
 
635
  inline bool ValueTable::operator ! () const { return ! _ptr; }
 
636
  inline ValueTable::operator PseudoBool::Type () const { return _ptr ? PseudoBool::TRUE : PseudoBool::FALSE; }
 
637
  inline size_t ValueTable::size() const { return _ptr ? _ptr->_values.size() : 0; }
 
638
  inline Generation ValueTable::generation() const { return _ptr ? _ptr->_generation : Generation(0); }
 
639
  inline ValueItem const& ValueTable::operator [] (ValueIndex idx) const { return const_cast<self*>(this)->operator [] (idx); }
 
640
  inline ValueTable& ValueTable::reset() { _ptr = 0; return *this; }
 
641
 
 
642
  inline ValueItem::ValueItem() : _type(VoidValue), _text(0,0), _name(0,0) {}
 
643
  inline ValueItem::ValueItem(ValueType type) : _type(type), _text(0,0), _name(0,0) {}
 
644
  inline ValueType ValueItem::getType() const { return _type; }
 
645
}
 
646
 
 
647
inline Value::~Value() { }
 
648
inline Value::Value() : _vidx(detail::NULL_VALUE_INDEX) {}
 
649
inline Value::Value(Configuration cfg, detail::ValueIndex vidx) : _config(cfg), _vidx(vidx) { }
 
650
inline bool Value::hasValue() const { return _config && _vidx != detail::NULL_VALUE_INDEX; }
 
651
inline Value::operator detail::PseudoBool::Type () const { return this->hasValue() ? detail::PseudoBool::TRUE : detail::PseudoBool::FALSE; }
 
652
inline bool Value::operator ! () const { return ! this->hasValue(); }
 
653
inline ValueType Value::getType() const { return this->hasValue() ? _config._table[_vidx]._type : VoidValue; }
 
654
inline ConstBuffer const& Value::getText() const {
 
655
  return this->hasValue() ? _config._table[_vidx]._text : detail::NULL_CONST_BUFFER;
 
656
}
 
657
inline Value& Value::setText(ConstBuffer const& text) {
 
658
  detail::ValueItem* item = this->item();
 
659
  if (item) item->_text = text;
 
660
  return *this;
 
661
}
 
662
inline ConstBuffer const& Value::getName() const {
 
663
  detail::ValueItem const* item = this->item();
 
664
  return item ? item->_name : detail::NULL_CONST_BUFFER;
 
665
}
 
666
inline size_t Value::getIndex() const {
 
667
  detail::ValueItem const* item = this->item();
 
668
  return item ? item->_local_index : 0;
 
669
}
 
670
  
 
671
inline bool Value::isLiteral() const { return 0 != (detail::IS_LITERAL & detail::Type_Property[this->getType()]); }
 
672
inline bool Value::isContainer() const { return 0 != (detail::IS_CONTAINER & detail::Type_Property[this->getType()]); }
 
673
inline Value Value::getParent() const { return this->hasValue() ? Value(_config, _config._table[_vidx]._parent) : Value(); }
 
674
inline bool Value::isRoot() const { return this->hasValue() && _vidx == 0; }
 
675
inline Value& Value::reset() { _config = Configuration(); _vidx = detail::NULL_VALUE_INDEX; return *this; }
 
676
inline detail::ValueItem* Value::item() { return this->hasValue() ? &(_config._table[_vidx]) : 0; }
 
677
inline detail::ValueItem const* Value::item() const { return const_cast<self*>(this)->item(); }
 
678
inline Value Value::operator [] (char const* name) const { return (*this)[ConstBuffer(name, strlen(name))]; }
 
679
inline size_t Value::childCount() const {
 
680
  detail::ValueItem const* item = this->item();
 
681
  return item ? item->_children.size() : 0;
 
682
}
 
683
inline Value Value::find(char const* path) { return this->find(ConstBuffer(path, strlen(path))); }
 
684
inline int Value::getSourceLine() const {
 
685
  detail::ValueItem const* item = this->item();
 
686
  return item ? item->_srcLine : 0;
 
687
}
 
688
inline int Value::getSourceColumn() const {
 
689
  detail::ValueItem const* item = this->item();
 
690
  return item ? item->_srcColumn : 0;
 
691
}
 
692
inline Value& Value::setSourceLine(int line) {
 
693
  detail::ValueItem* item = this->item();
 
694
  if (item) item->_srcLine = line;
 
695
  return *this;
 
696
}
 
697
inline Value& Value::setSourceColumn(int col) {
 
698
  detail::ValueItem* item = this->item();
 
699
  if (item) item->_srcColumn = col;
 
700
  return *this;
 
701
}
 
702
inline Value& Value::setSource(int line, int col) {
 
703
  detail::ValueItem* item = this->item();
 
704
  if (item) {
 
705
    item->_srcLine = line;
 
706
    item->_srcColumn = col;
 
707
  }
 
708
  return *this;
 
709
}
 
710
 
 
711
inline Path::ImplType::ImplType() { }
 
712
 
 
713
inline Path::Path() { }
 
714
inline Path::ImplType* Path::instance() { if (!_ptr) _ptr = new ImplType; return _ptr.get(); }
 
715
inline Path& Path::append(ConstBuffer const& tag) { this->instance()->_elements.push_back(tag); return *this; }
 
716
inline Path& Path::append(size_t index) { this->instance()->_elements.push_back(ConstBuffer(0, index)); return *this; }
 
717
inline size_t Path::count() const { return _ptr ? _ptr->_elements.size() : 0; }
 
718
inline ConstBuffer const& Path::operator [] (size_t idx) const { return _ptr ? _ptr->_elements[idx] : detail::NULL_CONST_BUFFER; }
 
719
 
 
720
inline Path::Parser::Parser() : _input(0,0), _c(0) { }
 
721
inline Path::Parser::Parser( ConstBuffer const& text ) : _input(text), _c(text._ptr) { }
 
722
inline bool Path::Parser::hasInput() const { return _input._ptr && _input._ptr + _input._size > _c; }
 
723
 
 
724
inline bool Configuration::operator ! () const { return ! _table; }
 
725
inline Configuration::operator detail::PseudoBool::Type() const { return _table.operator detail::PseudoBool::Type(); }
 
726
inline Value Configuration::find( char const* path ) { return this->getRoot().find(path); }
 
727
inline Buffer Configuration::alloc(size_t n) { return _table.alloc(n);  }
 
728
inline size_t Configuration::childCount() const { return this->getRoot().childCount(); }
 
729
inline Value Configuration::operator [] (size_t idx) const { return (this->getRoot())[idx]; }
 
730
inline Value Configuration::operator [] ( ConstBuffer const& name ) const { return (this->getRoot())[name]; }
 
731
inline Value Configuration::operator [] ( char const* name ) const { return (this->getRoot())[name]; }
 
732
 
 
733
}} // namespace ts::config
 
734
 
 
735
# endif