/* Web Polygraph       http://www.web-polygraph.org/
 * (C) 2003-2006 The Measurement Factory
 * Licensed under the Apache License, Version 2.0 */

#include "pgl/pgl.h"
#include "pgl/HostsBasedIter.h"

#include "pgl/AgentSym.h"
#include "pgl/PglNetAddrSym.h"


HostsBasedIter::HostsBasedIter(): theCfgIdx(0), theHostIdx(0) {
}

HostsBasedIter::HostsBasedIter(const Addrs *aLocalAddrs) {
	start(aLocalAddrs);
}

HostsBasedIter::~HostsBasedIter() {
}

HostsBasedIter &HostsBasedIter::start(const Addrs *aLocalAddrs) {
	theLocalAddrs = aLocalAddrs;
	return restart();
}

HostsBasedIter &HostsBasedIter::restart() {
	theCfgIdx = theHostIdx = 0;
	sync();
	return *this;
}

bool HostsBasedIter::eof() const {
	return theCfgIdx >= cfgCount();
}

HostsBasedIter::operator void *() const {
	return !eof() ? (void*)(-1) : 0;
}

HostsBasedIter &HostsBasedIter::operator ++() {
	theHostIdx++;
	sync();
	return *this;
}

HostsBasedIter &HostsBasedIter::nextSym() {
	theCfgIdx++;
	theHostIdx = 0;
	sync();
	return *this;
}

const NetAddr &HostsBasedIter::host() {
	Assert(!eof());
	return theHost;
}

const NetAddrSym *HostsBasedIter::hostSym() {
	Assert(!eof());
	return cfgSym(theCfgIdx)->host(theHostIdx);
}

NetAddr HostsBasedIter::host(int cidx, int hidx) const {
	return cfgSym(cidx)->host(hidx)->val();
}

// must be called after an index change
void HostsBasedIter::sync() {
	while (!eof()) {
		HostsBasedSym *cs = cfgSym(theCfgIdx);
		if (theHostIdx < cs->hostCount()) {
			if (belongs(cs, host(theCfgIdx, theHostIdx)))
				break;
			theHostIdx++;
		} else {
			theHostIdx = 0;
			theCfgIdx++;
		}
	}
		
	theHost = eof() ? NetAddr() : host(theCfgIdx, theHostIdx);
}

bool HostsBasedIter::belongs(const HostsBasedSym *, const NetAddr &host) const {
	if (!theLocalAddrs)
		return true; // no restrictions

	int i = theLocalAddrs->count();
	while (--i >= 0) {
		if (theLocalAddrs->item(i) == host.addrN())
			return true;
	}
	return false;
}


syntax highlighted by Code2HTML, v. 0.9.1