PageRenderTime 300ms CodeModel.GetById 50ms app.highlight 220ms RepoModel.GetById 12ms app.codeStats 1ms

/locationPathExpr.cpp

https://bitbucket.org/aonyung/vtd-xml-c-64
C++ | 2314 lines | 2059 code | 146 blank | 109 comment | 536 complexity | 40f07237d0779123f6a08f3abc598f02 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/* 
   2 * Copyright (C) 2002-2011 XimpleWare, info@ximpleware.com
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License as published by
   6 * the Free Software Foundation; either version 2 of the License, or
   7 * (at your option) any later version.
   8 *
   9 * This program is distributed in the hope that it will be useful,
  10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 * GNU General Public License for more details.
  13 *
  14 * You should have received a copy of the GNU General Public License
  15 * along with this program; if not, write to the Free Software
  16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17 */
  18#include "locationPathExpr.h"

  19#include "autoPilot.h"

  20#include "textIter.h"

  21
  22using namespace com_ximpleware;
  23
  24LocationPathExpr::LocationPathExpr() try : 
  25pathType(RELATIVE_PATH),
  26s(NULL),
  27currentStep(NULL),
  28state(XPATH_EVAL_START),
  29ih(new IntHash())
  30{
  31}
  32catch (std::bad_alloc&){
  33	throw OutOfMemException("Allocation failed for LocationPathExpr");
  34}
  35
  36LocationPathExpr::~LocationPathExpr(){
  37	Step *tmp, *tmp2;
  38	if (s != NULL){
  39		tmp = s;
  40		tmp2 = tmp->nextS;
  41		while(tmp2!=NULL){
  42			delete(tmp);
  43			tmp= tmp2;
  44			tmp2 = tmp2->nextS;
  45		}
  46		delete(tmp);
  47	}
  48	delete(ih);
  49}
  50
  51bool LocationPathExpr::evalBoolean(VTDNav *vn){
  52	bool a = false;
  53	int size;
  54	vn->push2();
  55	// record stack size
  56	size = vn->contextBuf2->size;
  57	try{
  58		a = (evalNodeSet(vn) != -1);
  59	}catch (...){
  60	}
  61	//rewind stack
  62	vn->contextBuf2->size = size;
  63	reset(vn);
  64	vn->pop2();
  65	return a;
  66}
  67double LocationPathExpr::evalNumber(VTDNav *vn){
  68	double d = 0.0;
  69	int a = getStringIndex(vn);
  70	try{
  71		if (a!=-1) return vn->parseDouble(a);
  72	}catch (...){
  73	}
  74	return 0/d;
  75}
  76int LocationPathExpr::evalNodeSet(VTDNav *vn){
  77    int result;
  78	if (currentStep == NULL) {
  79		if ( pathType ==  ABSOLUTE_PATH){
  80			vn->toElement(ROOT);
  81			vn->toElement(PARENT);
  82		}
  83		currentStep =  s;
  84		if (currentStep == NULL){
  85			if (state ==  XPATH_EVAL_START){
  86				state = XPATH_EVAL_END;
  87				return 0;
  88			}
  89			else{
  90				return -1;
  91			}
  92		}
  93	}
  94
  95	while (true) {
  96		switch (currentStep->axis_type) {
  97			case AXIS_CHILD:
  98			    if ( (result = process_child(vn))!=-2)
  99				   return result;
 100			    break;
 101			case AXIS_DESCENDANT_OR_SELF:
 102			case AXIS_DESCENDANT:
 103			case AXIS_PRECEDING:
 104			case AXIS_FOLLOWING:
 105			    if ((result = process_DDFP(vn))!= -2)
 106			        return result;
 107			    break;
 108			case AXIS_PARENT:
 109			    if ((result = process_parent(vn))!= -2)
 110			        return result;
 111			    break;
 112			case AXIS_ANCESTOR:
 113			    if ((result = process_ancestor(vn))!= -2)
 114			        return result;
 115			    break;
 116			case AXIS_ANCESTOR_OR_SELF:
 117			    if ((result = process_ancestor_or_self(vn))!= -2)
 118			        return result;
 119			    break;
 120			case AXIS_SELF:
 121			    if ((result = process_self(vn))!= -2)
 122			        return result;
 123			    break;
 124			case AXIS_FOLLOWING_SIBLING:
 125			    if ((result = process_following_sibling(vn))!= -2)
 126			        return result;
 127			    break;
 128			case AXIS_PRECEDING_SIBLING:
 129			    if ((result = process_preceding_sibling(vn))!= -2)
 130			        return result;
 131			    break;
 132			case AXIS_ATTRIBUTE:
 133			    if ((result = process_attribute(vn))!= -2)
 134			        return result;
 135			    break;
 136			case AXIS_NAMESPACE:
 137			    if ((result = process_namespace(vn))!= -2)
 138			        return result;
 139				break;
 140			default:
 141				throw XPathEvalException("axis not supported");
 142			}
 143		}
 144}
 145UCSChar* LocationPathExpr::evalString(VTDNav *vn){
 146	int a = getStringIndex(vn);
 147	try {
 148		if (a != -1)
 149			return vn->toString(a);
 150	} catch (std::bad_alloc&) {
 151		throw;
 152	}
 153	return createEmptyString();
 154}
 155
 156void LocationPathExpr::reset(VTDNav *vn){
 157	Step *temp = s;
 158	state = XPATH_EVAL_START;
 159	ih->reset();
 160	currentStep = NULL;
 161	while(temp!=NULL){
 162		temp->reset_s(vn);
 163		temp = temp->nextS;
 164	}
 165}
 166void LocationPathExpr::toString(UCSChar *string){
 167	Step *ts = s;
 168	if (pathType == ABSOLUTE_PATH){
 169		wprintf(L"/");
 170	}
 171	if (ts == NULL)
 172		return;
 173	else
 174		ts->toString_s(string);
 175}
 176
 177bool LocationPathExpr::isNumerical(){return false;}
 178bool LocationPathExpr::isNodeSet(){return true;}
 179bool LocationPathExpr::isString(){return false;}
 180bool LocationPathExpr::isBoolean(){return false;}
 181
 182bool LocationPathExpr::requireContextSize(){return false;}
 183void LocationPathExpr::setContextSize(int size){}
 184
 185void LocationPathExpr::setPosition(int pos){}
 186int LocationPathExpr::adjust(int n){
 187	int i;
 188	if (pathType == RELATIVE_PATH){
 189		i= min(6,IntHash::determineHashWidth(n));//hashwidth 64
 190	} else {
 191		i=IntHash::determineHashWidth(n);
 192	}
 193	if (ih!=NULL && i<=ih->e)
 194	{}else {
 195		delete (ih);
 196		ih =  new IntHash(i);
 197	}
 198	Step *temp = s;
 199	while(temp!=NULL){
 200		temp->adjust(n);
 201		temp = temp->nextS;
 202	}	
 203	return i;
 204}
 205
 206
 207int LocationPathExpr::computeContextSize(Predicate *p, VTDNav *vn){
 208	bool b = false;
 209	//Predicate *tp = NULL;
 210    int i = 0;
 211    AutoPilot *ap = (AutoPilot *)currentStep->o;
 212	UCSChar *helper = NULL;
 213	switch(currentStep->axis_type){
 214    	case AXIS_CHILD:
 215			if (currentStep->nt->testType < NT_TEXT){
 216    			b = vn->toElement(FIRST_CHILD);
 217    			if (b) {
 218    				do {
 219						if (currentStep->eval_s2(vn, p)) {
 220							i++;
 221    					}
 222    				} while (vn->toElement(NEXT_SIBLING));
 223    				vn->toElement(PARENT);
 224					currentStep->resetP2_s(vn,p);
 225    				return i;
 226   				} else
 227    				return 0;
 228			}else {
 229				int result;
 230				TextIter* ti = new TextIter();
 231	    	    ti->touch(vn);
 232	    	    selectNodeType(ti);
 233	    	    while((result=ti->getNext())!=-1){
 234					vn->LN = result;
 235					vn->atTerminal = true;
 236	    	        if (currentStep->evalPredicates2(vn,p)){
 237	    	            i++;
 238	    	        }
 239	    	    }
 240				vn->atTerminal = false;
 241				currentStep->resetP2_s(vn,p);
 242	    	    return i;
 243			}
 244
 245		case AXIS_DESCENDANT_OR_SELF:
 246		case AXIS_DESCENDANT:
 247		case AXIS_PRECEDING:
 248		case AXIS_FOLLOWING:
 249
 250			if (currentStep->nt->testType == NT_NODE){
 251				helper = (UCSChar *)L"*";
 252			}else if (currentStep->nt->testType == NT_NAMETEST){
 253				helper = currentStep->nt->nodeName;
 254			}else    			
 255				throw XPathEvalException(
 256				   "can't run descendant following, or following-sibling axis over comment(), pi(), and text()");
 257			if (ap==NULL)
 258					ap =  new AutoPilot(vn);
 259				else
 260					ap->bind(vn);
 261			if (currentStep->axis_type == AXIS_DESCENDANT_OR_SELF ){
 262				if (currentStep->nt->testType == NT_NODE)
 263					ap->setSpecial(true);
 264				else
 265					ap->setSpecial(false);
 266			}
 267			//currentStep.o = ap = new AutoPilot(vn);
 268			if (currentStep->axis_type == AXIS_DESCENDANT_OR_SELF)
 269				if (currentStep->nt->localName!=NULL)
 270					ap->selectElementNS(currentStep->nt->URL,currentStep->nt->localName);
 271				else
 272					ap->selectElement(helper);
 273			else if (currentStep->axis_type == AXIS_DESCENDANT)
 274				if (currentStep->nt->localName!=NULL)
 275					ap->selectElementNS_D(currentStep->nt->URL,currentStep->nt->localName);
 276				else
 277					ap->selectElement_D(helper);
 278			else if (currentStep->axis_type == AXIS_PRECEDING)
 279				if (currentStep->nt->localName!=NULL)
 280					ap->selectElementNS_P(currentStep->nt->URL,currentStep->nt->localName);
 281				else
 282					ap->selectElement_P(helper);
 283			else
 284				if (currentStep->nt->localName!=NULL)
 285					ap->selectElementNS_F(currentStep->nt->URL,currentStep->nt->localName);
 286				else
 287					ap->selectElement_F(helper);
 288			vn->push2();
 289			while(ap->iterate()){
 290				if (currentStep->evalPredicates2(vn,p)){
 291					i++;
 292				}
 293			}
 294			vn->pop2();
 295			currentStep->resetP2_s(vn,p);
 296			currentStep->o= ap;
 297			//freeAutoPilot(ap);
 298			return i;
 299
 300		case AXIS_PARENT:
 301			vn->push2();
 302			i = 0;
 303			if (vn->toElement( PARENT)){
 304				if (currentStep->eval_s2(vn,p)){
 305					i++;
 306				}
 307			}
 308			vn->pop2();
 309			currentStep->resetP2_s(vn,p);
 310			return i;
 311
 312		case AXIS_ANCESTOR:
 313			vn->push2();
 314			i = 0;
 315			while (vn->toElement(PARENT)) {
 316				if (currentStep->eval_s2(vn, p)) {
 317					i++;
 318				}
 319			}
 320			vn->pop2();
 321			currentStep->resetP2_s(vn,p);
 322			return i;
 323
 324		case AXIS_ANCESTOR_OR_SELF:
 325			vn->push2();
 326			i = 0;
 327			do {
 328				if (currentStep->eval_s2(vn, p)) {
 329					i++;
 330				}
 331			}while(vn->toElement(PARENT));
 332			vn->pop2();
 333			currentStep->resetP2_s(vn,p);
 334			return i;
 335
 336		case AXIS_SELF:
 337			i = 0;
 338			if (vn->toElement(PARENT)){
 339				if (currentStep->eval_s2(vn,p)){
 340					i++;
 341				}
 342			}
 343			currentStep->resetP2_s(vn,p);
 344			return i;
 345
 346		case AXIS_FOLLOWING_SIBLING:
 347			vn->push2();
 348			while(vn->toElement(NEXT_SIBLING)){
 349				if (currentStep->eval_s2(vn,p)){
 350					i++;
 351				}
 352			}
 353			vn->pop2();
 354			currentStep->resetP2_s(vn,p);
 355			return i;
 356
 357		case AXIS_PRECEDING_SIBLING:
 358			vn->push2();
 359			while(vn->toElement(PREV_SIBLING)){
 360				if (currentStep->eval_s2(vn,p)){
 361					i++;
 362				}
 363			}
 364			vn->pop2();
 365			currentStep->resetP2_s(vn,p);
 366			return i;
 367
 368		case AXIS_ATTRIBUTE:
 369			if (ap==NULL)
 370					ap =  new AutoPilot(vn);
 371				else
 372					ap->bind(vn);
 373			//ap = createAutoPilot(vn);
 374			if (currentStep->nt->testType == NT_NODE)
 375				ap->selectAttr((UCSChar *)L"*");
 376			else if (currentStep->nt->localName!=NULL)
 377				ap->selectAttrNS(currentStep->nt->URL,
 378				currentStep->nt->localName);
 379			else
 380				ap->selectAttr(currentStep->nt->nodeName);
 381			i = 0;
 382			while(ap->iterateAttr2()!=-1){
 383				if (currentStep->evalPredicates2( vn, p)){
 384					i++;
 385				}
 386			}
 387			currentStep->resetP2_s(vn,p);
 388			currentStep->o= ap;
 389			//freeAutoPilot(ap);
 390			return i;
 391
 392		case AXIS_NAMESPACE:
 393			if (ap==NULL)
 394					ap = new AutoPilot(vn);
 395				else
 396					ap->bind(vn);
 397			if (currentStep->nt->testType == NT_NODE)
 398				ap->selectNameSpace((UCSChar *)L"*");
 399			else
 400				ap->selectNameSpace(currentStep->nt->nodeName);
 401			i = 0;
 402			while(ap->iterateNameSpace()!=-1){
 403				if (currentStep->evalPredicates2( vn, p)){
 404					i++;
 405				}
 406			}
 407			currentStep->resetP2_s(vn,p);
 408			currentStep->o= ap;
 409			//freeAutoPilot(ap);
 410			return i;
 411
 412		default:
 413			throw XPathEvalException("unknown state");
 414			return 0;
 415	}
 416}
 417int LocationPathExpr::process_ancestor_or_self(VTDNav *vn){
 418	bool b = false, b1= false;
 419	int result;
 420	//int contextSize;
 421	Predicate *t= NULL;
 422
 423	switch ( state) {
 424		case  XPATH_EVAL_START:
 425			t = currentStep->p;
 426			while (t != NULL) {
 427				if (t->requireContextSize_p()) {
 428					int i = computeContextSize(t, vn);
 429					if (i == 0) {
 430						b1 = true;
 431						break;
 432					} else
 433						t->setContextSize_p(i);
 434				}
 435				t = t->nextP;
 436			}
 437			if (b1) {
 438				state = XPATH_EVAL_END;
 439				break;
 440			}
 441
 442			state =  XPATH_EVAL_END;
 443			vn->push2();
 444
 445			if (currentStep->get_ft()== true){
 446				currentStep->set_ft(false);
 447				if (currentStep->eval_s(vn)) {
 448					if (currentStep->getNextStep() != NULL) {
 449						state =  XPATH_EVAL_FORWARD;
 450						currentStep = currentStep->nextS;
 451						break;
 452					} else {
 453						//vn.pop();
 454						state =  XPATH_EVAL_TERMINAL;
 455						if (vn->atTerminal)
 456							result = vn->LN;
 457						else
 458							result = vn->getCurrentIndex();
 459						if ( isUnique(result))
 460							return result;
 461					}
 462				}
 463			}
 464
 465			while (vn->toElement(PARENT)) {
 466				if (currentStep->eval_s(vn)) {
 467					if (currentStep->nextS != NULL) {
 468						state =  XPATH_EVAL_FORWARD;
 469						currentStep = currentStep->nextS;
 470						break;
 471					} else {
 472						//vn.pop();
 473						state =  XPATH_EVAL_TERMINAL;
 474						result = vn->getCurrentIndex();
 475						if ( isUnique(result))
 476							return result;
 477					}
 478				}
 479			}
 480
 481			if ( state ==  XPATH_EVAL_END) {
 482				currentStep->resetP_s( vn);
 483				vn->pop2();
 484			}
 485
 486			break;
 487
 488		case  XPATH_EVAL_FORWARD:
 489			t = currentStep->p;
 490			while (t != NULL) {
 491				if (t->requireContextSize_p()) {
 492					int i = computeContextSize(t, vn);
 493					if (i == 0) {
 494						b1 = true;
 495						break;
 496					} else
 497						t->setContextSize_p(i);
 498				}
 499				t = t->nextP;
 500			}
 501			if (b1) {
 502				currentStep = currentStep->prevS;
 503				state = XPATH_EVAL_BACKWARD;
 504				break;
 505			}
 506
 507			state =  XPATH_EVAL_BACKWARD;
 508			vn->push2();
 509			if (currentStep->ft == true) {
 510				currentStep->ft= false;
 511				if (currentStep->eval_s(vn)) {
 512					if (currentStep->nextS != NULL) {
 513						state =  XPATH_EVAL_FORWARD;
 514						currentStep = currentStep->nextS;
 515						break;
 516					} else {
 517						//vn.pop();
 518						state =  XPATH_EVAL_TERMINAL;
 519						if (vn->atTerminal)
 520							result = vn->LN;
 521						else
 522							result = vn->getCurrentIndex();
 523						if ( isUnique(result))
 524							return result;
 525					}
 526				}
 527			}
 528			while (vn->toElement(PARENT)) {
 529				if (currentStep->eval_s(vn)) {
 530					if (currentStep->nextS != NULL) {
 531						state =  XPATH_EVAL_FORWARD;
 532						currentStep = currentStep->nextS;
 533						break;
 534					} else {
 535						//vn.pop();
 536						state =  XPATH_EVAL_TERMINAL;
 537						result = vn->getCurrentIndex();
 538						if ( isUnique(result))
 539							return result;
 540					}
 541				}
 542			}
 543
 544			if ( state ==  XPATH_EVAL_BACKWARD) {
 545				currentStep->resetP_s(vn);
 546				currentStep->ft = true;
 547				vn->pop2();
 548				currentStep = currentStep->prevS;
 549			}
 550			break;
 551
 552		case  XPATH_EVAL_END:
 553			currentStep = NULL;
 554			// reset();
 555	    	return -1;
 556
 557
 558		case  XPATH_EVAL_BACKWARD:
 559			b = false;
 560			vn->push2();
 561
 562			while (vn->toElement(PARENT)) {
 563				if (currentStep->eval_s(vn)) {
 564					if (currentStep->nextS != NULL) {
 565						state =  XPATH_EVAL_FORWARD;
 566						currentStep = currentStep->nextS;
 567						b = true;
 568						break;
 569					} else {
 570						//vn.pop();
 571						state =  XPATH_EVAL_TERMINAL;
 572						result = vn->getCurrentIndex();
 573						if ( isUnique(result))
 574							return result;
 575					}
 576				}
 577			}
 578			if (b == false) {
 579				vn->pop2();
 580				currentStep->resetP_s(vn);
 581				if (currentStep->prevS != NULL) {
 582					currentStep->ft = true;
 583					state =  XPATH_EVAL_BACKWARD;
 584					currentStep = currentStep->prevS;
 585				} else {
 586					state =  XPATH_EVAL_END;
 587				}
 588			}
 589			break;
 590
 591		case  XPATH_EVAL_TERMINAL:
 592			while (vn->toElement(PARENT)) {
 593				if (currentStep->eval_s(vn)) {
 594					result = vn->getCurrentIndex();
 595					if ( isUnique(result))
 596						return result;
 597				}
 598			}
 599			vn->pop2();
 600			currentStep->resetP_s(vn);
 601			if (currentStep->prevS != NULL) {
 602				currentStep->ft = true;
 603				state =  XPATH_EVAL_BACKWARD;
 604				currentStep = currentStep->prevS;
 605			}
 606			else {
 607				 state =  XPATH_EVAL_END;
 608			}
 609			break;
 610
 611
 612		default:
 613			throw XPathEvalException("unknown state");
 614		}
 615		return -2;
 616}
 617int LocationPathExpr::process_ancestor(VTDNav *vn){
 618	int result;
 619	bool b = false, b1 = false;
 620	//int contextSize;
 621	Predicate *t= NULL;
 622
 623	switch(state){
 624			case XPATH_EVAL_START:
 625				t = currentStep->p;
 626				while (t != NULL) {
 627					if (t->requireContextSize_p()) {
 628						int i = computeContextSize(t, vn);
 629						if (i == 0) {
 630							b1 = true;
 631							break;
 632						} else
 633							t->setContextSize_p(i);
 634					}
 635					t = t->nextP;
 636				}
 637				if (b1) {
 638					state = XPATH_EVAL_END;
 639					break;
 640				}
 641
 642				state = XPATH_EVAL_END;
 643				if (vn->getCurrentDepth() != -1) {
 644					vn->push2();
 645
 646					while (vn->toElement(PARENT)) {
 647						if (currentStep->eval_s(vn)) {
 648							if (currentStep->nextS != NULL) {
 649								state = XPATH_EVAL_FORWARD;
 650								currentStep = currentStep->nextS;
 651								break;
 652							} else {
 653								//vn.pop();
 654								state = XPATH_EVAL_TERMINAL;
 655								result = vn->getCurrentIndex();
 656								if (isUnique(result))
 657									return result;
 658							}
 659						}
 660					}
 661					if (state == XPATH_EVAL_END) {
 662						currentStep->resetP_s(vn);
 663						vn->pop2();
 664					}
 665				}
 666				break;
 667
 668			case XPATH_EVAL_END:
 669				currentStep =NULL;
 670				// reset();
 671				return -1;
 672
 673			case XPATH_EVAL_FORWARD:
 674				t = currentStep->p;
 675				while(t!=NULL){
 676					if (t->requireContextSize_p()){
 677						int i = computeContextSize(t,vn);
 678						if (i==0){
 679							b1 = true;
 680							break;
 681						}else
 682							t->setContextSize_p(i);
 683					}
 684					t = t->nextP;
 685				}
 686				if (b1){
 687					currentStep = currentStep->prevS;
 688					state = XPATH_EVAL_BACKWARD;
 689					break;
 690				}
 691				state =  XPATH_EVAL_BACKWARD;
 692				vn->push2();
 693
 694				while(vn->toElement(PARENT)){
 695					if (currentStep->eval_s(vn)){
 696						if (currentStep->nextS != NULL){
 697							state =  XPATH_EVAL_FORWARD;
 698							currentStep = currentStep->nextS;
 699							break;
 700						}
 701						else {
 702							//vn.pop();
 703							state =  XPATH_EVAL_TERMINAL;
 704							result = vn->getCurrentIndex();
 705							if ( isUnique(result))
 706								return result;
 707						}
 708					}
 709				}
 710				if ( state== XPATH_EVAL_BACKWARD){
 711					currentStep->resetP_s(vn);
 712					vn->pop2();
 713					currentStep=currentStep->prevS;
 714				}
 715				break;
 716
 717			case XPATH_EVAL_BACKWARD:
 718				b = false;
 719				vn->push2();
 720
 721				while (vn->toElement(PARENT)) {
 722					if (currentStep->eval_s(vn)) {
 723						if (currentStep->nextS!= NULL) {
 724							state =  XPATH_EVAL_FORWARD;
 725							currentStep = currentStep->nextS;
 726							b = true;
 727							break;
 728						} else {
 729							//vn.pop();
 730							state =  XPATH_EVAL_TERMINAL;
 731							result = vn->getCurrentIndex();
 732							if ( isUnique(result))
 733								return result;
 734						}
 735					}
 736				}
 737				if (b==false){
 738					vn->pop2();
 739					if (currentStep->prevS!=NULL) {
 740						currentStep->resetP_s(vn);
 741						state =  XPATH_EVAL_BACKWARD;
 742						currentStep = currentStep->prevS;
 743					}
 744					else {
 745						state =  XPATH_EVAL_END;
 746					}
 747				}
 748				break;
 749
 750			case XPATH_EVAL_TERMINAL:
 751				while (vn->toElement(PARENT)) {
 752					if (currentStep->eval_s(vn)) {
 753						result = vn->getCurrentIndex();
 754						if ( isUnique(result))
 755							return result;
 756					}
 757				}
 758				vn->pop2();
 759
 760				if (currentStep->prevS!=NULL) {
 761					currentStep->resetP_s(vn);
 762					state =  XPATH_EVAL_BACKWARD;
 763					currentStep = currentStep->prevS;
 764				}
 765				else {
 766					state =  XPATH_EVAL_END;
 767				}
 768				break;
 769
 770			default:
 771				throw XPathEvalException("unknown state");
 772	}
 773	return -2;
 774}
 775int LocationPathExpr::process_attribute(VTDNav *vn){
 776	AutoPilot *ap = NULL;
 777	bool b1 = false;
 778	Predicate *t= NULL;
 779	int temp;
 780	switch(state){
 781		case  XPATH_EVAL_START:
 782		case  XPATH_EVAL_FORWARD:
 783
 784			t = currentStep->p;
 785			while(t!=NULL){
 786				if (t->requireContextSize_p()){
 787					int i = computeContextSize(t,vn);
 788					if (i==0){
 789						b1 = true;
 790						break;
 791					}else
 792						t->setContextSize_p(i);
 793				}
 794				t = t->nextP;
 795			}
 796			if (b1){
 797				if (state == XPATH_EVAL_FORWARD){
 798					state= XPATH_EVAL_BACKWARD;
 799					currentStep = currentStep->prevS;
 800				}else
 801					state= XPATH_EVAL_END;
 802				break;
 803			}
 804
 805			if (vn->getAtTerminal()==true){
 806				if (state ==XPATH_EVAL_START)
 807					state = XPATH_EVAL_END;
 808				else {
 809					state = XPATH_EVAL_BACKWARD;
 810					currentStep  = currentStep->prevS;
 811				}
 812			} else {
 813				if (currentStep->ft == true) {
 814					if (currentStep->o == NULL)
 815						currentStep->o = ap = new AutoPilot(vn);
 816					else {
 817						ap = currentStep->o;
 818						ap->bind(vn);
 819					}
 820					if (currentStep->nt->testType== NT_NODE)
 821						ap->selectAttr((UCSChar *)L"*");
 822					else if (currentStep->nt->localName != NULL)
 823						ap->selectAttrNS(currentStep->nt->URL,
 824                                currentStep->nt->localName);
 825					else 
 826						ap->selectAttr(currentStep->nt->nodeName);
 827					currentStep->ft = false;
 828				}
 829				if ( state==  XPATH_EVAL_START)
 830					state=  XPATH_EVAL_END;
 831				vn->setAtTerminal(true);
 832				while( (temp = ap->iterateAttr2()) != -1){
 833					if (currentStep->evalPredicates(vn)){
 834						break;
 835					}
 836				}
 837				if (temp == -1){
 838					currentStep->ft = true;
 839					currentStep->resetP_s(vn);
 840					vn->setAtTerminal(false);
 841					if ( state==  XPATH_EVAL_FORWARD){
 842						state =  XPATH_EVAL_BACKWARD;
 843						currentStep = currentStep->prevS;
 844					}
 845				}else {
 846
 847					if (currentStep->nextS != NULL){
 848						vn->LN = temp;
 849						state=  XPATH_EVAL_FORWARD;
 850						currentStep = currentStep->nextS;
 851					}
 852					else {
 853						//vn.pop();
 854						state=  XPATH_EVAL_TERMINAL;
 855						if ( isUnique(temp)){
 856							vn->LN = temp;
 857							return temp;
 858						}
 859					}
 860
 861				}
 862			}
 863			break;
 864
 865		case  XPATH_EVAL_END:
 866			currentStep = NULL;
 867			// reset();
 868			return -1;
 869
 870		case  XPATH_EVAL_BACKWARD:
 871			ap = currentStep->o;
 872			//vn.push();
 873			while( (temp = ap->iterateAttr2()) != -1){
 874				if (currentStep->evalPredicates(vn)){
 875					break;
 876				}
 877			}
 878			if (temp == -1) {
 879				currentStep->ft = true;
 880				//freeAutoPilot(currentStep->o);
 881				//currentStep->o = NULL;
 882				currentStep->resetP_s(vn);
 883				vn->setAtTerminal(false);
 884				if (currentStep->prevS != NULL) {
 885					state =  XPATH_EVAL_BACKWARD;
 886					currentStep = currentStep->prevS;
 887				} else
 888					state =  XPATH_EVAL_END;
 889			} else {
 890				if (currentStep->nextS != NULL) {
 891					state =  XPATH_EVAL_FORWARD;
 892					currentStep = currentStep->nextS;
 893				} else {
 894					state =  XPATH_EVAL_TERMINAL;
 895					if ( isUnique(temp)){
 896						vn->LN = temp;
 897						return temp;
 898					}
 899				}
 900			}
 901			break;
 902
 903		case  XPATH_EVAL_TERMINAL:
 904			ap = currentStep->o;
 905			while( (temp = ap->iterateAttr2()) != -1){
 906				if (currentStep->evalPredicates(vn)){
 907					break;
 908				}
 909			}
 910			if (temp != -1)
 911				if (isUnique(temp)){
 912					vn->LN = temp;
 913					return temp;
 914				}
 915				vn->setAtTerminal(false);
 916				currentStep->resetP_s(vn);
 917				if (currentStep->prevS == NULL) {
 918					currentStep->ft = true;
 919					//freeAutoPilot(currentStep->o);
 920					//currentStep->o = NULL;
 921					state=  XPATH_EVAL_END;
 922				} else {
 923					state=  XPATH_EVAL_BACKWARD;
 924					currentStep->ft = true;
 925					//freeAutoPilot(currentStep->o);
 926					//currentStep->o = NULL;
 927					currentStep = currentStep->prevS;
 928				}
 929
 930				break;
 931
 932		default:
 933			throw XPathEvalException("unknown state");
 934	}
 935	return -2;
 936}
 937int LocationPathExpr::process_child(VTDNav *vn){
 938	int result;
 939	bool b = false, b1 = false;
 940	Predicate *t= NULL;
 941
 942	switch(state){
 943				case XPATH_EVAL_START:
 944					if (currentStep->nt->testType < NT_TEXT){
 945						/* first search for any predicate that
 946						// requires contextSize
 947						// if so, compute its context size
 948						// if size > 0
 949						// set context
 950						// if size ==0
 951						// immediately set the state to backward or end*/
 952						t = currentStep->p;
 953						while(t!=NULL){
 954							if (t->requireContextSize_p()){
 955								int i = computeContextSize(t,vn);
 956								if (i==0){
 957									b1 = true;
 958									break;
 959								}else
 960									t->setContextSize_p(i);
 961							}
 962							t = t->nextP;
 963						}
 964						if (b1){
 965							state= XPATH_EVAL_END;
 966							break;
 967						}
 968
 969						b=vn->toElement(FIRST_CHILD);
 970						state=  XPATH_EVAL_END;
 971						if (b == true){
 972						 do {
 973							 if (currentStep->eval_s(vn)) {
 974								 if (currentStep->nextS != NULL){
 975									 //currentStep.position++;
 976									 state=  XPATH_EVAL_FORWARD;
 977									 currentStep = currentStep->nextS;
 978								 }
 979								 else {
 980									 state=  XPATH_EVAL_TERMINAL;
 981									 result = vn->getCurrentIndex();
 982									 if ( isUnique(result)){
 983										 return result;
 984									 }
 985								 }
 986								 break;
 987							 }
 988						 } while (vn->toElement(NEXT_SIBLING));
 989						 if (state == XPATH_EVAL_END)
 990							 vn->toElement(PARENT);
 991					 }
 992					}else {
 993						TextIter *ti = NULL;
 994						if (vn->getAtTerminal()==true){
 995							state = XPATH_EVAL_END;
 996						}else {
 997						    // compute context size;
 998						    t = currentStep->p;
 999			    	        while(t!=NULL){
1000			    	            if (t->requireContextSize_p()){
1001			    	                int i = computeContextSize(t,vn);
1002			    	                if (i==0){
1003			    	                    b1 = true;
1004			    	                    break;
1005			    	                }else
1006			    	                    t->setContextSize_p(i);
1007			    	            }
1008			    	            t = t->nextP;
1009			    	        }
1010			    	        // b1 false indicate context size is zero. no need to go any further...
1011			    	        if (b1){
1012			    	            state = XPATH_EVAL_END;
1013			    	            break;
1014			    	        }
1015			    	        // get textIter
1016						    if (currentStep->o != NULL){
1017						        ti = (TextIter*) currentStep->o;
1018						    } else {
1019						        ti = new TextIter();
1020						        currentStep->o = (AutoPilot *)ti;
1021						    }
1022							selectNodeType(ti);
1023						    ti->touch(vn);
1024						    state = XPATH_EVAL_END;
1025						    while((result = ti->getNext())!=-1){
1026								vn->LN = result;
1027								vn->atTerminal = true;
1028								if (currentStep->evalPredicates(vn)){
1029									break;
1030								}
1031						    }
1032						    // old code
1033							//result = vn.getText();
1034							if (result != -1){
1035								vn->setAtTerminal(true);
1036								//currentStep.resetP(vn);
1037								vn->LN = result;
1038								if (currentStep->getNextStep() != NULL){
1039								    vn->LN = result;
1040				   				    state =  XPATH_EVAL_FORWARD;
1041									currentStep = currentStep->getNextStep();
1042								}
1043								else {
1044									//vn.pop();
1045									state =  XPATH_EVAL_TERMINAL;
1046									if (isUnique(result)){
1047									    vn->LN = result;
1048										return result;
1049									}
1050								}
1051							} else{
1052								//currentStep.set_ft(true);
1053								currentStep->resetP_s(vn);
1054								vn->setAtTerminal( false);
1055							}
1056						}
1057					}
1058					break;
1059				case XPATH_EVAL_END:
1060					currentStep =NULL;
1061					// reset();
1062					return -1;
1063
1064				case XPATH_EVAL_FORWARD:
1065					if (currentStep->nt->testType < NT_TEXT){
1066						t = currentStep->p;
1067						while(t!=NULL){
1068							if (t->requireContextSize_p()){
1069								int i = computeContextSize( t,vn);
1070								if (i==0){
1071									b1 = true;
1072									break;
1073								}else
1074									t->setContextSize_p(i);
1075							}
1076							t = t->nextP;
1077						}
1078						if (b1){
1079							currentStep = currentStep->prevS;
1080							state= XPATH_EVAL_BACKWARD;
1081							break;
1082						}
1083
1084						state =  XPATH_EVAL_BACKWARD;
1085						if (vn->toElement(FIRST_CHILD)) {
1086							do {
1087								if (currentStep->eval_s(vn)) {
1088									if (currentStep->nextS != NULL) {
1089										state=  XPATH_EVAL_FORWARD;
1090										currentStep = currentStep->nextS;
1091									} else {
1092										state=  XPATH_EVAL_TERMINAL;
1093										result = vn->getCurrentIndex();
1094										if ( isUnique(result))
1095											return result;
1096									}
1097									goto forward;
1098								}
1099							} while (vn->toElement(NEXT_SIBLING));
1100							vn->toElement(PARENT);
1101							currentStep->resetP_s(vn);
1102							currentStep = currentStep->prevS;
1103						} else {
1104							//vn.toElement(VTDNav.P);
1105							currentStep = currentStep->prevS;
1106						}
1107forward:;
1108					}else {
1109						TextIter *ti = NULL;
1110
1111 // predicate at an attribute is not evaled
1112						if (vn->getAtTerminal() == true){
1113							state =  XPATH_EVAL_BACKWARD;
1114							currentStep = currentStep->getPrevStep();
1115						}else {
1116						    // compute context size;
1117						    t = currentStep->p;
1118			    	        while(t!=NULL){
1119			    	            if (t->requireContextSize_p()){
1120			    	                int i = computeContextSize(t,vn);
1121			    	                if (i==0){
1122			    	                    b1 = true;
1123			    	                    break;
1124			    	                }else
1125			    	                    t->setContextSize_p(i);
1126			    	            }
1127			    	            t = t->nextP;
1128			    	        }
1129			    	        // b1 false indicate context size is zero. no need to go any further...
1130			    	        if (b1){
1131			    	            state =  XPATH_EVAL_BACKWARD;
1132			    	            break;
1133			    	        }
1134			    	        // get textIter
1135						    if (currentStep->o != NULL){
1136						        ti = (TextIter*) currentStep->o;
1137						    } else {
1138						        ti = new TextIter();
1139						        currentStep->o = (AutoPilot *)ti;
1140						    }
1141						    ti->touch(vn);
1142							selectNodeType(ti);
1143						    //result = ti.getNext();
1144
1145						    while((result = ti->getNext())!=-1){
1146								vn->LN = result;
1147								vn->atTerminal = true;
1148								if (currentStep->evalPredicates(vn)){
1149									break;
1150								}
1151						    }
1152
1153			                if (result == -1) {
1154			                    //currentStep.set_ft(true);
1155			                    //currentStep.resetP(vn);
1156			                    vn->setAtTerminal( false);
1157			                    if (state ==  XPATH_EVAL_FORWARD) {
1158			                        state =  XPATH_EVAL_BACKWARD;
1159									currentStep = currentStep->getPrevStep();
1160			                    }
1161			                } else {
1162								vn->setAtTerminal( true);
1163			                    if (currentStep->getNextStep() != NULL) {
1164			                        vn->LN = result;
1165			                        state =  XPATH_EVAL_FORWARD;
1166			                        currentStep = currentStep->getNextStep();
1167			                    } else {
1168			                        //vn.pop();
1169			                        state =  XPATH_EVAL_TERMINAL;
1170			                        if (isUnique(result)) {
1171			                            vn->LN = result;
1172			                            return result;
1173			                        }
1174			                    }
1175			                }
1176						}
1177
1178					}
1179
1180					break;
1181
1182				case XPATH_EVAL_BACKWARD:
1183					if (currentStep->nt->testType < NT_TEXT) {
1184						b = false;
1185						while (vn->toElement(NEXT_SIBLING)) {
1186							if (currentStep->eval_s(vn)) {
1187								b = true;
1188								break;
1189							}
1190						}
1191						if (b == true) {
1192							state=  XPATH_EVAL_FORWARD;
1193							currentStep = currentStep->nextS;
1194						} else if (currentStep->prevS == NULL){
1195							currentStep->resetP_s(vn);
1196							vn->toElement(PARENT);
1197							state=  XPATH_EVAL_END;
1198						}
1199						else {
1200							currentStep->resetP_s(vn);
1201							state=  XPATH_EVAL_BACKWARD;
1202							vn->toElement(PARENT);
1203							currentStep = currentStep->prevS;
1204						}
1205					}else {
1206						vn->setAtTerminal(false);
1207						if (currentStep->prevS == NULL)
1208							state=  XPATH_EVAL_END;
1209						else {
1210							state=  XPATH_EVAL_BACKWARD;
1211							currentStep = currentStep->prevS;
1212						}
1213					}
1214					break;
1215
1216				case XPATH_EVAL_TERMINAL:
1217					if (currentStep->nt->testType < NT_TEXT) {
1218						while (vn->toElement(NEXT_SIBLING)) {
1219							if (currentStep->eval_s(vn)) {
1220								result = vn->getCurrentIndex();
1221								if ( isUnique(result))
1222									return result;
1223							}
1224						}
1225						currentStep->resetP_s(vn);
1226						if (currentStep->prevS == NULL){
1227							state=  XPATH_EVAL_END;
1228							vn->toElement(PARENT);
1229						}
1230						else {
1231							vn->toElement(PARENT);
1232
1233							state=  XPATH_EVAL_BACKWARD;
1234							currentStep = currentStep->prevS;
1235						}
1236					}else {
1237						TextIter* ti = (TextIter*) currentStep->o;
1238					    while ((result= ti->getNext())!=-1) {
1239							vn->LN = result;
1240							vn->atTerminal = true;
1241							if (currentStep->evalPredicates(vn)) {
1242					            if ( isUnique(result))
1243									return result;
1244					        }
1245					    }
1246						currentStep->resetP_s( vn);
1247						vn->setAtTerminal( false);
1248						if (currentStep->getPrevStep() == NULL)
1249							 state=  XPATH_EVAL_END;
1250						else {
1251							 state=  XPATH_EVAL_BACKWARD;
1252							 currentStep = currentStep->getPrevStep();
1253						}
1254						///////////////////////////////
1255					}
1256					break;
1257
1258				default:
1259					throw XPathEvalException("unknown state");
1260	}
1261	return -2;
1262}
1263int LocationPathExpr::process_DDFP(VTDNav *vn){
1264	AutoPilot *ap;
1265	bool b = false, b1 = false;
1266	Predicate *t= NULL;
1267	int result;
1268	UCSChar *helper;
1269	switch(state){
1270			case XPATH_EVAL_START:
1271			case XPATH_EVAL_FORWARD:
1272				if (vn->atTerminal){
1273					if (state == XPATH_EVAL_START)
1274						state= XPATH_EVAL_END;
1275					else {
1276						// no need to set_ft to true
1277						// no need to resetP
1278						state= XPATH_EVAL_BACKWARD;
1279						currentStep = currentStep->prevS;
1280					}
1281					break;
1282				}
1283
1284				t = currentStep->p;
1285				while(t!=NULL){
1286					if (t->requireContextSize_p()){
1287						int i = computeContextSize( t,vn);
1288						if (i==0){
1289							b1 = true;
1290							break;
1291						}else
1292							t->setContextSize_p(i);
1293					}
1294					t = t->nextP;
1295				}
1296				if (b1){
1297					if (state ==XPATH_EVAL_START)
1298						state= XPATH_EVAL_END;
1299					else {
1300						currentStep = currentStep->prevS;
1301						state= XPATH_EVAL_BACKWARD;
1302					}
1303					break;
1304				}
1305
1306
1307				helper = NULL;
1308				if (currentStep->nt->testType == NT_NAMETEST){
1309					helper = currentStep->nt->nodeName;
1310				}else if (currentStep->nt->testType == NT_NODE){
1311					helper = (UCSChar *) L"*";
1312				}else
1313    				throw XPathEvalException(
1314					"can't run descendant following, or following-sibling axis over comment(), pi(), and text()"); 
1315				if (currentStep->o == NULL)
1316					currentStep->o = ap = new AutoPilot(vn);
1317				else{
1318					ap = currentStep->o;
1319					ap->bind(vn);
1320				}
1321				if (currentStep->ft == true) {
1322
1323					if (currentStep->axis_type == AXIS_DESCENDANT_OR_SELF ){
1324						if (currentStep->nt->testType == NT_NODE)
1325							ap->setSpecial(true);
1326						else
1327							ap->setSpecial(false);
1328					}
1329					//currentStep.o = ap = createAutoPilot(vn);
1330					if (currentStep->axis_type == AXIS_DESCENDANT_OR_SELF)
1331						ap->selectElement(helper);
1332					else if (currentStep->axis_type == AXIS_DESCENDANT)
1333						ap->selectElement_D(helper);
1334					else if (currentStep->axis_type == AXIS_PRECEDING)
1335						ap->selectElement_P(helper);
1336					else
1337						ap->selectElement_F(helper);
1338					currentStep->ft = false;
1339				}
1340				if ( state==  XPATH_EVAL_START)
1341					state=  XPATH_EVAL_END;
1342
1343				vn->push2(); // not the most efficient. good for now
1344				//System.out.println("  --++ push in //");
1345				b = false;
1346				while(ap->iterate()){
1347					if (currentStep->evalPredicates(vn)){
1348						b = true;
1349						break;
1350					}
1351				}
1352				if (b == false) {
1353					vn->pop2();
1354					//System.out.println("  --++ pop in //");
1355					currentStep->ft = true;
1356					currentStep->resetP_s(vn);
1357					if ( state==  XPATH_EVAL_FORWARD){
1358						state =  XPATH_EVAL_BACKWARD;
1359						currentStep = currentStep->prevS;
1360					}
1361				} else {
1362					if (currentStep->nextS != NULL){
1363						state =  XPATH_EVAL_FORWARD;
1364						currentStep = currentStep->nextS;
1365					}
1366					else {
1367						//vn.pop();
1368						state =  XPATH_EVAL_TERMINAL;
1369						result = vn->getCurrentIndex();
1370						if ( isUnique(result))
1371							return result;
1372					}
1373				}
1374				break;
1375
1376			case XPATH_EVAL_END:
1377				currentStep = NULL;
1378				// reset();
1379				return -1;
1380
1381			case XPATH_EVAL_BACKWARD:
1382				//currentStep = currentStep->prevS;
1383				ap = currentStep->o;
1384				//vn.push();
1385				b = false;
1386				while(ap->iterate()){
1387					if (currentStep->evalPredicates(vn)){
1388						b = true;
1389						break;
1390					}
1391				}
1392				if (b == false) {
1393					vn->pop2();
1394					currentStep->ft = true;
1395					currentStep->resetP_s(vn);
1396					//System.out.println("  --++ pop in //");
1397					if (currentStep->prevS != NULL) {
1398						state=  XPATH_EVAL_BACKWARD;
1399						currentStep = currentStep->prevS;
1400					} else
1401						state=  XPATH_EVAL_END;
1402				} else {
1403					if (currentStep->nextS != NULL) {
1404						//vn.push();
1405						//System.out.println("  --++ push in //");
1406						state=  XPATH_EVAL_FORWARD;
1407						currentStep = currentStep->nextS;
1408					} else {
1409						state=  XPATH_EVAL_TERMINAL;
1410						result = vn->getCurrentIndex();
1411						if ( isUnique(result))
1412							return result;
1413					}
1414				}
1415				break;
1416
1417			case XPATH_EVAL_TERMINAL:
1418				ap = currentStep->o;
1419				b = false;
1420				while (ap->iterate()) {
1421					if (currentStep->evalPredicates(vn)) {
1422						b = true;
1423						break;
1424					}
1425				}
1426				if (b == true) {
1427					if (currentStep->evalPredicates(vn)) {
1428						result = vn->getCurrentIndex();
1429						if (isUnique(result))
1430							return result;
1431					}
1432				} else if (currentStep->prevS == NULL) {
1433					currentStep->resetP_s(vn);
1434					vn->pop2();
1435					state= XPATH_EVAL_END;
1436				} else {
1437					vn->pop2();
1438					currentStep->ft = true;
1439					currentStep->resetP_s(vn);
1440					//System.out.println(" --++ pop in //");
1441					state= XPATH_EVAL_BACKWARD;
1442					//currentStep.ft = true;
1443					currentStep = currentStep->prevS;
1444				}
1445				break;
1446
1447			default:
1448				throw XPathEvalException(
1449					"unknown state");
1450	}
1451	return -2;
1452}
1453int LocationPathExpr::process_following_sibling(VTDNav *vn){
1454
1455	bool b = false, b1 = false;
1456	//int contextSize;
1457	Predicate *t= NULL;
1458	int result;
1459	switch( state){
1460		  case  XPATH_EVAL_START:
1461		  case  XPATH_EVAL_FORWARD:
1462
1463			  t = currentStep->p;
1464			  while(t!=NULL){
1465				  if (t->requireContextSize_p()){
1466					  int i = computeContextSize( t,vn);
1467					  if (i==0){
1468						  b1 = true;
1469						  break;
1470					  }else
1471						  t->setContextSize_p(i);
1472				  }
1473				  t = t->nextP;
1474			  }
1475			  if (b1){
1476				  if (state == XPATH_EVAL_FORWARD){
1477					  state= XPATH_EVAL_BACKWARD;
1478					  currentStep = currentStep->prevS;
1479				  }else
1480					  state= XPATH_EVAL_END;
1481				  break;
1482			  }
1483			  if ( state==  XPATH_EVAL_START)
1484				  state=  XPATH_EVAL_END;
1485			  else
1486				  state=  XPATH_EVAL_BACKWARD;
1487			  vn->push2();
1488			  while (vn->toElement(NEXT_SIBLING)){
1489				  if (currentStep->eval_s(vn)){
1490					  if (currentStep->nextS!=NULL){
1491						  state=  XPATH_EVAL_FORWARD;
1492						  currentStep = currentStep->nextS;
1493						  break;
1494					  } else {
1495						  state=  XPATH_EVAL_TERMINAL;
1496						  result = vn->getCurrentIndex();
1497						  if ( isUnique(result))
1498							  return result;
1499					  }
1500				  }
1501			  }
1502
1503			  if ( state==  XPATH_EVAL_END){
1504				  currentStep->resetP_s(vn);
1505				  vn->pop2();
1506			  }else if ( state==  XPATH_EVAL_BACKWARD){
1507				  currentStep->resetP_s(vn);
1508				  vn->pop2();
1509				  currentStep = currentStep->prevS;
1510			  }
1511			  break;
1512
1513		  case  XPATH_EVAL_END:
1514			  currentStep = NULL;
1515			  // reset();
1516			  return -1;
1517
1518		  case  XPATH_EVAL_BACKWARD:
1519			  while (vn->toElement(NEXT_SIBLING)){
1520				  if (currentStep->eval_s(vn)){
1521					  if (currentStep->nextS!=NULL){
1522						  state=  XPATH_EVAL_FORWARD;
1523						  currentStep = currentStep->nextS;
1524						  b = true;
1525						  break;
1526					  } else {
1527						  state=  XPATH_EVAL_TERMINAL;
1528						  result = vn->getCurrentIndex();
1529						  if ( isUnique(result))
1530							  return result;
1531					  }
1532				  }
1533			  }
1534			  if (b==false){
1535				  vn->pop2();
1536				  currentStep->resetP_s(vn);
1537				  if (currentStep->prevS==NULL){
1538					  state=  XPATH_EVAL_END;
1539				  }else{
1540					  state=  XPATH_EVAL_BACKWARD;
1541					  currentStep = currentStep->prevS;
1542				  }
1543			  }
1544			  break;
1545
1546		  case  XPATH_EVAL_TERMINAL:
1547			  while (vn->toElement(NEXT_SIBLING)){
1548				  if (currentStep->eval_s(vn)){
1549					  // state=  XPATH_EVAL_TERMINAL;
1550					  result = vn->getCurrentIndex();
1551					  if ( isUnique(result))
1552						  return result;
1553				  }
1554			  }
1555			  vn->pop2();
1556			  currentStep->resetP_s(vn);
1557			  if(currentStep->prevS!=NULL){
1558				  currentStep = currentStep->prevS;
1559				  state=  XPATH_EVAL_BACKWARD;
1560			  }else{
1561				  state=  XPATH_EVAL_END;
1562			  }
1563			  break;
1564
1565		  default:
1566			  throw XPathEvalException("unknown state");
1567	}
1568	return -2;
1569}
1570int LocationPathExpr::process_parent(VTDNav *vn){
1571	bool /*b = false,*/ b1 = false;
1572	Predicate *t= NULL;
1573	int result;
1574	switch ( state) {
1575			case  XPATH_EVAL_START:
1576			case  XPATH_EVAL_FORWARD:
1577				t = currentStep->p;
1578				while(t!=NULL){
1579					if (t->requireContextSize_p()){
1580						int i = computeContextSize(t,vn);
1581						if (i==0){
1582							b1 = true;
1583							break;
1584						}else
1585							t->setContextSize_p(i);
1586					}
1587					t = t->nextP;
1588				}
1589				if (b1){
1590					if (state == XPATH_EVAL_FORWARD){
1591						state= XPATH_EVAL_BACKWARD;
1592						currentStep = currentStep->prevS;
1593					}else
1594						state= XPATH_EVAL_END;
1595					break;
1596				}
1597
1598				if (vn->getCurrentDepth() == -1) {
1599					if ( state==  XPATH_EVAL_START)
1600						state=  XPATH_EVAL_END;
1601					else {
1602						//vn.pop();
1603						state=  XPATH_EVAL_BACKWARD;
1604						currentStep = currentStep->prevS;
1605					}
1606				} else {
1607					vn->push2();
1608					vn->toElement(PARENT); // must return true
1609					if (currentStep->eval_s(vn)){
1610						if (currentStep->nextS != NULL) {
1611							state=  XPATH_EVAL_FORWARD;
1612							currentStep = currentStep->nextS;
1613						} else {
1614							state=  XPATH_EVAL_TERMINAL;
1615							result = vn->getCurrentIndex();
1616							if ( isUnique(result))
1617								return result;
1618						}
1619					}else{
1620						vn->pop2();
1621						currentStep->resetP_s(vn);
1622						if ( state==  XPATH_EVAL_START)
1623							state=  XPATH_EVAL_END;
1624						else {
1625							state=  XPATH_EVAL_BACKWARD;
1626							currentStep = currentStep->prevS;
1627						}
1628					}
1629				}
1630
1631				break;
1632
1633			case  XPATH_EVAL_END:
1634				currentStep = NULL;
1635				// reset();
1636				return -1;
1637
1638			case  XPATH_EVAL_BACKWARD:
1639			case  XPATH_EVAL_TERMINAL:
1640				if (currentStep->prevS == NULL) {
1641					vn->pop2();
1642					state=  XPATH_EVAL_END;
1643					break;
1644				}else {
1645					vn->pop2();
1646					state=  XPATH_EVAL_BACKWARD;
1647					currentStep = currentStep->prevS;
1648					break;
1649				}
1650
1651			default:
1652				throw XPathEvalException("unknown state");
1653
1654	}
1655	return -2;
1656}
1657int LocationPathExpr::process_preceding_sibling(VTDNav *vn){
1658
1659	bool b = false, b1 = false;
1660	Predicate *t= NULL;
1661	int result;
1662	switch(state){
1663		  case  XPATH_EVAL_START:
1664		  case  XPATH_EVAL_FORWARD:
1665			  t = currentStep->p;
1666			  while(t!=NULL){
1667				  if (t->requireContextSize_p()){
1668					  int i = computeContextSize(t,vn);
1669					  if (i==0){
1670						  b1 = true;
1671						  break;
1672					  }else
1673						  t->setContextSize_p(i);
1674				  }
1675				  t = t->nextP;
1676			  }
1677			  if (b1){
1678				  if (state == XPATH_EVAL_FORWARD){
1679					  state= XPATH_EVAL_BACKWARD;
1680					  currentStep = currentStep->prevS;
1681				  }else
1682					  state= XPATH_EVAL_END;
1683				  break;
1684			  }
1685			  if ( state==  XPATH_EVAL_START)
1686				  state=  XPATH_EVAL_END;
1687			  else
1688				  state=  XPATH_EVAL_BACKWARD;
1689			  vn->push2();
1690			  while (vn->toElement(PREV_SIBLING)){
1691				  if (currentStep->eval_s(vn)){
1692					  if (currentStep->nextS!=NULL){
1693						  state=  XPATH_EVAL_FORWARD;
1694						  currentStep = currentStep->nextS;
1695						  break;
1696					  } else {
1697						  state=  XPATH_EVAL_TERMINAL;
1698						  result = vn->getCurrentIndex();
1699						  if ( isUnique(result))
1700							  return result;
1701					  }
1702				  }
1703			  }
1704
1705			  if ( state==  XPATH_EVAL_END){
1706				  currentStep->resetP_s(vn);
1707				  vn->pop2();
1708			  }else if ( state==  XPATH_EVAL_BACKWARD){
1709				  currentStep->resetP_s(vn);
1710				  vn->pop2();
1711				  currentStep = currentStep->prevS;
1712			  }
1713			  break;
1714
1715		  case  XPATH_EVAL_END:
1716			  currentStep = NULL;
1717			  // reset();
1718			  return -1;
1719
1720		  case  XPATH_EVAL_BACKWARD:
1721			  while (vn->toElement(PREV_SIBLING)){
1722				  if (currentStep->eval_s(vn)){
1723					  if (currentStep->nextS!=NULL){
1724						  state=  XPATH_EVAL_FORWARD;
1725						  currentStep = currentStep->nextS;
1726						  b = true;
1727						  break;
1728					  } else {
1729						  state=  XPATH_EVAL_TERMINAL;
1730						  result = vn->getCurrentIndex();
1731						  if ( isUnique(result))
1732							  return result;
1733					  }
1734				  }
1735			  }
1736			  if (b==false){
1737				  vn->pop2();
1738				  currentStep->resetP_s(vn);
1739				  if (currentStep->prevS==NULL){
1740					  state=  XPATH_EVAL_END;
1741				  }else{
1742					  state=  XPATH_EVAL_BACKWARD;
1743					  currentStep = currentStep->prevS;
1744				  }
1745			  }
1746			  break;
1747
1748		  case  XPATH_EVAL_TERMINAL:
1749			  while (vn->toElement(PREV_SIBLING)){
1750				  if (currentStep->eval_s(vn)){
1751					  // state =  XPATH_EVAL_TERMINAL;
1752					  result = vn->getCurrentIndex();
1753					  if ( isUnique(result))
1754						  return result;
1755				  }
1756			  }
1757			  vn->pop2();
1758			  if(currentStep->prevS!=NULL){
1759				  currentStep = currentStep->prevS;
1760				  state=  XPATH_EVAL_BACKWARD;
1761			  }else{
1762				  state=  XPATH_EVAL_END;
1763			  }
1764			  break;
1765
1766		  default:
1767			  throw XPathEvalException("unknown state");
1768	}
1769	return -2;
1770}
1771int LocationPathExpr::process_self(VTDNav *vn){		
1772	
1773	bool /*b = false,*/ b1 = false;
1774	    //int contextSize;
1775	    Predicate *t= NULL;
1776	    int result;
1777		switch( state){
1778		  case  XPATH_EVAL_START:
1779		  case  XPATH_EVAL_FORWARD:
1780  	        t = currentStep->p;
1781	        while(t!=NULL){
1782	            if (t->requireContextSize_p()){
1783	                int i = computeContextSize(t,vn);
1784	                if (i==0){
1785	                    b1 = true;
1786	                    break;
1787	                }else
1788	                    t->setContextSize_p(i);
1789	            }
1790	            t = t->nextP;
1791	        }
1792	        if (b1){
1793	            if (state == XPATH_EVAL_FORWARD){
1794	                state= XPATH_EVAL_BACKWARD;
1795	                currentStep = currentStep->prevS;
1796	            }else
1797	                state= XPATH_EVAL_END;
1798	            break;
1799	        }
1800		  	if (currentStep->eval_s(vn)){
1801		  		if (currentStep->nextS!=NULL){
1802		  			 state=  XPATH_EVAL_FORWARD;
1803		  			currentStep = currentStep->nextS;
1804		  		}
1805		  		else{
1806		  			 state=  XPATH_EVAL_TERMINAL;
1807		  			 if (vn->atTerminal == true)
1808		  			     result = vn->LN;
1809		  			 else
1810		  			     result = vn->getCurrentIndex();
1811					if ( isUnique(result))
1812						return result;
1813		  		}
1814		  	}else {
1815		  		currentStep->resetP_s(vn);
1816		  		if ( state==  XPATH_EVAL_START)
1817		  			 state=  XPATH_EVAL_END;
1818		  		else
1819		  			 state=  XPATH_EVAL_BACKWARD;
1820		  	}
1821		    break;
1822
1823		  case  XPATH_EVAL_END:
1824		  	currentStep = NULL;
1825		  	// reset();
1826		  	return -1;
1827
1828		  case  XPATH_EVAL_BACKWARD:
1829		  case  XPATH_EVAL_TERMINAL:
1830		  	if (currentStep->prevS!=NULL){
1831	  			 state=  XPATH_EVAL_BACKWARD;
1832	  			currentStep= currentStep->prevS;
1833	  		}else{
1834	  			 state=  XPATH_EVAL_END;
1835	  		}
1836		  	break;
1837
1838		  default:
1839			throw XPathEvalException("unknown state");
1840		}
1841	    return -2;
1842}
1843int LocationPathExpr::process_namespace(VTDNav *vn){
1844	AutoPilot *ap = NULL;
1845	bool b1 = false;
1846	Predicate *t= NULL;
1847	int temp;
1848	switch(state){
1849		case  XPATH_EVAL_START:
1850		case  XPATH_EVAL_FORWARD:
1851
1852			t = currentStep->p;
1853			while(t!=NULL){
1854				if (t->requireContextSize_p()){
1855					int i = computeContextSize(t,vn);
1856					if (i==0){
1857						b1 = true;
1858						break;
1859					}else
1860						t->setContextSize_p(i);
1861				}
1862				t = t->nextP;
1863			}
1864			if (b1){
1865				if (state == XPATH_EVAL_FORWARD){
1866					state= XPATH_EVAL_BACKWARD;
1867					currentStep = currentStep->prevS;
1868				}else
1869					state= XPATH_EVAL_END;
1870				break;
1871			}
1872
1873			if (vn->getAtTerminal()==true){
1874				if (state ==XPATH_EVAL_START)
1875					state = XPATH_EVAL_END;
1876				else {
1877					state = XPATH_EVAL_BACKWARD;
1878					currentStep  = currentStep->prevS;
1879				}
1880			} else {
1881				if (currentStep->ft == true) {
1882					if (currentStep->o == NULL)
1883						currentStep->o = ap = new AutoPilot(vn);
1884					else {
1885						ap = currentStep->o;
1886						ap->bind(vn);
1887					}
1888					if (currentStep->nt->testType== NT_NODE)
1889						ap->selectNameSpace((UCSChar *)L"*");
1890					else 
1891						ap->selectNameSpace(currentStep->nt->nodeName);
1892					currentStep->ft = false;
1893				}
1894				if ( state==  XPATH_EVAL_START)
1895					state=  XPATH_EVAL_END;
1896				vn->push2();
1897				//vn->setAtTerminal(true);
1898				while( (temp = ap->iterateNameSpace()) != -1){
1899					if (currentStep->evalPredicates(vn)){
1900						break;
1901					}
1902				}
1903				if (temp == -1){
1904					currentStep->ft = true;
1905					currentStep->resetP_s(vn);
1906					vn->setAtTerminal(false);
1907					if ( state==  XPATH_EVAL_FORWARD){
1908						state =  XPATH_EVAL_BACKWARD;
1909						currentStep = currentStep->prevS;
1910					}
1911				}else {
1912
1913					if (currentStep->nextS != NULL){
1914						vn->LN = temp;
1915						state=  XPATH_EVAL_FORWARD;
1916						currentStep = currentStep->nextS;
1917					}
1918					else {
1919						//vn.pop();
1920						state=  XPATH_EVAL_TERMINAL;
1921						if ( isUnique(temp)){
1922							vn->LN = temp;
1923							return temp;
1924						}
1925					}
1926
1927				}
1928			}
1929			break;
1930
1931		case  XPATH_EVAL_END:
1932			currentStep = NULL;
1933			// reset();
1934			return -1;
1935
1936		case  XPATH_EVAL_BACKWARD:
1937			ap = currentStep->o;
1938			//vn.push();
1939			while( (temp = ap->iterateNameSpace()) != -1){
1940				if (currentStep->evalPredicates(vn)){
1941					break;
1942				}
1943			}
1944			if (temp == -1) {
1945				vn->pop2();
1946				currentStep->ft = true;
1947				//freeAutoPilot(currentStep->o);
1948				//currentStep->o = NULL;
1949				currentStep->resetP_s(vn);
1950				vn->setAtTerminal(false);
1951				if (currentStep->prevS != NULL) {
1952					state =  XPATH_EVAL_BACKWARD;
1953					currentStep = currentStep->prevS;
1954				} else
1955					state =  XPATH_EVAL_END;
1956			} else {
1957				if (currentStep->nextS != NULL) {
1958					state =  XPATH_EVAL_FORWARD;
1959					currentStep = currentStep->nextS;
1960				} else {
1961					state =  XPATH_EVAL_TERMINAL;
1962					if ( isUnique(temp)){
1963						vn->LN = temp;
1964						return temp;
1965					}
1966				}
1967			}
1968			break;
1969
1970		case  XPATH_EVAL_TERMINAL:
1971			ap = currentStep->o;
1972			while( (temp = ap->iterateNameSpace()) != -1){
1973				if (currentStep->evalPredicates(vn)){
1974					break;
1975				}
1976			}
1977			if (temp != -1)
1978				if (isUnique(temp)){
1979					vn->LN = temp;
1980					return temp;
1981				}
1982				vn->setAtTerminal(false);
1983				currentStep->resetP_s(vn);
1984				if (currentStep->prevS == NULL) {
1985					currentStep->ft = true;
1986					//freeAutoPilot(currentStep->o);
1987					//currentStep->o = NULL;
1988					vn->pop2();
1989					state=  XPATH_EVAL_END;
1990				} else {
1991					state=  XPATH_EVAL_BACKWARD;
1992					vn->pop2();
1993					currentStep->ft = true;
1994					//freeAutoPilot(currentStep->o);
1995					//currentStep->o = NULL;
1996					currentStep = currentStep->prevS;
1997				}
1998
1999				break;
2000
2001		default:
2002			throw XPathEvalException(
2003				"unknown state");
2004	}
2005	return -2;
2006}
2007void LocationPathExpr::selectNodeType(TextIter *ti){
2008		if (currentStep->nt->testType == NT_T

Large files files are truncated, but you can click here to view the full file