1// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
2// Distributed under MIT license, or public domain if desired and
3// recognized in your jurisdiction.
4// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
5
6// included by json_value.cpp
7
8namespace Json {
9
10// //////////////////////////////////////////////////////////////////
11// //////////////////////////////////////////////////////////////////
12// //////////////////////////////////////////////////////////////////
13// class ValueIteratorBase
14// //////////////////////////////////////////////////////////////////
15// //////////////////////////////////////////////////////////////////
16// //////////////////////////////////////////////////////////////////
17
18ValueIteratorBase::ValueIteratorBase()
19    : current_(), isNull_(true) {
20}
21
22ValueIteratorBase::ValueIteratorBase(
23    const Value::ObjectValues::iterator& current)
24    : current_(current), isNull_(false) {}
25
26Value& ValueIteratorBase::deref() const {
27  return current_->second;
28}
29
30void ValueIteratorBase::increment() {
31  ++current_;
32}
33
34void ValueIteratorBase::decrement() {
35  --current_;
36}
37
38ValueIteratorBase::difference_type
39ValueIteratorBase::computeDistance(const SelfType& other) const {
40#ifdef JSON_USE_CPPTL_SMALLMAP
41  return other.current_ - current_;
42#else
43  // Iterator for null value are initialized using the default
44  // constructor, which initialize current_ to the default
45  // std::map::iterator. As begin() and end() are two instance
46  // of the default std::map::iterator, they can not be compared.
47  // To allow this, we handle this comparison specifically.
48  if (isNull_ && other.isNull_) {
49    return 0;
50  }
51
52  // Usage of std::distance is not portable (does not compile with Sun Studio 12
53  // RogueWave STL,
54  // which is the one used by default).
55  // Using a portable hand-made version for non random iterator instead:
56  //   return difference_type( std::distance( current_, other.current_ ) );
57  difference_type myDistance = 0;
58  for (Value::ObjectValues::iterator it = current_; it != other.current_;
59       ++it) {
60    ++myDistance;
61  }
62  return myDistance;
63#endif
64}
65
66bool ValueIteratorBase::isEqual(const SelfType& other) const {
67  if (isNull_) {
68    return other.isNull_;
69  }
70  return current_ == other.current_;
71}
72
73void ValueIteratorBase::copy(const SelfType& other) {
74  current_ = other.current_;
75  isNull_ = other.isNull_;
76}
77
78Value ValueIteratorBase::key() const {
79  const Value::CZString czstring = (*current_).first;
80  if (czstring.data()) {
81    if (czstring.isStaticString())
82      return Value(StaticString(czstring.data()));
83    return Value(czstring.data(), czstring.data() + czstring.length());
84  }
85  return Value(czstring.index());
86}
87
88UInt ValueIteratorBase::index() const {
89  const Value::CZString czstring = (*current_).first;
90  if (!czstring.data())
91    return czstring.index();
92  return Value::UInt(-1);
93}
94
95JSONCPP_STRING ValueIteratorBase::name() const {
96  char const* keey;
97  char const* end;
98  keey = memberName(&end);
99  if (!keey) return JSONCPP_STRING();
100  return JSONCPP_STRING(keey, end);
101}
102
103char const* ValueIteratorBase::memberName() const {
104  const char* cname = (*current_).first.data();
105  return cname ? cname : "";
106}
107
108char const* ValueIteratorBase::memberName(char const** end) const {
109  const char* cname = (*current_).first.data();
110  if (!cname) {
111    *end = NULL;
112    return NULL;
113  }
114  *end = cname + (*current_).first.length();
115  return cname;
116}
117
118// //////////////////////////////////////////////////////////////////
119// //////////////////////////////////////////////////////////////////
120// //////////////////////////////////////////////////////////////////
121// class ValueConstIterator
122// //////////////////////////////////////////////////////////////////
123// //////////////////////////////////////////////////////////////////
124// //////////////////////////////////////////////////////////////////
125
126ValueConstIterator::ValueConstIterator() {}
127
128ValueConstIterator::ValueConstIterator(
129    const Value::ObjectValues::iterator& current)
130    : ValueIteratorBase(current) {}
131
132ValueConstIterator::ValueConstIterator(ValueIterator const& other)
133    : ValueIteratorBase(other) {}
134
135ValueConstIterator& ValueConstIterator::
136operator=(const ValueIteratorBase& other) {
137  copy(other);
138  return *this;
139}
140
141// //////////////////////////////////////////////////////////////////
142// //////////////////////////////////////////////////////////////////
143// //////////////////////////////////////////////////////////////////
144// class ValueIterator
145// //////////////////////////////////////////////////////////////////
146// //////////////////////////////////////////////////////////////////
147// //////////////////////////////////////////////////////////////////
148
149ValueIterator::ValueIterator() {}
150
151ValueIterator::ValueIterator(const Value::ObjectValues::iterator& current)
152    : ValueIteratorBase(current) {}
153
154ValueIterator::ValueIterator(const ValueConstIterator& other)
155    : ValueIteratorBase(other) {
156  throwRuntimeError("ConstIterator to Iterator should never be allowed.");
157}
158
159ValueIterator::ValueIterator(const ValueIterator& other)
160    : ValueIteratorBase(other) {}
161
162ValueIterator& ValueIterator::operator=(const SelfType& other) {
163  copy(other);
164  return *this;
165}
166
167} // namespace Json
168