00001 // bsonobjiterator.h 00002 00003 /* Copyright 2009 10gen Inc. 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 #pragma once 00019 00020 #include <boost/preprocessor/cat.hpp> // like the ## operator but works with __LINE__ 00021 00022 namespace mongo { 00023 00032 class BSONObjIterator { 00033 public: 00036 BSONObjIterator(const BSONObj& jso) { 00037 int sz = jso.objsize(); 00038 if ( sz == 0 ) { 00039 _pos = _theend = 0; 00040 return; 00041 } 00042 _pos = jso.objdata() + 4; 00043 _theend = jso.objdata() + sz; 00044 } 00045 00046 BSONObjIterator( const char * start , const char * end ) { 00047 _pos = start + 4; 00048 _theend = end; 00049 } 00050 00052 bool more() { return _pos < _theend && _pos[0]; } 00053 00055 bool moreWithEOO() { return _pos < _theend; } 00056 00058 BSONElement next( bool checkEnd = false ) { 00059 assert( _pos < _theend ); 00060 BSONElement e( _pos, checkEnd ? (int)(_theend - _pos) : -1 ); 00061 _pos += e.size( checkEnd ? (int)(_theend - _pos) : -1 ); 00062 return e; 00063 } 00064 00065 void operator++() { next(); } 00066 void operator++(int) { next(); } 00067 00068 BSONElement operator*() { 00069 assert( _pos < _theend ); 00070 return BSONElement(_pos, -1); 00071 } 00072 00073 private: 00074 const char* _pos; 00075 const char* _theend; 00076 }; 00077 00078 class BSONObjIteratorSorted { 00079 public: 00080 BSONObjIteratorSorted( const BSONObj& o ); 00081 00082 ~BSONObjIteratorSorted() { 00083 assert( _fields ); 00084 delete[] _fields; 00085 _fields = 0; 00086 } 00087 00088 bool more() { 00089 return _cur < _nfields; 00090 } 00091 00092 BSONElement next() { 00093 assert( _fields ); 00094 if ( _cur < _nfields ) 00095 return BSONElement( _fields[_cur++] ); 00096 return BSONElement(); 00097 } 00098 00099 private: 00100 const char ** _fields; 00101 int _nfields; 00102 int _cur; 00103 }; 00104 00123 #define BSONForEach(e, obj) \ 00124 BSONObjIterator BOOST_PP_CAT(it_,__LINE__)(obj); \ 00125 for ( BSONElement e; \ 00126 (BOOST_PP_CAT(it_,__LINE__).more() ? \ 00127 (e = BOOST_PP_CAT(it_,__LINE__).next(), true) : \ 00128 false) ; \ 00129 /*nothing*/ ) 00130 00131 }