/*=============================================================================
	CAIOIterator.h

	$Log: CAIOIterator.h,v $
	Revision 1.4  2005/01/12 19:32:34  jcm10
	make sure IO_OBJECT_NULL is always defined
	
	Revision 1.3  2004/12/14 23:58:39  jcm10
	use IO_OBJECT_NULL instead of NULL
	
	Revision 1.2  2004/04/13 07:06:52  jcm10
	fix compiler warnings
	
	Revision 1.1  2003/10/09 22:03:03  jcm10
	first checked in
	
	Revision 0.0  Thu Oct 02 2003 21:31:36 US/Pacific  moorf
	Created
		
	$NoKeywords: $
=============================================================================*/
#if !defined(__CAIOIterator_h__)
#define __CAIOIterator_h__

//=============================================================================
//	Includes
//=============================================================================

//	System Includes
#include <IOKit/IOKitLib.h>

#if !defined(IO_OBJECT_NULL)
	#define	IO_OBJECT_NULL	((io_object_t) 0)
#endif

//=============================================================================
//	CAIOIterator
//=============================================================================

class CAIOIterator
{

//	Construction/Destruction
public:
					CAIOIterator() : mIOIterator(IO_OBJECT_NULL), mWillRelease(true), mLastKernelError(0) {}
					CAIOIterator(io_iterator_t inIOIterator, bool inWillRelease = true) : mIOIterator(inIOIterator), mWillRelease(inWillRelease), mLastKernelError(0) {}
					CAIOIterator(io_object_t inParent, const io_name_t inPlane) : mIOIterator(IO_OBJECT_NULL), mWillRelease(true), mLastKernelError(0) { mLastKernelError = IORegistryEntryGetChildIterator(inParent, inPlane, &mIOIterator); }
					CAIOIterator(io_object_t inChild, const io_name_t inPlane, bool /*inGetParent*/) : mIOIterator(IO_OBJECT_NULL), mWillRelease(true), mLastKernelError(0) { mLastKernelError = IORegistryEntryGetParentIterator(inChild, inPlane, &mIOIterator); }
					~CAIOIterator() { Release(); }
					CAIOIterator(const CAIOIterator& inIterator) : mIOIterator(inIterator.mIOIterator), mWillRelease(inIterator.mWillRelease), mLastKernelError(0) { Retain(); }
	CAIOIterator&   operator=(const CAIOIterator& inIterator) { Release(); mIOIterator = inIterator.mIOIterator; mWillRelease = inIterator.mWillRelease; Retain(); mLastKernelError = 0; return *this; }
	CAIOIterator&   operator=(io_iterator_t inIOIterator) { Release(); mIOIterator = inIOIterator; mWillRelease = true; return *this; }

private:
	void			Retain() { if(mWillRelease && (mIOIterator != IO_OBJECT_NULL)) { IOObjectRetain(mIOIterator); } }
	void			Release() { if(mWillRelease && (mIOIterator != IO_OBJECT_NULL)) { IOObjectRelease(mIOIterator); mIOIterator = IO_OBJECT_NULL; } }
	
	io_iterator_t   mIOIterator;
	bool			mWillRelease;
	kern_return_t   mLastKernelError;

//	Operations
public:
	void			AllowRelease() { mWillRelease = true; }
	void			DontAllowRelease() { mWillRelease = false; }
	bool			IsValid() const { return mIOIterator != IO_OBJECT_NULL; }
	bool			IsEqual(io_iterator_t inIOIterator) { return IOObjectIsEqualTo(inIOIterator, mIOIterator); }
	io_object_t		Next() { return IOIteratorNext(mIOIterator); }

//	Value Access
public:
	io_iterator_t   GetIOIterator() const { return mIOIterator; }
	io_iterator_t   CopyIOIterator() const { if(mIOIterator != IO_OBJECT_NULL) { IOObjectRetain(mIOIterator); } return mIOIterator; }
	kern_return_t   GetLastKernelError() const { return mLastKernelError; }

};

#endif
