diff options
author | George Hazan <george.hazan@gmail.com> | 2012-05-22 11:58:35 +0000 |
---|---|---|
committer | George Hazan <george.hazan@gmail.com> | 2012-05-22 11:58:35 +0000 |
commit | 37f2cac0981177aef291a3411c64c0494187cfbc (patch) | |
tree | 1ae9cbf1f0edb61e993f54599a8fa345dbb83f26 /plugins/json/Source/JSONIterators.cpp | |
parent | ad95ff6459f880b92dd2d00aba08adb22f487fbd (diff) |
JSON plugin
git-svn-id: http://svn.miranda-ng.org/main/trunk@128 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/json/Source/JSONIterators.cpp')
-rw-r--r-- | plugins/json/Source/JSONIterators.cpp | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/plugins/json/Source/JSONIterators.cpp b/plugins/json/Source/JSONIterators.cpp new file mode 100644 index 0000000000..5b140d9b17 --- /dev/null +++ b/plugins/json/Source/JSONIterators.cpp @@ -0,0 +1,214 @@ +#include "JSONNode.h" + +#ifdef JSON_ITERATORS + #ifdef JSON_REF_COUNT + #define JSON_ASSERT_UNIQUE(x) JSON_ASSERT(internal -> refcount == 1, json_string(JSON_TEXT(x)) + JSON_TEXT(" in non single reference")) + #else + #define JSON_ASSERT_UNIQUE(x) (void)0 + #endif + + #ifdef JSON_MUTEX_CALLBACKS + #define JSON_MUTEX_COPY2 ,internal -> mylock + #else + #define JSON_MUTEX_COPY2 + #endif + +JSONNode::json_iterator JSONNode::find(const json_string & name_t){ + JSON_CHECK_INTERNAL(); + JSON_ASSERT(type() == JSON_NODE, JSON_TEXT("finding a non-iteratable node")); + makeUniqueInternal(); + if (JSONNode ** res = internal -> at(name_t)){ + return ptr_to_json_iterator(res); + } + return end(); +} + +#ifdef JSON_CASE_INSENSITIVE_FUNCTIONS + JSONNode::json_iterator JSONNode::find_nocase(const json_string & name_t){ + JSON_CHECK_INTERNAL(); + JSON_ASSERT(type() == JSON_NODE, JSON_TEXT("finding a non-iteratable node")); + makeUniqueInternal(); + if (JSONNode ** res = internal -> at_nocase(name_t)){ + return ptr_to_json_iterator(res); + } + return end(); + } +#endif + +JSONNode::json_iterator JSONNode::erase(json_iterator pos){ + JSON_CHECK_INTERNAL(); + JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node")); + JSON_ASSERT_UNIQUE("erase 1"); + JSON_ASSERT_SAFE(pos < end(), JSON_TEXT("erase out of range"), return end();); + JSON_ASSERT_SAFE(pos >= begin(), JSON_TEXT("erase out of range"), return begin();); + deleteJSONNode(*(json_iterator_ptr(pos))); + internal -> Children.erase(json_iterator_ptr(pos)); + return (empty()) ? end() : pos; +} + +JSONNode::json_iterator JSONNode::erase(json_iterator _start, const json_iterator & _end){ + if (_start == _end) return _start; + JSON_CHECK_INTERNAL(); + JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node")); + JSON_ASSERT_UNIQUE("erase 3"); + JSON_ASSERT_SAFE(_start <= end(), JSON_TEXT("erase out of lo range"), return end();); + JSON_ASSERT_SAFE(_end <= end(), JSON_TEXT("erase out of hi range"), return end();); + JSON_ASSERT_SAFE(_start >= begin(), JSON_TEXT("erase out of lo range"), return begin();); + JSON_ASSERT_SAFE(_end >= begin(), JSON_TEXT("erase out of hi range"), return begin();); + for (JSONNode ** pos = json_iterator_ptr(_start); pos < json_iterator_ptr(_end); ++pos){ + deleteJSONNode(*pos); + } + + internal -> Children.erase(json_iterator_ptr(_start), json_iterator_ptr(_end) - json_iterator_ptr(_start)); + return (empty()) ? end() : _start; +} + +#ifdef JSON_LIBRARY +JSONNode::json_iterator JSONNode::insert(json_iterator pos, JSONNode * x){ +#else +JSONNode::json_iterator JSONNode::insert(json_iterator pos, const JSONNode & x){ +#endif + JSON_CHECK_INTERNAL(); + JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node")); + JSON_ASSERT_UNIQUE("insert 1"); + if (json_iterator_ptr(pos) >= internal -> Children.end()){ + internal -> push_back(x); + return end() - 1; + } + JSON_ASSERT_SAFE(pos >= begin(), JSON_TEXT("insert out of lo range"), return begin();); + #ifdef JSON_LIBRARY + internal -> Children.insert(json_iterator_ptr(pos), x); + #else + internal -> Children.insert(json_iterator_ptr(pos), newJSONNode(x)); + #endif + return pos; +} + +JSONNode::json_iterator JSONNode::insertFFF(json_iterator pos, JSONNode ** const _start, JSONNode ** const _end){ + JSON_CHECK_INTERNAL(); + JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node")); + JSON_ASSERT_UNIQUE("insertFFF"); + JSON_ASSERT_SAFE(pos <= end(), JSON_TEXT("insert out of high range"), return end();); + JSON_ASSERT_SAFE(pos >= begin(), JSON_TEXT("insert out of low range"), return begin();); + const size_t num = _end - _start; + json_auto<JSONNode *> mem(num); + JSONNode ** runner = mem.ptr; + for (JSONNode ** po = _start; po < _end; ++po){ + *runner++ = newJSONNode(*(*po) JSON_MUTEX_COPY2); + } + internal -> Children.insert(json_iterator_ptr(pos), mem.ptr, num); + return pos; +} + +#ifndef JSON_LIBRARY + JSONNode::const_iterator JSONNode::find(const json_string & name_t) const { + JSON_CHECK_INTERNAL(); + JSON_ASSERT(type() == JSON_NODE, JSON_TEXT("finding a non-iteratable node")); + if (JSONNode ** res = internal -> at(name_t)){ + return JSONNode::const_iterator(res); + } + return JSONNode::const_iterator(internal -> end()); + } + + #ifdef JSON_CASE_INSENSITIVE_FUNCTIONS + JSONNode::const_iterator JSONNode::find_nocase(const json_string & name_t) const { + JSON_CHECK_INTERNAL(); + JSON_ASSERT(type() == JSON_NODE, JSON_TEXT("finding a non-iteratable node")); + if (JSONNode ** res = internal -> at_nocase(name_t)){ + return JSONNode::const_iterator(res); + } + return JSONNode::const_iterator(internal -> end()); + } + #endif + + JSONNode::reverse_iterator JSONNode::erase(reverse_iterator pos){ + JSON_CHECK_INTERNAL(); + JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node")); + JSON_ASSERT_UNIQUE("erase 2"); + JSON_ASSERT_SAFE(pos < rend(), JSON_TEXT("erase out of range"), return rend();); + JSON_ASSERT_SAFE(pos >= rbegin(), JSON_TEXT("erase out of range"), return rbegin();); + deleteJSONNode(*(pos.it)); + internal -> Children.erase(pos.it); + return (empty()) ? rend() : pos + 1; + } + + JSONNode::reverse_iterator JSONNode::erase(reverse_iterator _start, const reverse_iterator & _end){ + if (_start == _end) return _start; + JSON_CHECK_INTERNAL(); + JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node")); + JSON_ASSERT_UNIQUE("erase 4"); + JSON_ASSERT_SAFE(_start <= rend(), JSON_TEXT("erase out of lo range"), return rend();); + JSON_ASSERT_SAFE(_end <= rend(), JSON_TEXT("erase out of hi range"), return rend();); + JSON_ASSERT_SAFE(_start >= rbegin(), JSON_TEXT("erase out of lo range"), return rbegin();); + JSON_ASSERT_SAFE(_end >= rbegin(), JSON_TEXT("erase out of hi range"), return rbegin();); + for (JSONNode ** pos = _start.it; pos > _end.it; --pos){ + deleteJSONNode(*pos); + } + const size_t num = _start.it - _end.it; + internal -> Children.erase(_end.it + 1, num, _start.it); + return (empty()) ? rend() : _start + num; + } + + JSONNode::reverse_iterator JSONNode::insert(reverse_iterator pos, const JSONNode & x){ + JSON_CHECK_INTERNAL(); + JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node")); + JSON_ASSERT_UNIQUE("insert 1"); + if (pos.it < internal -> Children.begin()){ + internal -> push_front(x); + return rend() - 1; + } + JSON_ASSERT_SAFE(pos >= rbegin(), JSON_TEXT("insert out of range"), return rbegin();); + internal -> Children.insert(++pos.it, newJSONNode(x), true); + return pos; + } + + JSONNode::reverse_iterator JSONNode::insertRFF(reverse_iterator pos, JSONNode ** const _start, JSONNode ** const _end){ + JSON_CHECK_INTERNAL(); + JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node")); + JSON_ASSERT_UNIQUE("insert RFF"); + JSON_ASSERT_SAFE(pos <= rend(), JSON_TEXT("insert out of range"), return rend();); + JSON_ASSERT_SAFE(pos >= rbegin(), JSON_TEXT("insert out of range"), return rbegin();); + const size_t num = _end - _start; + json_auto<JSONNode *> mem(num); + JSONNode ** runner = mem.ptr + num; + for (JSONNode ** po = _start; po < _end; ++po){ //fill it backwards + *(--runner) = newJSONNode(*(*po) JSON_MUTEX_COPY2); + } + internal -> Children.insert(++pos.it, mem.ptr, num); + return pos - num + 1; + } + + JSONNode::iterator JSONNode::insertFRR(json_iterator pos, JSONNode ** const _start, JSONNode ** const _end){ + JSON_CHECK_INTERNAL(); + JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node")); + JSON_ASSERT_UNIQUE("insert FRR"); + JSON_ASSERT_SAFE(pos <= end(), JSON_TEXT("insert out of range"), return end();); + JSON_ASSERT_SAFE(pos >= begin(), JSON_TEXT("insert out of range"), return begin();); + const size_t num = _start - _end; + json_auto<JSONNode *> mem(num); + JSONNode ** runner = mem.ptr; + for (JSONNode ** po = _start; po > _end; --po){ + *runner++ = newJSONNode(*(*po) JSON_MUTEX_COPY2); + } + internal -> Children.insert(pos.it, mem.ptr, num); + return pos; + } + + JSONNode::reverse_iterator JSONNode::insertRRR(reverse_iterator pos, JSONNode ** const _start, JSONNode ** const _end){ + JSON_CHECK_INTERNAL(); + JSON_ASSERT(type() == JSON_NODE || type() == JSON_ARRAY, JSON_TEXT("erasing a non-iteratable node")); + JSON_ASSERT_UNIQUE("insert RRR"); + JSON_ASSERT_SAFE(pos <= rend(), JSON_TEXT("insert out of range"), return rend();); + JSON_ASSERT_SAFE(pos >= rbegin(), JSON_TEXT("insert out of range"), return rbegin();); + const size_t num = _start - _end; + json_auto<JSONNode *> mem(num); + JSONNode ** runner = mem.ptr; + for (JSONNode ** po = _start; po > _end; --po){ + *runner++ = newJSONNode(*(*po) JSON_MUTEX_COPY2); + } + internal -> Children.insert(++pos.it, mem.ptr, num); + return pos - num + 1; + } +#endif + +#endif |