diff --git a/mozilla/content/xslt/src/base/txDouble.cpp b/mozilla/content/xslt/src/base/txDouble.cpp new file mode 100644 index 00000000000..f4730bef4ae --- /dev/null +++ b/mozilla/content/xslt/src/base/txDouble.cpp @@ -0,0 +1,238 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + + + +#include "primitives.h" + +//----------------------------/ +//- Implementation of Double -/ +//----------------------------/ +/** + * A wrapper for the primitive double type, and provides some simple + * floating point related routines + * @author Larry Fitzpatrick + * @author Keith Visco +**/ + +double d0 = 0.0; + +const double Double::NaN = (d0/d0); +const double Double::NEGATIVE_INFINITY = (-1.0/d0); +const double Double::POSITIVE_INFINITY = (1.0/d0); + +/** + * Creates a new Double with it's value initialized to 0; +**/ +Double::Double() { + value = 0; +} //-- Double + +/** + * Creates a new Double with it's value initialized to the given double +**/ +Double::Double(double dbl) { + this->value = dbl; +} //-- Double + +/** + * Creates a new Double with it's value initialized from the given String. + * The String will be converted to a double. If the String does not + * represent an IEEE 754 double, the value will be initialized to NaN +**/ +Double::Double(const String& string) { + this->value = toDouble(string); +} //-- Double + + + +/** + * Returns the value of this Double as a double +**/ +double Double::doubleValue() { + return this->value; +} //-- doubleValue + +/** + * Returns the value of this Double as an int +**/ +int Double::intValue() { + return (int)value; +} //-- intValue + +/** + * Determins whether the given double represents positive or negative + * inifinity +**/ +MBool Double::isInfinite(double dbl) { + return (MBool)((dbl == POSITIVE_INFINITY ) || (dbl == NEGATIVE_INFINITY)); +} //-- isInfinite + +/** + * Determins whether this Double's value represents positive or + * negative inifinty +**/ +MBool Double::isInfinite() { + return (MBool)(( value == POSITIVE_INFINITY ) || (value == NEGATIVE_INFINITY)); +} //-- isInfinite + +/** + * Determins whether the given double is NaN +**/ +MBool Double::isNaN(double dbl) { +#ifdef MOZILLA + return (MBool) _isnan(dbl); +#else + return (MBool) isnan(dbl); +#endif +} //-- isNaN + +/** + * Determins whether this Double's value is NaN +**/ +MBool Double::isNaN() { +#ifdef MOZILLA + return (MBool) _isnan(value); +#else + return (MBool) isnan(value); +#endif +} //-- isNaN + +/** + * Converts the given String to a double, if the String value does not + * represent a double, NaN will be returned +**/ +double Double::toDouble(const String& src) { + + double dbl = 0.0; + double fraction = 1.0; + double multiplier = 10.0; + Int32 idx = 0; + + double sign = 1.0; + + //-- trim leading whitespace + for ( ; idx < src.length(); idx++ ) + if ( src.charAt(idx) != ' ' ) break; + + //-- check first character for sign + if ( idx < src.length() ) { + Int32 ch = src.charAt(idx); + if ( ch == '-' ) { + sign = -1.0; + ++idx; + } + } + else { + return Double::NaN; + } + + //-- convert remaining to number + for ( ; idx < src.length(); idx++ ) { + + Int32 ch = src.charAt(idx); + + if (( ch >= '0') && (ch <= '9')) { + if ( multiplier > 1.0 ) { + dbl = dbl*multiplier; + dbl += (double) (ch-48); + } + else { + dbl += multiplier * (ch-48); + multiplier = multiplier * 0.1; + } + } + else if ( ch == '.') { + if ( multiplier < 1.0 ) return Double::NaN; + multiplier = 0.1; + } + else return Double::NaN; + } + dbl = dbl*sign; + return dbl; +} //-- toDouble + + +/** + * Converts the value of this Double to a String, and places + * The result into the destination String. + * @return the given dest string +**/ +String& Double::toString(String& dest) { + return toString(value, dest); +} //-- toString + +/** + * Converts the value of the given double to a String, and places + * The result into the destination String. + * @return the given dest string +**/ +String& Double::toString(double value, String& dest) { + + //-- check for special cases + + if ( isNaN(value) ) { + dest.append("NaN"); + return dest; + } + if ( isInfinite(value) ) { + if (value < 0) dest.append('-'); + dest.append("Infinity"); + return dest; + } + + MBool isNegative = (MBool)(value<0.0); + double val = value; + if ( isNegative ) val = val * -1.0; + + double ival = 0; + double fval = modf(val, &ival); + + String iStr; + + int temp = (int)ival; + + + if ( temp > 0.0 ) { + while ( temp > 0.0 ) { + iStr.append( (char) ((temp % 10)+48) ); + temp = temp / 10; + } + if ( isNegative ) iStr.append('-'); + iStr.reverse(); + } + else iStr.append('0'); + + iStr.append('.'); + if ( fval > 0.0 ) { + while ( fval > 0.0000001 ) { + fval = fval*10.0; + fval = modf(fval, &ival); + iStr.append( (char) (ival+48) ); + } + } + else iStr.append('0'); + + dest.append(iStr); + return dest; +} //-- toString + + diff --git a/mozilla/content/xslt/src/base/txErrorObserver.h b/mozilla/content/xslt/src/base/txErrorObserver.h new file mode 100644 index 00000000000..c5150fd261f --- /dev/null +++ b/mozilla/content/xslt/src/base/txErrorObserver.h @@ -0,0 +1,96 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#ifndef MITRE_ERROROBSERVER_H +#define MITRE_ERROROBSERVER_H + +#include "baseutils.h" +#include "String.h" +#include "iostream.h" + +/** + * A simple interface for observing errors + * @author Keith Visco +**/ +class ErrorObserver { + +public: + + enum ErrorLevel {FATAL = 0, NORMAL, WARNING}; + + /** + * Default Destructor for ErrorObserver + **/ + virtual ~ErrorObserver() {}; + + /** + * Notifies this Error observer of a new error, with default + * level of NORMAL + **/ + virtual void recieveError(String& errorMessage) = 0; + + /** + * Notifies this Error observer of a new error using the given error level + **/ + virtual void recieveError(String& errorMessage, ErrorLevel level) = 0; + +}; //-- ErrorObserver + +/** + * A simple ErrorObserver which allows printing error messages to a stream +**/ +class SimpleErrorObserver : public ErrorObserver { + +public: + + /** + * Creates a new SimpleErrorObserver. + * All errors will be printed to the console (cout). + **/ + SimpleErrorObserver(); + + /** + * Creates a new SimpleErrorObserver. + * All errors will be printed to the given ostream. + **/ + SimpleErrorObserver(ostream& errStream); + + virtual ~SimpleErrorObserver() {}; + + /** + * Notifies this Error observer of a new error, with default + * level of NORMAL + **/ + virtual void recieveError(String& errorMessage); + + /** + * Notifies this Error observer of a new error using the given error level + **/ + virtual void recieveError(String& errorMessage, ErrorLevel level); + + virtual void supressWarnings(MBool supress); + +private: + + ostream* errStream; + MBool hideWarnings; +}; //-- SimpleErrorObserver +#endif diff --git a/mozilla/content/xslt/src/base/txList.cpp b/mozilla/content/xslt/src/base/txList.cpp new file mode 100644 index 00000000000..c9136a6f269 --- /dev/null +++ b/mozilla/content/xslt/src/base/txList.cpp @@ -0,0 +1,319 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "List.h" +#include + //--------------------------/ + //- Implementation of List -/ +//--------------------------/ + +/** + * Default constructor for a List; +**/ +List::List() { + firstItem = 0; + lastItem = 0; + itemCount = 0; +} //-- List; + +/** + * List destructor, cleans up List Items, but will not delete the Object + * references +*/ +List::~List() { + ListItem* item = firstItem; + while (item) { + ListItem* tItem = item; + item = item->nextItem; + delete tItem; + } +} //-- ~List + +void List::insert(int index, void* objPtr) { + + if ( index >= itemCount ) { + insertBefore(objPtr, 0); + } + else { + //-- add to middle of list + ListItem* nextItem = firstItem; + for ( int i = 0; i < index; i++ ) nextItem = nextItem->nextItem; + insertBefore(objPtr, nextItem); + } +} //-- insert + +void List::add(void* objPtr) { + insert(itemCount, objPtr); +} //-- add + +List::ListItem* List::getFirstItem() { + return firstItem; +} //-- getFirstItem + +List::ListItem* List::getLastItem() { + return lastItem; +} //-- getLastItem + +/** + * Returns the number of items in this List +**/ +Int32 List::getLength() { + return itemCount; +} //-- getLength + + +/** + * Inserts the given Object pointer as the item just after refItem. + * If refItem is a null pointer the Object will be inserted at the + * beginning of the List (ie, insert after nothing). + * This method assumes refItem is a member of this list, and since this + * is a private method, I feel that's a valid assumption +**/ +void List::insertAfter(void* objPtr, ListItem* refItem) { + //-- if refItem == null insert at front + if (!refItem) insertBefore(objPtr, firstItem); + else insertBefore(objPtr, refItem->nextItem); +} //-- insertAfter + +/** + * Inserts the given Object pointer as the item just before refItem. + * If refItem is a null pointer the Object will be inserted at the + * end of the List (ie, insert before nothing). + * This method assumes refItem is a member of this list, and since this + * is a private method, I feel that's a valid assumption +**/ +void List::insertBefore(void* objPtr, ListItem* refItem) { + + ListItem* item = new ListItem; + item->objPtr = objPtr; + item->nextItem = 0; + item->prevItem = 0; + + //-- if refItem == null insert at end + if (!refItem) { + //-- add to back of list + if ( lastItem ) { + lastItem->nextItem = item; + item->prevItem = lastItem; + } + lastItem = item; + if ( !firstItem ) firstItem = item; + } + else { + //-- insert before given item + item->nextItem = refItem; + item->prevItem = refItem->prevItem; + refItem->prevItem = item; + + if (refItem == firstItem) firstItem = item; + if (itemCount == 0) lastItem = item; // <-should we ever see this? + } + + // increase the item count + ++itemCount; +} //-- insertBefore + +/** + * Returns a ListIterator for this List +**/ +ListIterator* List::iterator() { + return new ListIterator(this); +} + +void* List::remove(void* objPtr) { + ListItem* item = firstItem; + while (item) { + if (item->objPtr == objPtr) { + remove(item); + delete item; + return objPtr; + } + item = item->nextItem; + } + // not in list + return 0; +} //-- remove + +List::ListItem* List::remove(ListItem* item) { + + if ( !item ) return item; + + //-- adjust the previous item's next pointer + if (item->prevItem) { + item->prevItem->nextItem = item->nextItem; + } + //-- adjust the next item's previous pointer + if ( item->nextItem ) { + item->nextItem->prevItem = item->prevItem; + } + + //-- adjust first and last items + if (item == firstItem) firstItem = item->nextItem; + if (item == lastItem) lastItem = item->prevItem; + + //-- decrease Item count + --itemCount; + return item; +} //-- remove + + //----------------------------------/ + //- Implementation of ListIterator -/ +//----------------------------------/ + + +/** + * Creates a new ListIterator for the given List + * @param list, the List to create an Iterator for +**/ +ListIterator::ListIterator(List* list) { + this->list = list; + currentItem = 0; + allowRemove = MB_FALSE; + moveForward = MB_TRUE; + done = MB_FALSE; + count = 0; +} //-- ListIterator + +ListIterator::~ListIterator() { + //-- overrides default destructor to do nothing +} //-- ~ListIterator + +/** + * Adds the Object pointer to the List pointed to by this ListIterator. + * The Object pointer is inserted as the next item in the List + * based on the current position within the List + * @param objPtr the Object pointer to add to the list +**/ +void ListIterator::add(void* objPtr) { + + list->insertAfter(objPtr,currentItem); + allowRemove = MB_FALSE; + +} //-- add + +/** + * Returns true if a sucessful call to the next() method can be made + * @return MB_TRUE if a sucessful call to the next() method can be made, + * otherwise MB_FALSE +**/ +MBool ListIterator::hasNext() { + MBool hasNext = MB_FALSE; + if ( done ) return hasNext; + else if ( currentItem ) { + if (moveForward) hasNext = (MBool) currentItem->nextItem; + else hasNext = (MBool)currentItem->prevItem; + } + else { + if (moveForward) hasNext = (MBool) list->firstItem; + else hasNext = (MBool) list->lastItem; + } + return hasNext; +} //-- hasNext + +/** + * Returns true if a sucessful call to the previous() method can be made + * @return MB_TRUE if a sucessful call to the previous() method can be made, + * otherwise MB_FALSE +**/ +MBool ListIterator::hasPrevious() { + MBool hasPrevious = MB_FALSE; + if (currentItem) { + if (moveForward) hasPrevious = (MBool)(currentItem->prevItem); + else hasPrevious = (MBool) (currentItem->nextItem); + } + return hasPrevious; +} //-- hasPrevious + +/** + * Returns the next Object pointer in the list +**/ +void* ListIterator::next() { + + void* obj = 0; + if ( done ) return obj; + + if (currentItem) { + if ( moveForward ) currentItem = currentItem->nextItem; + else currentItem = currentItem->prevItem; + } + else { + if ( moveForward ) currentItem = list->firstItem; + else currentItem = list->lastItem; + } + + if ( currentItem ) { + obj = currentItem->objPtr; + allowRemove = MB_TRUE; + } + else done = MB_TRUE; + + return obj; +} //-- next + +/** + * Returns the previous Object in the list +**/ +void* ListIterator::previous() { + + void* obj = 0; + + if (currentItem) { + if ( moveForward ) currentItem = currentItem->prevItem; + else currentItem = currentItem->nextItem; + if ( currentItem ) obj = currentItem->objPtr; + } + return obj; +} //-- previous + +/** + * Removes the Object last returned by the next() or previous() methods; + * @return the removed Object pointer +**/ +void* ListIterator::remove() { + + if (!allowRemove) return 0; + allowRemove = MB_FALSE; + + void* obj = 0; + if (currentItem) { + obj = currentItem->objPtr; + List::ListItem* item = currentItem; + previous(); //-- make previous item the current item + list->remove(item); + } + return obj; +} //-- remove + +/** + * Resets the current location within the List to the beginning of the List +**/ +void ListIterator::reset() { + done = MB_FALSE; + currentItem = 0; +} //-- reset + +/** + * sets this iterator to operate in the reverse direction +**/ +void ListIterator::reverse() { + moveForward = (MBool)(!moveForward); +} //-- reverse + diff --git a/mozilla/content/xslt/src/base/txList.h b/mozilla/content/xslt/src/base/txList.h new file mode 100644 index 00000000000..a147c115149 --- /dev/null +++ b/mozilla/content/xslt/src/base/txList.h @@ -0,0 +1,188 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "baseutils.h" + +#ifndef MITRE_LIST_H +#define MITRE_LIST_H + +/** + * Represents an ordered list of Object pointers. Modeled after a Java 2 List. + * @author Keith Visco +**/ +class List { + +friend class ListIterator; + +public: + + /** + * Creates an empty List + **/ + List(); + + /** + * List destructor, object references will not be deleted. + **/ + virtual ~List(); + + /** + * Returns the number of items in this List + **/ + Int32 getLength(); + + /** + * Returns a ListIterator for this List + **/ + ListIterator* iterator(); + + /** + * Adds the given Object to the specified position in the list + **/ + void insert(int index, void* objPtr); + + /** + * Adds the given Object to the list + **/ + void add(void* objPtr); + + /** + * Removes the given Object pointer from the list + **/ + void* remove(void* objPtr); + + +protected: + + struct ListItem { + ListItem* nextItem; + ListItem* prevItem; + void* objPtr; + }; + + ListItem* getFirstItem(); + ListItem* getLastItem(); + + /** + * Removes the given ListItem pointer from the list + **/ + ListItem* remove(ListItem* sItem); + +private: + + ListItem* firstItem; + ListItem* lastItem; + Int32 itemCount; + + void insertAfter(void* objPtr, ListItem* sItem); + void insertBefore(void* objPtr, ListItem* sItem); + +}; + + + +/** + * An Iterator for the List Class + * @author Keith Visco +**/ +class ListIterator { + +public: + + + /** + * Creates a new ListIterator for the given List + * @param list, the List to create an Iterator for + **/ + ListIterator(List* list); + + /** + * Destructor, destroys a given instance of a ListIterator + **/ + virtual ~ListIterator(); + + /** + * Adds the Object pointer to the List pointed to by this ListIterator. + * The Object pointer is inserted as the next item in the List + * based on the current position within the List + * @param objPtr the Object pointer to add to the list + **/ + + virtual void add(void* objPtr); + + /** + * Returns true if a sucessful call to the next() method can be made + * @return MB_TRUE if a sucessful call to the next() method can be made, + * otherwise MB_FALSE + **/ + virtual MBool hasNext(); + + /** + * Returns true if a sucessful call to the previous() method can be made + * @return MB_TRUE if a sucessful call to the previous() method can be made, + * otherwise MB_FALSE + **/ + virtual MBool hasPrevious(); + + /** + * Returns the next Object pointer from the list + **/ + virtual void* next(); + + /** + * Returns the previous Object pointer from the list + **/ + virtual void* previous(); + + /** + * Removes the Object last returned by the next() or previous() methods; + * @return the removed Object pointer + **/ + virtual void* remove(); + + /** + * Resets the current location within the List to the beginning of the List + **/ + virtual void reset(); + + /** + * sets this iterator to operate in the reverse direction + **/ + void reverse(); + +private: + + int count; + //-- points to the current list item + List::ListItem* currentItem; + + //-- points to the list to iterator over + List* list; + + //-- determins if we can remove the current item from the list + MBool allowRemove; + + MBool done; + + MBool moveForward; +}; + +#endif diff --git a/mozilla/content/xslt/src/base/txSimpleErrorObserver.cpp b/mozilla/content/xslt/src/base/txSimpleErrorObserver.cpp new file mode 100644 index 00000000000..bf598199a64 --- /dev/null +++ b/mozilla/content/xslt/src/base/txSimpleErrorObserver.cpp @@ -0,0 +1,76 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "ErrorObserver.h" + +/** + * Creates a new SimpleErrorObserver. + * All errors will be printed to the console (cout). +**/ +SimpleErrorObserver::SimpleErrorObserver() { + errStream = &cout; + hideWarnings = MB_FALSE; +} //-- SimpleErrorObserver + +/** + * Creates a new SimpleErrorObserver. + * All errors will be printed to the given ostream. +**/ +SimpleErrorObserver::SimpleErrorObserver(ostream& errStream) { + this->errStream = &errStream; + hideWarnings = MB_FALSE; +} //-- SimpleErrorObserver + +/** + * Notifies this Error observer of a new error, with default + * level of NORMAL +**/ +void SimpleErrorObserver::recieveError(String& errorMessage) { + *errStream << "error: " << errorMessage << endl; + errStream->flush(); +} //-- recieveError + +/** + * Notifies this Error observer of a new error using the given error level +**/ +void SimpleErrorObserver::recieveError(String& errorMessage, ErrorLevel level) { + + + switch ( level ) { + case ErrorObserver::FATAL : + *errStream << "fatal error: "; + break; + case ErrorObserver::WARNING : + if ( hideWarnings ) return; + *errStream << "warning: "; + break; + default: + *errStream << "error: "; + break; + } + + *errStream << errorMessage << endl; + errStream->flush(); +} //-- recieveError + +void SimpleErrorObserver::supressWarnings(MBool supress) { + this->hideWarnings = supress; +} //-- supressWarnings diff --git a/mozilla/content/xslt/src/main/transformiix.cpp b/mozilla/content/xslt/src/main/transformiix.cpp new file mode 100644 index 00000000000..ddbc420b8b4 --- /dev/null +++ b/mozilla/content/xslt/src/main/transformiix.cpp @@ -0,0 +1,140 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "XSLProcessor.h" + + //--------------/ + //- Prototypes -/ +//--------------/ + +/** + * Prints the command line help screen to the console +**/ +void printHelp(); + +/** + * prints the command line usage information to the console +**/ +void printUsage(); + +/** + * The TransforMiiX command line interface + * @author Keith Visco +**/ +int main(int argc, char** argv) { + + XSLProcessor xslProcessor; + + String copyright("(C) 1999 The MITRE Corporation"); + cout << xslProcessor.getAppName() << " "; + cout << xslProcessor.getAppVersion() << copyright <length()+1]; + ifstream xmlInput(xmlFilename->toChar(chars), ios::in); + delete chars; + + //-- create document base + String documentBase; + URIUtils::getDocumentBase(*xmlFilename, documentBase); + + //-- handle output stream + ostream* resultOutput = &cout; + ofstream resultFileStream; + if ( outFilename ) { + chars = new char[outFilename->length()+1]; + resultFileStream.open(outFilename->toChar(chars), ios::out); + delete chars; + if ( !resultFileStream ) { + cout << "error opening output file: " << *xmlFilename << endl; + return -1; + } + resultOutput = &resultFileStream; + } + //-- process + if ( !xslFilename ) { + xslProcessor.process(xmlInput, documentBase, *resultOutput); + } + else { + //-- open XSL file + chars = new char[xslFilename->length()+1]; + ifstream xslInput(xslFilename->toChar(chars), ios::in); + delete chars; + xslProcessor.process(xmlInput, xslInput, *resultOutput); + } + resultFileStream.close(); + return 0; +} //-- main + +void printHelp() { + cout << "The following flags are available for use with TransforMiiX -"; + cout<Keith Visco +**/ + +#include "XMLUtils.h" + + //------------------------------/ + //- Implementation of XMLUtils -/ +//------------------------------/ + +const String XMLUtils::XMLNS = "xmlns"; + +void XMLUtils::getNameSpace(const String& src, String& dest) { + + //-- anything preceding ':' is the namespace part of the name + int idx = src.indexOf(':'); + if ( idx > 0 ) { + //-- create new String to prevent any chars in dest from being + //-- lost + String tmp; + src.subString(0,idx, tmp); + dest.append(tmp); + } + else dest.append(""); + +} //-- getNameSpace + +void XMLUtils::getLocalPart(const String& src, String& dest) { + + //-- anything after ':' is the local part of the name + int idx = src.indexOf(':'); + if ( idx < -1 ) idx = -1; + //-- create new String to prevent any chars in dest from being + //-- lost + String tmp; + src.subString(idx+1, tmp); + dest.append(tmp); + +} //-- getLocalPart + +/** + * Returns true if the given character represents an Alpha letter +**/ +MBool XMLUtils::isAlphaChar(Int32 ch) { + if ((ch >= 'a' ) && (ch <= 'z' )) return MB_TRUE; + if ((ch >= 'A' ) && (ch <= 'Z' )) return MB_TRUE; + return MB_FALSE; +} //-- isAlphaChar + +/** + * Returns true if the given character represents a numeric letter (digit) +**/ +MBool XMLUtils::isDigit(Int32 ch) { + if ((ch >= '0') && (ch <= '9')) return MB_TRUE; + return MB_FALSE; +} //-- isDigit + +/** + * Returns true if the given character is an allowable QName character +**/ +MBool XMLUtils::isNCNameChar(Int32 ch) { + if (isDigit(ch) || isAlphaChar(ch)) return MB_TRUE; + return (MBool) ((ch == '.') ||(ch == '_') || (ch == '-')); +} //-- isNCNameChar + +/** + * Returns true if the given character is an allowable NCName character +**/ +MBool XMLUtils::isQNameChar(Int32 ch) { + return (MBool) (( ch == ':') || isNCNameChar(ch)); +} //-- isQNameChar + +/** + * Returns true if the given String is a valid XML QName +**/ +MBool XMLUtils::isValidQName(String& name) { + + int size = name.length(); + if ( size == 0 ) return MB_FALSE; + else if ( !isAlphaChar(name.charAt(0))) return MB_FALSE; + else { + for ( int i = 1; i < size; i++) { + if ( ! isQNameChar(name.charAt(i))) return MB_FALSE; + } + } + return MB_TRUE; +} //-- isValidQName + +/** + * Normalizes the value of an XML attribute +**/ +void XMLUtils::normalizeAttributeValue(String& attValue) { + Int32 size = attValue.length(); + //-- make copy of chars + char* chars = new char[size+1]; + attValue.toChar(chars); + //-- clear attValue + attValue.clear(); + + Int32 cc = 0; + MBool addSpace = MB_FALSE; + while ( cc < size) { + char ch = chars[cc++]; + switch (ch) { + case ' ': + if ( attValue.length() > 0) addSpace = MB_TRUE; + break; + case '\r': + break; + case '\n': + attValue.append(" "); + break; + default: + if ( addSpace) { + attValue.append(' '); + addSpace = MB_FALSE; + } + attValue.append(ch); + break; + } + } + delete chars; +} //-- normalizeAttributeValue + +/** + * Normalizes the value of a XML processing instruction +**/ +void XMLUtils::normalizePIValue(String& piValue) { + Int32 size = piValue.length(); + //-- make copy of chars + char* chars = new char[size+1]; + piValue.toChar(chars); + //-- clear attValue + piValue.clear(); + + Int32 cc = 0; + char prevCh = '\0'; + while ( cc < size) { + char ch = chars[cc++]; + switch (ch) { + case '>': + if ( prevCh == '?' ) { + piValue.append(' '); + } + piValue.append(ch); + break; + default: + piValue.append(ch); + break; + } + prevCh = ch; + } + delete chars; +} //-- noramlizePIValue + +/** + * Strips whitespace from the given String. + * Newlines (#xD), tabs (#x9), and consecutive spaces (#x20) are + * converted to a single space (#x20). + * @param data the String to strip whitespace from + * @param dest the destination String to append the result to +**/ +void XMLUtils::stripSpace (const String& data, String& dest) { + stripSpace(data,dest,MB_FALSE,MB_FALSE); +} //-- stripSpace + +/** + * Strips whitespace from the given String. + * Newlines (#xD), tabs (#x9), and consecutive spaces (#x20) are + * converted to a single space (#x20). + * @param data the String to strip whitespace from + * @param dest the destination String to append the result to + * @param stripAllLeadSpace, a boolean indicating whether or not to + * strip all leading space. If true all whitespace from the start of the + * given String will be stripped. If false, all whitespace from the start + * of the given String will be converted to a single space. + * @param stripAllTrailSpace, a boolean indicating whether or not to + * strip all trailing space. If true all whitespace at the end of the + * given String will be stripped. If false, all whitespace at the end + * of the given String will be converted to a single space. +**/ +void XMLUtils::stripSpace + ( const String& data, + String& dest, + MBool stripAllLeadSpace, + MBool stripAllTrailSpace ) +{ + + char lastToken, token; + Int32 oldSize = data.length(); + char* chars = new char[oldSize+1]; + data.toChar(chars); + + lastToken = '\0'; + Int32 total = 0; + + // indicates we have seen at least one + // non whitespace charater + MBool validChar = MB_FALSE; + + for (int i = 0; i < oldSize; i++) { + token = chars[i]; + switch(token) { + case ' ': + case '\t': + case '\n': + case '\r': + token = ' '; + if (stripAllLeadSpace && (!validChar)) break; + if (lastToken != token) chars[total++] = token; + break; + default: + chars[total++] = token; + validChar = MB_TRUE; + break; + } + lastToken = token; + } + + //-- remove last trailing space if necessary + if (stripAllTrailSpace) + if ((total > 0) && (chars[total-1] == ' ')) --total; + + if (validChar) { + chars[total] = '\0'; //-- add Null terminator + dest.append(chars); + } + delete chars; +} //-- stripSpace + diff --git a/mozilla/content/xslt/src/xml/txXMLUtils.h b/mozilla/content/xslt/src/xml/txXMLUtils.h new file mode 100644 index 00000000000..fa935158ef4 --- /dev/null +++ b/mozilla/content/xslt/src/xml/txXMLUtils.h @@ -0,0 +1,109 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * An XML Utility class + * @author Keith Visco +**/ + +#include "String.h" +#include "baseutils.h" + +#ifndef MITRE_XMLUTILS_H +#define MITRE_XMLUTILS_H + +class XMLUtils { + +public: + + static const String XMLNS; + + static void getNameSpace(const String& src, String& dest); + static void getLocalPart(const String& src, String& dest); + + /** + * Returns true if the given String is a valid XML QName + **/ + static MBool isValidQName(String& name); + + /** + * Normalizes the value of an XML attribute + **/ + static void normalizeAttributeValue(String& attValue); + + /** + * Normalizes the value of a XML processingInstruction + **/ + static void normalizePIValue(String& attValue); + + /** + * Strips whitespace from the given String. + * Newlines (#xD), tabs (#x9), and consecutive spaces (#x20) are + * converted to a single space (#x20). + * @param data the String to strip whitespace from + * @param dest the destination String to append the result to + **/ + static void stripSpace (const String& data, String& dest); + + /** + * Strips whitespace from the given String. + * Newlines (#xD), tabs (#x9), and consecutive spaces (#x20) are + * converted to a single space (#x20). + * @param data the String to strip whitespace from + * @param dest the destination String to append the result to + * @param stripAllLeadSpace, a boolean indicating whether or not to + * strip all leading space. If true all whitespace from the start of the + * given String will be stripped. If false, all whitespace from the start + * of the given String will be converted to a single space. + * @param stripAllTrailSpace, a boolean indicating whether or not to + * strip all trailing space. If true all whitespace at the end of the + * given String will be stripped. If false, all whitespace at the end + * of the given String will be converted to a single space. + **/ + static void stripSpace (const String& data, + String& dest, + MBool stripAllLeadSpace, + MBool stripAllTrailSpace); + +private: + + /** + * Returns true if the given character represents an Alpha letter + **/ + static MBool isAlphaChar(Int32 ch); + + /** + * Returns true if the given character represents a numeric letter (digit) + **/ + static MBool isDigit(Int32 ch); + + /** + * Returns true if the given character is an allowable QName character + **/ + static MBool isQNameChar(Int32 ch); + + /** + * Returns true if the given character is an allowable NCName character + **/ + static MBool isNCNameChar(Int32 ch); + +}; //-- XMLUtils +#endif diff --git a/mozilla/extensions/transformiix/build/XSLProcessorFactory.cpp b/mozilla/extensions/transformiix/build/XSLProcessorFactory.cpp new file mode 100644 index 00000000000..b3e89d6b87c --- /dev/null +++ b/mozilla/extensions/transformiix/build/XSLProcessorFactory.cpp @@ -0,0 +1,58 @@ +#include "d:\progra~1\devstudio\vc\include\string.h" // XXX HACK, needs to be removed. +#include "XSLProcessor.h" +#include "nsIComponentManager.h" +#include "nsIServiceManager.h" +#include "nsIGenericFactory.h" + +static NS_DEFINE_CID(kXSLProcessorCID, MITRE_XSL_PROCESSOR_CID); +static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID); + +extern "C" PR_IMPLEMENT(nsresult) +NSGetFactory(nsISupports* aServMgr, + const nsCID &aClass, + const char *aClassName, + const char *aProgID, + nsIFactory **aFactory) +{ + nsresult rv; + nsIGenericFactory* fact; + if (aClass.Equals(kXSLProcessorCID)) + rv = NS_NewGenericFactory(&fact, XSLProcessor::Create); + else + rv = NS_ERROR_FAILURE; + + if (NS_SUCCEEDED(rv)) + *aFactory = fact; + return rv; +} + +extern "C" PR_IMPLEMENT(nsresult) +NSRegisterSelf(nsISupports* aServMgr , const char* aPath) +{ + nsresult rv; + + NS_WITH_SERVICE1(nsIComponentManager, compMgr, + aServMgr, kComponentManagerCID, &rv); + if (NS_FAILED(rv)) return rv; + + printf("Registering XSL Processor...\n"); + rv = compMgr->RegisterComponent(kXSLProcessorCID, + "Transformiix XSL Processor", + "component://netscape/document-transformer?type=text/xsl", + aPath, PR_TRUE, PR_TRUE); + + return rv; +} + +extern "C" PR_IMPLEMENT(nsresult) +NSUnregisterSelf(nsISupports* aServMgr, const char* aPath) +{ + nsresult rv; + NS_WITH_SERVICE1(nsIComponentManager, compMgr, + aServMgr, kComponentManagerCID, &rv); + if (NS_FAILED(rv)) return rv; + + rv = compMgr->UnregisterComponent(kXSLProcessorCID, aPath); + + return rv; +} diff --git a/mozilla/extensions/transformiix/build/makefile.win b/mozilla/extensions/transformiix/build/makefile.win new file mode 100644 index 00000000000..4d3f07c9a07 --- /dev/null +++ b/mozilla/extensions/transformiix/build/makefile.win @@ -0,0 +1,67 @@ +#!nmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH=..\..\..\.. +include <$(DEPTH)/config/config.mak> + +DEFINES=-DMOZILLA + +MODULE=transformix +REQUIRES=xpcom raptor +IS_COMPONENT = 1 + +CPPSRCS= \ + XSLProcessorFactory.cpp \ + $(NULL) + +CPP_OBJS= \ + .\$(OBJDIR)\XSLProcessorFactory.obj \ + $(NULL) + +MAKE_OBJ_TYPE = DLL +DLLNAME = transformiix +DLL=.\$(OBJDIR)\$(DLLNAME).dll + +LCFLAGS = \ + $(LCFLAGS) \ + $(DEFINES) \ + $(NULL) + +LINCS= -I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor \ + -I..\source\xml\dom \ + -I..\source\xsl\expr -I..\source\xsl\util -I..\source\xml -I..\source\xsl \ + -I..\source\base \ + +# These are the libraries we need to link with to create the dll +LLIBS= \ + $(DIST)\lib\xpcom.lib \ + $(DIST)\lib\transformix_base.lib \ + $(DIST)\lib\transformix_xml.lib \ + $(DIST)\lib\transformix_xml_dom_mozImpl.lib \ + $(DIST)\lib\transformix_xsl.lib \ + $(DIST)\lib\transformix_xsl_expr.lib \ + $(DIST)\lib\transformix_xsl_util.lib + +include <$(DEPTH)\config\rules.mak> + +install:: $(DLL) + $(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).dll $(DIST)\bin\components + $(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).lib $(DIST)\lib + +clobber:: + rm -f $(DIST)\bin\$(DLLNAME).dll + rm -f $(DIST)\lib\$(DLLNAME).lib diff --git a/mozilla/extensions/transformiix/changes.txt b/mozilla/extensions/transformiix/changes.txt new file mode 100644 index 00000000000..d3571776cb3 --- /dev/null +++ b/mozilla/extensions/transformiix/changes.txt @@ -0,0 +1,56 @@ +TransforMiiX (TM) (C) Copyright The MITRE Corporation 1999 All rights reserved. + + +Build 19990813 +-- added new example: indentity.xml/xsl which tests: + -- xsl:copy, node() +-- added comment(), pi(), and node() + -- XMLParser still needs to handle reading in XML comments +-- added xsl:copy +-- added xsl:processing-instruction +-- added xsl:comment + +Build 19990812 +-- Created base/Double.cpp (primitives.h) + -- Based off some code submitted by Larry Fitzpatrick, changed Name from + FloatPort to Double, I wanted to add more Double related methods + -- changed the NaN() method to just a static double + -- All expr classes now use Double::isNaN() and Double::NaN + -- I added Double::isInfinite, Double::POSITIVE_INFINITY and + Double::NEGATIVE_INFINITY +-- Added base/Integer.cpp back into Makefile + -- added Integer::toString(int,String); + -- changed implementation +-- Moved code to convert from Strings to doubles and from doubles to Strings + into the Double class +-- removed testdom.cpp from xml/dom +-- Added more changes from Larry Fitzpatrick and Michele Lee for + porting issues + -- added appropriate return values for: + -- xml/dom/Element.cpp + -- xml/dom/NodeDefinition.cpp + -- base/StringList.cpp + -- xsl/expr/PredicateList.cpp +-- Added remaining String Function Calls + -- substring(), substring-after(), substring-before(), translate(), + string-length() + + +Build 19990810 +-- Added most of the Whitespace handling +-- Added ErrorObserver interface + -- ErrorObserver is now used throughout most of the code +-- Added SimpleErrorObserver implementation of ErrorObserver +-- Moved main() method from XSLProcessor.cpp to tranformiix.cpp +-- Added the following XPath functions: + -- local-part(), name(), namespace() + -- see functions.xml/functions.xsl for available functions + +Build 19990806 +-- Incoporated Changes From Larry Fitzpatrick +-- Added more XPath functions + -- last(), count(), string(), contains(), starts-with(), concat() + -- see functions.xml/functions.xsl for available functions +-- Added xsl:text support + + diff --git a/mozilla/extensions/transformiix/docs/contributors.html b/mozilla/extensions/transformiix/docs/contributors.html new file mode 100644 index 00000000000..277eff9ffa1 --- /dev/null +++ b/mozilla/extensions/transformiix/docs/contributors.html @@ -0,0 +1,122 @@ + + +MITRE TransforMiiX(tm) Contributors + + + + + + + + + + + + + +
+ MITRE + + TransforMiiX + TM +

+ +
+
+

+ Much of the TransforMiiX code was ported + from XSL:P, + an open source XSLT processor. Thanks to all the contributors of + that project. +

+

+Core Developers

+The following people have contributed substantial time and +effort to the development. + + + + + + + + + + + + + + + +
NameContributionCompany
+ Visco, Keith + + Software design and most of the implementation + + The MITRE Corporation +
+ Kneeland, Tom + + DOM Implementation, Most of the String class + + The MITRE Corporation +
+

+

+

+Additional Developers

+The following people have contributed to the development. +
(appearing in alphabetical order) + + + + + + + + + + + + + + + +
NameContributionCompany
+ Fitzpatrick, Larry + + C++ porting issues with Visual C++, design influences + + OpenText +
+ Lee, Michele + + C++ porting issues + + Oblix +
+ +

Testing/Feedback (Suggestions/Bug Reports)

+The following people have used TransforMiiX and provided feedback that has been +beneficial to the development. +
(appearing in alphabetical order) + + + + + + + +
NameCompany
Costello, RogerThe MITRE Corporation
+ + + +


+ +The MITRE Corporation, (C) Copyright 1999, All rights reserved
+Email:kvisco@mitre.org +
+ +
+ + diff --git a/mozilla/extensions/transformiix/makefile.win b/mozilla/extensions/transformiix/makefile.win new file mode 100644 index 00000000000..14972d4f468 --- /dev/null +++ b/mozilla/extensions/transformiix/makefile.win @@ -0,0 +1,22 @@ +#!nmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH=..\..\.. + +DIRS=source build + +include <$(DEPTH)\config\rules.mak> diff --git a/mozilla/extensions/transformiix/release.txt b/mozilla/extensions/transformiix/release.txt new file mode 100644 index 00000000000..a88a4b0e085 --- /dev/null +++ b/mozilla/extensions/transformiix/release.txt @@ -0,0 +1,24 @@ +TransforMiiX (TM) (C) Copyright The MITRE Corporation 1999 All rights reserved. + +All source and compiled binaries are considered the "program". + +The contents of all source files in distributed with this +program are subject to the Mozilla Public License +Version 1.0 (the "License"); you may not use those files except in +compliance with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +The program provided "as is" without any warranty express or +implied, including the warranty of non-infringement and the implied +warranties of merchantibility and fitness for a particular purpose. +The Copyright owner will not be liable for any damages suffered by +you as a result of using the Program. In no event will the Copyright +owner be liable for any special, indirect or consequential damages or +lost profits even if the Copyright owner has been advised of the +possibility of their occurrence. + +Much of the source code was ported from XSL:P [http://xslp.kvisco.com], +an open source Java XSL processor written by Keith Visco. +There were a number of contributors to XSL:P and therefor many of +those contributors have indirectly contributed to this project. + diff --git a/mozilla/extensions/transformiix/source/Makefile b/mozilla/extensions/transformiix/source/Makefile new file mode 100644 index 00000000000..b4edb22d278 --- /dev/null +++ b/mozilla/extensions/transformiix/source/Makefile @@ -0,0 +1,100 @@ +target: TransforMiiX + +CC = g++ + +ROOT_PATH = . +XML_PATH = $(ROOT_PATH)/xml +XSL_PATH = $(ROOT_PATH)/xsl +BASE_PATH = $(ROOT_PATH)/base +DOM_PATH = $(XML_PATH)/dom +NET_PATH = $(ROOT_PATH)/net +EXPR_PATH = $(XSL_PATH)/expr +XSLUTIL_PATH = $(XSL_PATH)/util +XMLPRINTER_PATH = $(XML_PATH)/printer +XMLPARSER_PATH = $(XML_PATH)/parser +EXPAT_PARSER_PATH = $(XMLPARSER_PATH)/xmlparse +EXPAT_TOKEN_PATH = $(XMLPARSER_PATH)/xmltok + + +INCLUDE_PATHS = -I $(BASE_PATH) \ + -I $(NET_PATH) \ + -I $(DOM_PATH) \ + -I $(XML_PATH) \ + -I $(EXPR_PATH) \ + -I $(XSL_PATH) \ + -I $(XSLUTIL_PATH) \ + -I $(XMLPARSER_PATH) \ + -I $(XMLPRINTER_PATH) \ + -I $(EXPAT_PARSER_PATH) -I- + +BASE_OBJS = $(BASE_PATH)/*.o + +NET_OBJS = $(NET_PATH)/*.o + +DOM_OBJS = $(DOM_PATH)/*.o + +EXPR_OBJS = $(EXPR_PATH)/*.o + +XML_OBJS = $(XML_PATH)/*.o + +XMLPRINTER_OBJS = $(XMLPRINTER_PATH)/*.o + +XMLPARSER_OBJS = $(XMLPARSER_PATH)/*.o +EXPAT_TOKEN_OBJS = $(EXPAT_TOKEN_PATH)/*.o +EXPAT_PARSER_OBJS = $(EXPAT_PARSER_PATH)/*.o + +XSLUTIL_OBJS = $(XSLUTIL_PATH)/*.o +XSL_OBJS = $(XSL_PATH)/*.o + +ALL_OBJS = $(BASE_OBJS) \ + $(NET_OBJS) \ + $(DOM_OBJS) \ + $(XSLUTIL_OBJS) \ + $(EXPR_OBJS) \ + $(XML_OBJS) \ + $(XMLPRINTER_OBJS) \ + $(XMLPARSER_OBJS) \ + $(EXPAT_TOKEN_OBJS) \ + $(EXPAT_PARSER_OBJS) \ + $(XSL_OBJS) + +MAIN_CPP = main/transformiix.cpp + +TransforMiiX: $(ALL_OBJS) + $(CC) $(INCLUDE_PATHS) $(ALL_OBJS) $(MAIN_CPP) -o transfrmx.exe + + +$(BASE_OBJS): $(BASE_PATH)/*.cpp $(BASE_PATH)/*.h + cd $(BASE_PATH); make + +$(DOM_OBJS): $(DOM_PATH)/*.cpp $(DOM_PATH)/dom.h + cd $(DOM_PATH); make + + +$(XML_OBJS): $(XML_PATH)/*.cpp $(XML_PATH)/*.h + cd $(XML_PATH); make + +$(EXPAT_TOKEN_OBJS): + cd $(XMLPARSER_PATH); make -f expat.mk + +$(EXPAT_PARSER_OBJS): + cd $(XMLPARSER_PATH); make -f expat.mk + +$(XMLPARSER_OBJS): + cd $(XMLPARSER_PATH); make + +$(XMLPRINTER_OBJS): + cd $(XMLPRINTER_PATH); make + +$(NET_OBJS): + cd $(NET_PATH); make + +$(XSLUTIL_OBJS): + cd $(XSLUTIL_PATH); make + +$(EXPR_OBJS): + cd $(EXPR_PATH); make + +$(XSL_OBJS): + cd $(XSL_PATH); make + diff --git a/mozilla/extensions/transformiix/source/base/CommandLineUtils.cpp b/mozilla/extensions/transformiix/source/base/CommandLineUtils.cpp new file mode 100644 index 00000000000..d9f201c2228 --- /dev/null +++ b/mozilla/extensions/transformiix/source/base/CommandLineUtils.cpp @@ -0,0 +1,77 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "CommandLineUtils.h" + +/** + * @author Keith Visco +**/ +void CommandLineUtils::getOptions + (NamedMap& options, int argc, char** argv, StringList& flags) +{ + String arg; + String flag; + for (int i = 0; i < argc; i++) { + arg.clear(); + arg.append(argv[i]); + + if ((arg.length()>0) && (arg.charAt(0) == '-')) { + + // clean up previous flag + if (flag.length()>0) { + options.put(flag, new String(arg)); + flag.clear(); + } + // get next flag + arg.subString(1,flag); + + //-- check full flag, otherwise try to find + //-- flag within string + if (!flags.contains(flag)) { + Int32 idx = 1; + String tmpFlag; + while(idx <= flag.length()) { + flag.subString(0,idx, tmpFlag); + if (flags.contains(tmpFlag)) { + if (idx < flag.length()) { + String* value = new String(); + flag.subString(idx, *value); + options.put(tmpFlag,value); + break; + } + } + else if (idx == flag.length()) { + cout << "invalid option: -" << flag << endl; + } + ++idx; + }// end while + } + }// if flag char '-' + else { + // Store both flag key and number key + if (flag.length() > 0) options.put(flag, new String(arg)); + flag.clear(); + } + + }// end for + if (flag.length()>0) options.put(flag, new String("no value")); +} //-- getOptions + diff --git a/mozilla/extensions/transformiix/source/base/CommandLineUtils.h b/mozilla/extensions/transformiix/source/base/CommandLineUtils.h new file mode 100644 index 00000000000..6a74ab9ac3f --- /dev/null +++ b/mozilla/extensions/transformiix/source/base/CommandLineUtils.h @@ -0,0 +1,40 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "baseutils.h" +#include "StringList.h" +#include "NamedMap.h" + +#ifndef MITRE_COMMANDLINEUTILS_H +#define MITRE_COMMANDLINEUTILS_H + +/** + * @author Keith Visco +**/ +class CommandLineUtils { + +public: + static void getOptions + (NamedMap& options, int argc, char** argv, StringList& flags); + +}; + +#endif diff --git a/mozilla/extensions/transformiix/source/base/Double.cpp b/mozilla/extensions/transformiix/source/base/Double.cpp new file mode 100644 index 00000000000..f4730bef4ae --- /dev/null +++ b/mozilla/extensions/transformiix/source/base/Double.cpp @@ -0,0 +1,238 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + + + +#include "primitives.h" + +//----------------------------/ +//- Implementation of Double -/ +//----------------------------/ +/** + * A wrapper for the primitive double type, and provides some simple + * floating point related routines + * @author Larry Fitzpatrick + * @author Keith Visco +**/ + +double d0 = 0.0; + +const double Double::NaN = (d0/d0); +const double Double::NEGATIVE_INFINITY = (-1.0/d0); +const double Double::POSITIVE_INFINITY = (1.0/d0); + +/** + * Creates a new Double with it's value initialized to 0; +**/ +Double::Double() { + value = 0; +} //-- Double + +/** + * Creates a new Double with it's value initialized to the given double +**/ +Double::Double(double dbl) { + this->value = dbl; +} //-- Double + +/** + * Creates a new Double with it's value initialized from the given String. + * The String will be converted to a double. If the String does not + * represent an IEEE 754 double, the value will be initialized to NaN +**/ +Double::Double(const String& string) { + this->value = toDouble(string); +} //-- Double + + + +/** + * Returns the value of this Double as a double +**/ +double Double::doubleValue() { + return this->value; +} //-- doubleValue + +/** + * Returns the value of this Double as an int +**/ +int Double::intValue() { + return (int)value; +} //-- intValue + +/** + * Determins whether the given double represents positive or negative + * inifinity +**/ +MBool Double::isInfinite(double dbl) { + return (MBool)((dbl == POSITIVE_INFINITY ) || (dbl == NEGATIVE_INFINITY)); +} //-- isInfinite + +/** + * Determins whether this Double's value represents positive or + * negative inifinty +**/ +MBool Double::isInfinite() { + return (MBool)(( value == POSITIVE_INFINITY ) || (value == NEGATIVE_INFINITY)); +} //-- isInfinite + +/** + * Determins whether the given double is NaN +**/ +MBool Double::isNaN(double dbl) { +#ifdef MOZILLA + return (MBool) _isnan(dbl); +#else + return (MBool) isnan(dbl); +#endif +} //-- isNaN + +/** + * Determins whether this Double's value is NaN +**/ +MBool Double::isNaN() { +#ifdef MOZILLA + return (MBool) _isnan(value); +#else + return (MBool) isnan(value); +#endif +} //-- isNaN + +/** + * Converts the given String to a double, if the String value does not + * represent a double, NaN will be returned +**/ +double Double::toDouble(const String& src) { + + double dbl = 0.0; + double fraction = 1.0; + double multiplier = 10.0; + Int32 idx = 0; + + double sign = 1.0; + + //-- trim leading whitespace + for ( ; idx < src.length(); idx++ ) + if ( src.charAt(idx) != ' ' ) break; + + //-- check first character for sign + if ( idx < src.length() ) { + Int32 ch = src.charAt(idx); + if ( ch == '-' ) { + sign = -1.0; + ++idx; + } + } + else { + return Double::NaN; + } + + //-- convert remaining to number + for ( ; idx < src.length(); idx++ ) { + + Int32 ch = src.charAt(idx); + + if (( ch >= '0') && (ch <= '9')) { + if ( multiplier > 1.0 ) { + dbl = dbl*multiplier; + dbl += (double) (ch-48); + } + else { + dbl += multiplier * (ch-48); + multiplier = multiplier * 0.1; + } + } + else if ( ch == '.') { + if ( multiplier < 1.0 ) return Double::NaN; + multiplier = 0.1; + } + else return Double::NaN; + } + dbl = dbl*sign; + return dbl; +} //-- toDouble + + +/** + * Converts the value of this Double to a String, and places + * The result into the destination String. + * @return the given dest string +**/ +String& Double::toString(String& dest) { + return toString(value, dest); +} //-- toString + +/** + * Converts the value of the given double to a String, and places + * The result into the destination String. + * @return the given dest string +**/ +String& Double::toString(double value, String& dest) { + + //-- check for special cases + + if ( isNaN(value) ) { + dest.append("NaN"); + return dest; + } + if ( isInfinite(value) ) { + if (value < 0) dest.append('-'); + dest.append("Infinity"); + return dest; + } + + MBool isNegative = (MBool)(value<0.0); + double val = value; + if ( isNegative ) val = val * -1.0; + + double ival = 0; + double fval = modf(val, &ival); + + String iStr; + + int temp = (int)ival; + + + if ( temp > 0.0 ) { + while ( temp > 0.0 ) { + iStr.append( (char) ((temp % 10)+48) ); + temp = temp / 10; + } + if ( isNegative ) iStr.append('-'); + iStr.reverse(); + } + else iStr.append('0'); + + iStr.append('.'); + if ( fval > 0.0 ) { + while ( fval > 0.0000001 ) { + fval = fval*10.0; + fval = modf(fval, &ival); + iStr.append( (char) (ival+48) ); + } + } + else iStr.append('0'); + + dest.append(iStr); + return dest; +} //-- toString + + diff --git a/mozilla/extensions/transformiix/source/base/ErrorObserver.h b/mozilla/extensions/transformiix/source/base/ErrorObserver.h new file mode 100644 index 00000000000..c5150fd261f --- /dev/null +++ b/mozilla/extensions/transformiix/source/base/ErrorObserver.h @@ -0,0 +1,96 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#ifndef MITRE_ERROROBSERVER_H +#define MITRE_ERROROBSERVER_H + +#include "baseutils.h" +#include "String.h" +#include "iostream.h" + +/** + * A simple interface for observing errors + * @author Keith Visco +**/ +class ErrorObserver { + +public: + + enum ErrorLevel {FATAL = 0, NORMAL, WARNING}; + + /** + * Default Destructor for ErrorObserver + **/ + virtual ~ErrorObserver() {}; + + /** + * Notifies this Error observer of a new error, with default + * level of NORMAL + **/ + virtual void recieveError(String& errorMessage) = 0; + + /** + * Notifies this Error observer of a new error using the given error level + **/ + virtual void recieveError(String& errorMessage, ErrorLevel level) = 0; + +}; //-- ErrorObserver + +/** + * A simple ErrorObserver which allows printing error messages to a stream +**/ +class SimpleErrorObserver : public ErrorObserver { + +public: + + /** + * Creates a new SimpleErrorObserver. + * All errors will be printed to the console (cout). + **/ + SimpleErrorObserver(); + + /** + * Creates a new SimpleErrorObserver. + * All errors will be printed to the given ostream. + **/ + SimpleErrorObserver(ostream& errStream); + + virtual ~SimpleErrorObserver() {}; + + /** + * Notifies this Error observer of a new error, with default + * level of NORMAL + **/ + virtual void recieveError(String& errorMessage); + + /** + * Notifies this Error observer of a new error using the given error level + **/ + virtual void recieveError(String& errorMessage, ErrorLevel level); + + virtual void supressWarnings(MBool supress); + +private: + + ostream* errStream; + MBool hideWarnings; +}; //-- SimpleErrorObserver +#endif diff --git a/mozilla/extensions/transformiix/source/base/Integer.cpp b/mozilla/extensions/transformiix/source/base/Integer.cpp new file mode 100644 index 00000000000..05860c00c55 --- /dev/null +++ b/mozilla/extensions/transformiix/source/base/Integer.cpp @@ -0,0 +1,138 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + + + +#include "primitives.h" +#include "baseutils.h" + +//-----------------------------/ +//- Implementation of Integer -/ +//-----------------------------/ + +/** + * A wrapper for the primitive int type, and provides some simple + * integer related routines + * @author Keith Visco +**/ + +/** + * Creates a new Integer initialized to 0. +**/ +Integer::Integer() { + value = 0; +} //-- Integer + +/** + * Creates a new Integer initialized to the given int value. +**/ +Integer::Integer(int value) { + this->value = value; +} //-- Integer + +/** + * Creates a new Integer based on the value of the given String +**/ +Integer::Integer(const String& str) { + Int32 val = 0; + for (Int32 i = 0; i < str.length(); i++) { + val = (val * 10) + (str.charAt(i) - 48); + } +} //-- Integer + +/** + * Returns the int value of this Integer +**/ + +Int32 Integer::intValue() { + return value; +} //-- intValue; + +/** + * Converts the given String to an integer +**/ +int Integer::intValue(const String& src) { + + int result = 0; + Int32 idx = 0; + int sign = 1; + + //-- trim leading whitespace + for ( ; idx < src.length(); idx++ ) + if ( src.charAt(idx) != ' ' ) break; + + //-- check first character for sign + if ( idx < src.length() ) { + Int32 ch = src.charAt(idx); + if ( ch == '-' ) { + sign = -1; + ++idx; + } + } + else { + return 0; //-- we should return NaN here + } + + //-- convert remaining to number + for ( ; idx < src.length(); idx++ ) { + Int32 ch = src.charAt(idx); + if (( ch >= '0') && (ch <= '9')) { + result = result*10; + result += (ch-48); + } + else return 0; + } + result = result*sign; + return result; +} //-- toInteger + +/** + * Converts the given int to a String +**/ +String& Integer::toString(int value, String& dest) { + + String result; + UNICODE_CHAR charDigit; + Int32 tempVal = value; + MBool isNegative = (value < 0); + if ( isNegative ) tempVal = -value; + + if ( tempVal > 0 ) { + while (tempVal) { + charDigit = (tempVal % 10) + 48; + result.append(charDigit); + tempVal /=10; + } + if ( isNegative ) result.append('-'); + result.reverse(); + } + else result.append('0'); + dest.append(result); + return dest; +} //-- toString + +/** + * Converts the given the value of this Integer to a String +**/ +String& Integer::toString(String& dest) { + return Integer::toString(value, dest); +} //-- toString + diff --git a/mozilla/extensions/transformiix/source/base/List.cpp b/mozilla/extensions/transformiix/source/base/List.cpp new file mode 100644 index 00000000000..c9136a6f269 --- /dev/null +++ b/mozilla/extensions/transformiix/source/base/List.cpp @@ -0,0 +1,319 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "List.h" +#include + //--------------------------/ + //- Implementation of List -/ +//--------------------------/ + +/** + * Default constructor for a List; +**/ +List::List() { + firstItem = 0; + lastItem = 0; + itemCount = 0; +} //-- List; + +/** + * List destructor, cleans up List Items, but will not delete the Object + * references +*/ +List::~List() { + ListItem* item = firstItem; + while (item) { + ListItem* tItem = item; + item = item->nextItem; + delete tItem; + } +} //-- ~List + +void List::insert(int index, void* objPtr) { + + if ( index >= itemCount ) { + insertBefore(objPtr, 0); + } + else { + //-- add to middle of list + ListItem* nextItem = firstItem; + for ( int i = 0; i < index; i++ ) nextItem = nextItem->nextItem; + insertBefore(objPtr, nextItem); + } +} //-- insert + +void List::add(void* objPtr) { + insert(itemCount, objPtr); +} //-- add + +List::ListItem* List::getFirstItem() { + return firstItem; +} //-- getFirstItem + +List::ListItem* List::getLastItem() { + return lastItem; +} //-- getLastItem + +/** + * Returns the number of items in this List +**/ +Int32 List::getLength() { + return itemCount; +} //-- getLength + + +/** + * Inserts the given Object pointer as the item just after refItem. + * If refItem is a null pointer the Object will be inserted at the + * beginning of the List (ie, insert after nothing). + * This method assumes refItem is a member of this list, and since this + * is a private method, I feel that's a valid assumption +**/ +void List::insertAfter(void* objPtr, ListItem* refItem) { + //-- if refItem == null insert at front + if (!refItem) insertBefore(objPtr, firstItem); + else insertBefore(objPtr, refItem->nextItem); +} //-- insertAfter + +/** + * Inserts the given Object pointer as the item just before refItem. + * If refItem is a null pointer the Object will be inserted at the + * end of the List (ie, insert before nothing). + * This method assumes refItem is a member of this list, and since this + * is a private method, I feel that's a valid assumption +**/ +void List::insertBefore(void* objPtr, ListItem* refItem) { + + ListItem* item = new ListItem; + item->objPtr = objPtr; + item->nextItem = 0; + item->prevItem = 0; + + //-- if refItem == null insert at end + if (!refItem) { + //-- add to back of list + if ( lastItem ) { + lastItem->nextItem = item; + item->prevItem = lastItem; + } + lastItem = item; + if ( !firstItem ) firstItem = item; + } + else { + //-- insert before given item + item->nextItem = refItem; + item->prevItem = refItem->prevItem; + refItem->prevItem = item; + + if (refItem == firstItem) firstItem = item; + if (itemCount == 0) lastItem = item; // <-should we ever see this? + } + + // increase the item count + ++itemCount; +} //-- insertBefore + +/** + * Returns a ListIterator for this List +**/ +ListIterator* List::iterator() { + return new ListIterator(this); +} + +void* List::remove(void* objPtr) { + ListItem* item = firstItem; + while (item) { + if (item->objPtr == objPtr) { + remove(item); + delete item; + return objPtr; + } + item = item->nextItem; + } + // not in list + return 0; +} //-- remove + +List::ListItem* List::remove(ListItem* item) { + + if ( !item ) return item; + + //-- adjust the previous item's next pointer + if (item->prevItem) { + item->prevItem->nextItem = item->nextItem; + } + //-- adjust the next item's previous pointer + if ( item->nextItem ) { + item->nextItem->prevItem = item->prevItem; + } + + //-- adjust first and last items + if (item == firstItem) firstItem = item->nextItem; + if (item == lastItem) lastItem = item->prevItem; + + //-- decrease Item count + --itemCount; + return item; +} //-- remove + + //----------------------------------/ + //- Implementation of ListIterator -/ +//----------------------------------/ + + +/** + * Creates a new ListIterator for the given List + * @param list, the List to create an Iterator for +**/ +ListIterator::ListIterator(List* list) { + this->list = list; + currentItem = 0; + allowRemove = MB_FALSE; + moveForward = MB_TRUE; + done = MB_FALSE; + count = 0; +} //-- ListIterator + +ListIterator::~ListIterator() { + //-- overrides default destructor to do nothing +} //-- ~ListIterator + +/** + * Adds the Object pointer to the List pointed to by this ListIterator. + * The Object pointer is inserted as the next item in the List + * based on the current position within the List + * @param objPtr the Object pointer to add to the list +**/ +void ListIterator::add(void* objPtr) { + + list->insertAfter(objPtr,currentItem); + allowRemove = MB_FALSE; + +} //-- add + +/** + * Returns true if a sucessful call to the next() method can be made + * @return MB_TRUE if a sucessful call to the next() method can be made, + * otherwise MB_FALSE +**/ +MBool ListIterator::hasNext() { + MBool hasNext = MB_FALSE; + if ( done ) return hasNext; + else if ( currentItem ) { + if (moveForward) hasNext = (MBool) currentItem->nextItem; + else hasNext = (MBool)currentItem->prevItem; + } + else { + if (moveForward) hasNext = (MBool) list->firstItem; + else hasNext = (MBool) list->lastItem; + } + return hasNext; +} //-- hasNext + +/** + * Returns true if a sucessful call to the previous() method can be made + * @return MB_TRUE if a sucessful call to the previous() method can be made, + * otherwise MB_FALSE +**/ +MBool ListIterator::hasPrevious() { + MBool hasPrevious = MB_FALSE; + if (currentItem) { + if (moveForward) hasPrevious = (MBool)(currentItem->prevItem); + else hasPrevious = (MBool) (currentItem->nextItem); + } + return hasPrevious; +} //-- hasPrevious + +/** + * Returns the next Object pointer in the list +**/ +void* ListIterator::next() { + + void* obj = 0; + if ( done ) return obj; + + if (currentItem) { + if ( moveForward ) currentItem = currentItem->nextItem; + else currentItem = currentItem->prevItem; + } + else { + if ( moveForward ) currentItem = list->firstItem; + else currentItem = list->lastItem; + } + + if ( currentItem ) { + obj = currentItem->objPtr; + allowRemove = MB_TRUE; + } + else done = MB_TRUE; + + return obj; +} //-- next + +/** + * Returns the previous Object in the list +**/ +void* ListIterator::previous() { + + void* obj = 0; + + if (currentItem) { + if ( moveForward ) currentItem = currentItem->prevItem; + else currentItem = currentItem->nextItem; + if ( currentItem ) obj = currentItem->objPtr; + } + return obj; +} //-- previous + +/** + * Removes the Object last returned by the next() or previous() methods; + * @return the removed Object pointer +**/ +void* ListIterator::remove() { + + if (!allowRemove) return 0; + allowRemove = MB_FALSE; + + void* obj = 0; + if (currentItem) { + obj = currentItem->objPtr; + List::ListItem* item = currentItem; + previous(); //-- make previous item the current item + list->remove(item); + } + return obj; +} //-- remove + +/** + * Resets the current location within the List to the beginning of the List +**/ +void ListIterator::reset() { + done = MB_FALSE; + currentItem = 0; +} //-- reset + +/** + * sets this iterator to operate in the reverse direction +**/ +void ListIterator::reverse() { + moveForward = (MBool)(!moveForward); +} //-- reverse + diff --git a/mozilla/extensions/transformiix/source/base/List.h b/mozilla/extensions/transformiix/source/base/List.h new file mode 100644 index 00000000000..a147c115149 --- /dev/null +++ b/mozilla/extensions/transformiix/source/base/List.h @@ -0,0 +1,188 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "baseutils.h" + +#ifndef MITRE_LIST_H +#define MITRE_LIST_H + +/** + * Represents an ordered list of Object pointers. Modeled after a Java 2 List. + * @author Keith Visco +**/ +class List { + +friend class ListIterator; + +public: + + /** + * Creates an empty List + **/ + List(); + + /** + * List destructor, object references will not be deleted. + **/ + virtual ~List(); + + /** + * Returns the number of items in this List + **/ + Int32 getLength(); + + /** + * Returns a ListIterator for this List + **/ + ListIterator* iterator(); + + /** + * Adds the given Object to the specified position in the list + **/ + void insert(int index, void* objPtr); + + /** + * Adds the given Object to the list + **/ + void add(void* objPtr); + + /** + * Removes the given Object pointer from the list + **/ + void* remove(void* objPtr); + + +protected: + + struct ListItem { + ListItem* nextItem; + ListItem* prevItem; + void* objPtr; + }; + + ListItem* getFirstItem(); + ListItem* getLastItem(); + + /** + * Removes the given ListItem pointer from the list + **/ + ListItem* remove(ListItem* sItem); + +private: + + ListItem* firstItem; + ListItem* lastItem; + Int32 itemCount; + + void insertAfter(void* objPtr, ListItem* sItem); + void insertBefore(void* objPtr, ListItem* sItem); + +}; + + + +/** + * An Iterator for the List Class + * @author Keith Visco +**/ +class ListIterator { + +public: + + + /** + * Creates a new ListIterator for the given List + * @param list, the List to create an Iterator for + **/ + ListIterator(List* list); + + /** + * Destructor, destroys a given instance of a ListIterator + **/ + virtual ~ListIterator(); + + /** + * Adds the Object pointer to the List pointed to by this ListIterator. + * The Object pointer is inserted as the next item in the List + * based on the current position within the List + * @param objPtr the Object pointer to add to the list + **/ + + virtual void add(void* objPtr); + + /** + * Returns true if a sucessful call to the next() method can be made + * @return MB_TRUE if a sucessful call to the next() method can be made, + * otherwise MB_FALSE + **/ + virtual MBool hasNext(); + + /** + * Returns true if a sucessful call to the previous() method can be made + * @return MB_TRUE if a sucessful call to the previous() method can be made, + * otherwise MB_FALSE + **/ + virtual MBool hasPrevious(); + + /** + * Returns the next Object pointer from the list + **/ + virtual void* next(); + + /** + * Returns the previous Object pointer from the list + **/ + virtual void* previous(); + + /** + * Removes the Object last returned by the next() or previous() methods; + * @return the removed Object pointer + **/ + virtual void* remove(); + + /** + * Resets the current location within the List to the beginning of the List + **/ + virtual void reset(); + + /** + * sets this iterator to operate in the reverse direction + **/ + void reverse(); + +private: + + int count; + //-- points to the current list item + List::ListItem* currentItem; + + //-- points to the list to iterator over + List* list; + + //-- determins if we can remove the current item from the list + MBool allowRemove; + + MBool done; + + MBool moveForward; +}; + +#endif diff --git a/mozilla/extensions/transformiix/source/base/MITREObject.h b/mozilla/extensions/transformiix/source/base/MITREObject.h new file mode 100644 index 00000000000..4e07671f43a --- /dev/null +++ b/mozilla/extensions/transformiix/source/base/MITREObject.h @@ -0,0 +1,46 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#ifndef MITRE_MITREOBJECT_H +#define MITRE_MITREOBJECT_H + +/** + * A standard base class for many of the Class definitions in this + * application + * @author Keith Visco +**/ +class MITREObject { +public: + MITREObject() {}; + virtual ~MITREObject() {}; +}; + +/** + * A Simple MITREObject wrapper class +**/ +class MITREObjectWrapper : public MITREObject { +public: + MITREObjectWrapper(); + virtual ~MITREObjectWrapper(); + void* object; +}; + +#endif diff --git a/mozilla/extensions/transformiix/source/base/MITREObjectWrapper.cpp b/mozilla/extensions/transformiix/source/base/MITREObjectWrapper.cpp new file mode 100644 index 00000000000..cfef351ec7f --- /dev/null +++ b/mozilla/extensions/transformiix/source/base/MITREObjectWrapper.cpp @@ -0,0 +1,40 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "MITREObject.h" + + //--------------------------------------/ + //- A Simple MITREObject wrapper class -/ + //--------------------------------------/ + +/** + * Default Constructor +**/ +MITREObjectWrapper::MITREObjectWrapper() { + this->object = 0; +} //-- MITREObjectWrapper + +/** + * Default destructor +**/ +MITREObjectWrapper::~MITREObjectWrapper() { + this->object = 0; +} //-- ~MITREObjectWrapper diff --git a/mozilla/extensions/transformiix/source/base/Makefile b/mozilla/extensions/transformiix/source/base/Makefile new file mode 100644 index 00000000000..271ec36cf3d --- /dev/null +++ b/mozilla/extensions/transformiix/source/base/Makefile @@ -0,0 +1,50 @@ +target: make_base + +CC = g++ + +BASE_OBJS = CommandLineUtils.o \ + Double.o \ + Integer.o \ + List.o \ + MITREObjectWrapper.o \ + NamedMap.o \ + SimpleErrorObserver.o \ + Stack.o \ + String.o \ + StringList.o \ + Tokenizer.o + +make_base: $(BASE_OBJS) + +CommandLineUtils.o: CommandLineUtils.h CommandLineUtils.cpp + $(CC) -c CommandLineUtils.cpp + +Double.o: primitives.h Double.cpp + $(CC) -c Double.cpp + +Integer.o: primitives.h Integer.cpp + $(CC) -c Integer.cpp + +List.o: List.h List.cpp + $(CC) -c List.cpp + +MITREObjectWrapper.o: MITREObject.h MITREObjectWrapper.cpp + $(CC) -c MITREObjectWrapper.cpp + +NamedMap.o: String.h NamedMap.h NamedMap.cpp + $(CC) -c NamedMap.cpp + +SimpleErrorObserver.o: String.h baseutils.h ErrorObserver.h SimpleErrorObserver.cpp + $(CC) -c SimpleErrorObserver.cpp + +Stack.o: List.h Stack.h Stack.cpp + $(CC) -c Stack.cpp + +String.o: String.h String.cpp + $(CC) -c String.cpp + +StringList.o: String.h StringList.h StringList.cpp + $(CC) -c StringList.cpp + +Tokenizer.o: Tokenizer.h Tokenizer.cpp + $(CC) -c Tokenizer.cpp diff --git a/mozilla/extensions/transformiix/source/base/NamedMap.cpp b/mozilla/extensions/transformiix/source/base/NamedMap.cpp new file mode 100644 index 00000000000..443b64e451d --- /dev/null +++ b/mozilla/extensions/transformiix/source/base/NamedMap.cpp @@ -0,0 +1,313 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * A Named Map for MITREObjects + * @author Keith Visco +**/ + +#include "NamedMap.h" + + //-------------/ + //- Constants -/ +//-------------/ + +const int NamedMap::DEFAULT_SIZE = 17; + + //----------------/ + //- Constructors -/ +//----------------/ + +/** + * Creates a new NamedMap with the default Size +**/ +NamedMap::NamedMap() { + initialize(DEFAULT_SIZE); +} //-- NamedMap + +/** + * Creates a new NamedMap with the specified number of buckets +**/ +NamedMap::NamedMap(int size) { + initialize(size); +} //-- NamedMap + +/** + * Helper method for Constructors +**/ +void NamedMap::initialize(Int32 size) { + + //-- by default the NamedMap will not delete it's + //-- object references + doObjectDeletion = MB_FALSE; + + //-- create a new array of bucket pointers + elements = new BucketItem*[size]; + + //-- initialize all elements to 0; + for ( Int32 i = 0; i < size; i++ ) elements[i] = 0; + + numberOfBuckets = size; + numberOfElements = 0; +} //-- initialize + +/** + * Destructor for NamedMap +**/ +NamedMap::~NamedMap() { + //cout << "~NamedMap() - start"<next; + //-- repoint item to 0 to prevent deletion + if ( ! deleteObjects ) tItem->item = 0; + else { + delete tItem->item; + } + //--delete tItem; + delete tItem; + } + } + numberOfElements = 0; +} //-- clear + +void NamedMap::dumpMap() { + + + cout << "#NamedMap -------- { "<{"; + + BucketItem* item = elements[i]; + MBool hasPrevItem = MB_FALSE; + while (item) { + if (hasPrevItem) cout << ", "; + cout << item->key; + hasPrevItem = MB_TRUE; + item = item->next; + } + cout << "}"<item; + return 0; +} //-- get + +/** + * Returns true if there are no Nodes in the NodeStack. + * @return true if there are no Nodes in the NodeStack. +**/ +MBool NamedMap::isEmpty() { + return (numberOfElements == 0) ? MB_TRUE : MB_FALSE; +} //-- isEmpty + +/** + * Adds the specified Node to the top of this Stack. + * @param node the Node to add to the top of the Stack +**/ +void NamedMap::put(const char* key, MITREObject* obj) { + String sKey = key; + put(sKey, obj); +} //-- put + +/** + * Adds the specified Node to the top of this Stack. + * @param node the Node to add to the top of the Stack +**/ +void NamedMap::put(const String& key, MITREObject* obj) { + + //-- compute hash for key + unsigned long hashCode = hashKey(key); + //-- calculate index + int idx = hashCode % numberOfBuckets; + + //-- fetch first item in bucket + BucketItem* bktItem = elements[idx]; + + //-- if bktItem is 0 then there are no items is this Bucket, + //-- add to front of list + if ( !bktItem ) { + elements[idx] = createBucketItem(key, obj); + ++numberOfElements; + } + //-- find current item, or add to end of list + else { + BucketItem* prevItem = bktItem; + //-- advance to next spot + while ( bktItem ) { + //-- if current key equals desired key, break + if ( bktItem->key.isEqual(key) ) { + break; + } + prevItem = bktItem; + bktItem = bktItem->next; + } + //-- if we did not find a bucket Item create a new one + if ( !bktItem) { + bktItem = createBucketItem(key, obj); + prevItem->next = bktItem; + bktItem->prev = prevItem; + ++numberOfElements; + } + //-- we found bucket item, just set value + else bktItem->item = obj; + } +} //-- put +/** + * Removes the the specified Object from the NamedMap + * @param key the key of the Object to remove from the NamedMap + * @return the Object being removed +**/ +MITREObject* NamedMap::remove(String& key) { + + BucketItem* bktItem = getBucketItem(key); + + if ( bktItem ) { + bktItem->prev->next = bktItem->next; + numberOfElements--; + return bktItem->item; + } + return 0; + +} //-- remove + +/** + * Sets the object deletion flag. If set to true, objects in + * the NamedMap will be deleted upon calling the clear() method, or + * upon destruction. By default this is false. +**/ +void NamedMap::setObjectDeletion(MBool deleteObjects) { + doObjectDeletion = deleteObjects; +} //-- setObjectDeletion + +/** + * Returns the number of elements in the NodeStack + * @return the number of elements in the NodeStack +**/ +int NamedMap::size() { + return numberOfElements; +} //-- size + + //-------------------/ + //- Private Methods -/ +//-------------------/ + +NamedMap::BucketItem* NamedMap::createBucketItem(const String& key, MITREObject* objPtr) +{ + BucketItem* bktItem = new BucketItem; + bktItem->next = 0; + bktItem->prev = 0; + bktItem->key = key; + bktItem->item = objPtr; + return bktItem; +} //-- createBucketItem + +NamedMap::BucketItem* NamedMap::getBucketItem(const String& key) { + // compute hash for key + long hashCode = hashKey(key); + + int idx = hashCode % numberOfBuckets; + + BucketItem* bktItem = elements[idx]; + + while ( bktItem ) { + if ( bktItem->key.isEqual(key) ) return bktItem; + bktItem = bktItem->next; + } + + return bktItem; + +} //-- getBucketItem + +/** +**/ +unsigned long NamedMap::hashKey(const String& key) { + + Int32 len = key.length(); + UNICODE_CHAR* chars = new UNICODE_CHAR[len]; + key.toUnicode(chars); + + unsigned long hashCode = 0; + for (Int32 i = 0; i < len; i++) { + hashCode += ((Int32)chars[i]) << 3; + } + + return hashCode; +} //-- hashKey + + diff --git a/mozilla/extensions/transformiix/source/base/NamedMap.h b/mozilla/extensions/transformiix/source/base/NamedMap.h new file mode 100644 index 00000000000..1d553e4ed7b --- /dev/null +++ b/mozilla/extensions/transformiix/source/base/NamedMap.h @@ -0,0 +1,177 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * A Named Map for MITREObjects + * @author Keith Visco +**/ + +#ifndef MITREXSL_NAMEDMAP_H +#define MITREXSL_NAMEDMAP_H + +#include "String.h" +#include "baseutils.h" +#include "MITREObject.h" + +class NamedMap : public MITREObject { + + +public: + + //----------------/ + //- Constructors -/ + //----------------/ + + /** + * Creates a new NodeStack with the default Size + **/ + NamedMap(); + + /** + * Creates a new NodeStack with the specified number of buckets + **/ + NamedMap(int size); + + /** + * Destructor for a NamedMap table, will not delete references unless + * The setObjectDeletion flag has been set to MB_TRUE + **/ + virtual ~NamedMap(); + + /** + * Returns the object reference in this Map associated with the given name + * @return the object reference in this Map associated with the given name + **/ + MITREObject* get(const String& name); + + /** + * Returns the object reference in this Map associated with the given name + * @return the object reference in this Map associated with the given name + **/ + MITREObject* get(const char* name); + + /** + * Adds the Object reference to the map and associates it with the given name + **/ + void put(const String& name, MITREObject* obj); + + /** + * Adds the Object reference to the map and associates it with the given name + **/ + void put(const char* name, MITREObject* obj); + + /** + * Removes all elements from the Map table + **/ + void clear(); + + void clear(MBool doObjectDeletion); + + /** + * Returns true if the specified Node is contained in the set. + * if the specfied Node is null, then if the NodeSet contains a null + * value, true will be returned. + * @param node the element to search the NodeSet for + * @return true if specified Node is contained in the NodeSet + **/ + //MBool contains(Node* node); + + /** + * Compares the specified object with this NamedMap for equality. + * Returns true if and only if the specified Object is a NamedMap + * that hashes to the same value as this NamedMap + * @return true if and only if the specified Object is a NamedMap + * that hashes to the same value as this NamedMap + **/ + MBool equals(NamedMap* namedMap); + + /** + * Returns true if there are no Nodes in the NodeSet. + * @return true if there are no Nodes in the NodeSet. + **/ + MBool isEmpty(); + + /** + * Removes the Node at the specified index from the NodeSet + * @param index the position in the NodeSet to remove the Node from + * @return the Node that was removed from the list + **/ + MITREObject* remove(String& key); + + /** + * Sets the object deletion flag. If set to true, objects in + * the NamedMap will be deleted upon calling the clear() method, or + * upon destruction. By default this is false. + **/ + void setObjectDeletion(MBool deleteObjects); + + /** + * Returns the number of key-element pairs in the NamedMap + * @return the number of key-element in the NamedMap + **/ + int size(); + + void dumpMap(); + + + + + //-------------------/ + //- Private Members -/ + //-------------------/ + + +private: + + struct BucketItem { + String key; + MITREObject* item; + BucketItem* next; + BucketItem* prev; + }; + + static const int DEFAULT_SIZE; + + // map table + BucketItem** elements; + + Int32 numberOfBuckets; + Int32 numberOfElements; + MBool doObjectDeletion; + + //-------------------/ + //- Private Methods -/ + //-------------------/ + + BucketItem* createBucketItem(const String& key, MITREObject* objPtr); + + BucketItem* getBucketItem(const String& key); + + unsigned long hashKey(const String& key); + + /** + * Helper method for constructors + **/ + void initialize(int size); + +}; //-- NamedMap + +#endif diff --git a/mozilla/extensions/transformiix/source/base/SimpleErrorObserver.cpp b/mozilla/extensions/transformiix/source/base/SimpleErrorObserver.cpp new file mode 100644 index 00000000000..bf598199a64 --- /dev/null +++ b/mozilla/extensions/transformiix/source/base/SimpleErrorObserver.cpp @@ -0,0 +1,76 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "ErrorObserver.h" + +/** + * Creates a new SimpleErrorObserver. + * All errors will be printed to the console (cout). +**/ +SimpleErrorObserver::SimpleErrorObserver() { + errStream = &cout; + hideWarnings = MB_FALSE; +} //-- SimpleErrorObserver + +/** + * Creates a new SimpleErrorObserver. + * All errors will be printed to the given ostream. +**/ +SimpleErrorObserver::SimpleErrorObserver(ostream& errStream) { + this->errStream = &errStream; + hideWarnings = MB_FALSE; +} //-- SimpleErrorObserver + +/** + * Notifies this Error observer of a new error, with default + * level of NORMAL +**/ +void SimpleErrorObserver::recieveError(String& errorMessage) { + *errStream << "error: " << errorMessage << endl; + errStream->flush(); +} //-- recieveError + +/** + * Notifies this Error observer of a new error using the given error level +**/ +void SimpleErrorObserver::recieveError(String& errorMessage, ErrorLevel level) { + + + switch ( level ) { + case ErrorObserver::FATAL : + *errStream << "fatal error: "; + break; + case ErrorObserver::WARNING : + if ( hideWarnings ) return; + *errStream << "warning: "; + break; + default: + *errStream << "error: "; + break; + } + + *errStream << errorMessage << endl; + errStream->flush(); +} //-- recieveError + +void SimpleErrorObserver::supressWarnings(MBool supress) { + this->hideWarnings = supress; +} //-- supressWarnings diff --git a/mozilla/extensions/transformiix/source/base/Stack.cpp b/mozilla/extensions/transformiix/source/base/Stack.cpp new file mode 100644 index 00000000000..a4a73e11d36 --- /dev/null +++ b/mozilla/extensions/transformiix/source/base/Stack.cpp @@ -0,0 +1,115 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * Stack + * @author Keith Visco + *
+ *
+ * Modifications:
+ * 19990806: Larry Fitzpatrick
+ *  - in method #peek():
+ *    - Changed ListItem::ListItem to List::ListItem
+ * 
+**/ + +#include "Stack.h" + + //-------------/ + //- Stack.cpp -/ +//-------------/ + +/** + * Creates a new Stack +**/ +Stack::Stack() : List() { +} //-- Stack + + +/** + * Destructor for Stack, will not delete Object references +**/ +Stack::~Stack() { + //-- the base destructor for List will do all clean up +} + +/** + * Returns an iterator that will iterator over the Stack, from the topmost + * element to the bottom element. + * You will need to delete this Iterator when you are done +**/ +StackIterator* Stack::iterator() { + StackIterator* iter = (StackIterator*)List::iterator(); + iter->reverse(); + return iter; +} //-- iterator + +/** + * Returns the specified Object from the top of this Stack, + * without removing it from the stack. + * @return a pointer to the object that is the top of this Stack +**/ +void* Stack::peek() { + void* obj = 0; + List::ListItem* item = getLastItem(); + if ( item ) obj = item->objPtr; + return obj; +} //-- peek + +/** + * Adds the specified Object to the top of this Stack. + * @param obj a pointer to the object that is to be added to the + * top of this Stack +**/ +void Stack::push(void* obj) { + add(obj); +} //-- push + +/** + * Removes and returns the specified Object from the top of this Stack. + * @return a pointer to the object that was the top of this Stack +**/ +void* Stack::pop() { + void* obj = 0; + ListItem* item = getLastItem(); + if ( item ) obj = item->objPtr; + item = remove(item); + item->objPtr = 0; + delete item; + return obj; +} //-- pop + +/** + * Returns true if there are no objects in the Stack. + * @return true if there are no objects in the Stack. +**/ +MBool Stack::empty() { + return (MBool) (getLength() == 0); +} //-- empty + +/** + * Returns the number of elements in the Stack + * @return the number of elements in the Stack +**/ +int Stack::size() { + return getLength(); +} //-- size + diff --git a/mozilla/extensions/transformiix/source/base/Stack.h b/mozilla/extensions/transformiix/source/base/Stack.h new file mode 100644 index 00000000000..b3693c7d679 --- /dev/null +++ b/mozilla/extensions/transformiix/source/base/Stack.h @@ -0,0 +1,94 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * Stack + * @author Keith Visco +**/ + +#include "List.h" +#include "baseutils.h" + + +#ifndef MITRE_STACK_H +#define MITRE_STACK_H + +typedef ListIterator StackIterator; + +class Stack : private List { + +public: + + //----------------/ + //- Constructors -/ + //----------------/ + + /** + * Creates a new Stack + **/ + Stack(); + + + /** + * Destructor for Stack, will not delete Object references + **/ + virtual ~Stack(); + + StackIterator* iterator(); + + /** + * Returns the specified Object from the top of this Stack, + * without removing it from the stack. + * @return a pointer to the object that is the top of this Stack + **/ + void* peek(); + + /** + * Adds the specified Object to the top of this Stack. + * @param obj a pointer to the object that is to be added to the + * top of this Stack + **/ + void push(void* obj); + + /** + * Removes and returns the specified Object from the top of this Stack. + * @return a pointer to the object that was the top of this Stack + **/ + void* pop(); + + /** + * Returns true if there are no objects in the Stack. + * @return true if there are no objects in the Stack. + **/ + MBool empty(); + + /** + * Returns the number of elements in the Stack + * @return the number of elements in the Stack + **/ + int size(); + +private: + +}; //-- Stack + + +#endif diff --git a/mozilla/extensions/transformiix/source/base/String.cpp b/mozilla/extensions/transformiix/source/base/String.cpp new file mode 100644 index 00000000000..f298d20c9cd --- /dev/null +++ b/mozilla/extensions/transformiix/source/base/String.cpp @@ -0,0 +1,1154 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +// Tom Kneeland (3/17/99) +// +// Implementation of a simple String class +// +// Modification History: +// Who When What +// TK 03/17/99 Created +// TK 03/23/99 Released without "lastIndexOf" functions +// TK 04/02/99 Added support for 'const' strings, and added +// 'operator=' for constant char*. +// TK 04/09/99 Overloaded the output operator (<<). Currently it only +// supports outputing the String to a C sytle character based +// stream. +// TK 04/09/99 Provided support for the extraction of the DOM_CHAR +// representation of the string. The new method, "toDomChar()" +// returns a constant pointer to the internal DOM_CHAR string +// buffer. +// TK 04/10/99 Added the implementation for appending an array of DOM_CHARs +// to a string. It should be noted that a length needs to be +// provided in order to determine the length of the source +// array. +// TK 04/22/99 Fixed a bug where setting a string equal to NULL would cause +// a core dump. Also added support for constructing a string +// using the NULL identifier. +// Modified the output operator (<<) to accept a const String +// reference. This eliminates a wasteful copy constructor call. +// TK 04/28/99 Modified the clear() method to leave the DOM_CHAR array +// in place. +// TK 04/28/99 Added 3 new member functions: insert, deleteChars, and +// replace. +// TK 05/05/99 Added support for implicit integer conversion. This allows +// integers to be appended, inserted, and used as replacements +// for DOM_CHARs. To support this feature, ConvertInt has been +// added which converts the given integer to a string and stores +// it in the target. +// TK 05/05/99 Converted DOM_CHAR to UNICODE_CHAR +// +// KV 07/29/1999 Added lastIndexOf methods +// KV 07/29/1999 Changed indexOf methods with no offset, to call the +// indexOf methods with offset of 0. This allows re-use of +// code, makes it easier to debug, and minimizes the size of +// the implementation +// LF 08/06/1999 In method #operator=, +// added line: return *this +// KV 08/11/1999 changed charAt to return -1, if index is out of bounds, instead of 0, +// since 0, is a valid character, and this makes my code more compatible +// with Java +// KV 08/11/1999 removed PRBool, uses baseutils.h (MBool) + + +#include +#include +#include "String.h" +#include + +// +//Default Constructor, create an empty String +// +String::String() +{ + strBuffer = NULL; + bufferLength = 0; + strLength = 0; +} + +// +//Create an empty String of a specific size +// +String::String(Int32 initSize) +{ + strBuffer = new UNICODE_CHAR[initSize]; + bufferLength = initSize; + strLength = 0; +} + +// +//Create a copy of the source String +// +String::String(const String& source) +{ + + Int32 copyLoop; + + //Allocate space for the source string + strLength = source.length(); + + //-- modified by kvisco to only use necessay amount of space + //-- was: bufferLength = source.bufferLength; + bufferLength = strLength; + + strBuffer = new UNICODE_CHAR[bufferLength]; + + //Copy the new string data after the old data + for (copyLoop=0;copyLoop strLength) + { + ensureCapacity(totalOffset - strLength); + strLength += totalOffset - strLength; + } + + for (replaceLoop=0;replaceLoop strLength) + { + ensureCapacity(totalOffset - strLength); + strLength += totalOffset - strLength; + } + + for (replaceLoop=0;replaceLoop strLength) + { + ensureCapacity(totalOffset - strLength); + strLength += totalOffset - strLength; + } + + for (replaceLoop=0;replaceLoop current length, the string will be extended + * and padded with '\0' null characters. Otherwise the String + * will be truncated +**/ +void String::setLength(Int32 length) { + setLength(length, '\0'); +} //-- setLength + +/** + * Sets the Length of this String, if length is less than 0, it will + * be set to 0; if length > current length, the string will be extended + * and padded with given pad character. Otherwise the String + * will be truncated +**/ +void String::setLength(Int32 length, UNICODE_CHAR padChar) { + if ( length < 0 ) strLength = 0; + else if ( length > strLength ) { + Int32 diff = length-strLength; + ensureCapacity(diff); + for ( Int32 i = strLength; i < length; i++ ) + strBuffer[i] = padChar; + strLength = length; + } + else strLength = length; +} //-- setLength + +// +//Delete the "substring" starting at "offset" and proceeding for "count" number +//of characters (or until the end of the string, whichever comes first). +// +void String::deleteChars(Int32 offset, Int32 count) +{ + Int32 deleteLoop; + Int32 offsetCount; + + offset = offset < 0 ? 0 : offset; + offsetCount = offset + count; + + if (offsetCount < strLength) + { + for (deleteLoop=0;deleteLoop= 0)) + return strBuffer[index]; + else + return -1; +} + +// +//Clear out the string by simply setting the length to zero. The buffer is +//left intact. +// +void String::clear() +{ + strLength = 0; +} + +// +//Make sure the buffer has room for 'capacity' UNICODE_CHARS. +// +void String::ensureCapacity(Int32 capacity) +{ + UNICODE_CHAR* tempStrBuffer = NULL; + + //Check for the desired capacity + Int32 freeSpace = bufferLength - strLength; //(added by kvisco) + + if (freeSpace < capacity) { + + //-- modified by kvisco to only add needed capacity, + //-- not extra bytes as before + //-- old : bufferLength += capacity; + bufferLength += capacity - freeSpace; + + tempStrBuffer = new UNICODE_CHAR[bufferLength]; + copyString(tempStrBuffer); + + //If the old string contained any data, delete it, and save the new. + if (strBuffer) + delete strBuffer; + + strBuffer = tempStrBuffer; + } +} + +/** + * Performs a CASE SENSITIVE search of the string for the first occurence + * of 'data'. If found return the index, else return NOT_FOUND. + * -- changed by kvisco to call indexOf(UNICODE_CHAR, Int32) +**/ +Int32 String::indexOf(UNICODE_CHAR data) const +{ + return indexOf(data, 0); +} //-- indexOf + +// +//Starting at 'offset' perform a CASE SENSITIVE search of the string looking +//for the first occurence of 'data'. If found return the index, else return +//NOT_FOUND. If the offset is less than zero, then start at zero. +// +Int32 String::indexOf(UNICODE_CHAR data, Int32 offset) const +{ + Int32 searchIndex = offset < 0 ? searchIndex = 0 : searchIndex = offset; + + while (1) + { + if (searchIndex >= strLength) + return NOT_FOUND; + else if (strBuffer[searchIndex] == data) + return searchIndex; + else + ++searchIndex; + } +} //-- indexOf + +// +//Returns the index of the first occurence of data +// +Int32 String::indexOf(const String& data) const +{ + Int32 searchIndex = 0; + + while (1) + { + if (searchIndex <= (strLength - data.length())) + { + if (isEqual(&strBuffer[searchIndex], + &data.strBuffer[0], + data.length())) + return searchIndex; + } + else + return NOT_FOUND; + + searchIndex++; + } +} + +// +//Returns the index of the first occurrence of data starting at offset +// +Int32 String::indexOf(const String& data, Int32 offset) const +{ + Int32 searchIndex = offset < 0 ? 0 : offset; + + while (1) + { + if (searchIndex <= (strLength - data.length())) + { + if (isEqual(&strBuffer[searchIndex], + &data.strBuffer[0], + data.length())) + return searchIndex; + } + else + return NOT_FOUND; + + searchIndex++; + } +} + +// +//Check for equality between this string, and data +// +MBool String::isEqual(const String& data) const +{ + if (this == &data) + return MB_TRUE; + else if (strLength != data.length()) + return MB_FALSE; + else + return isEqual(strBuffer, data.strBuffer, data.length()); +} + +/** + * Returns index of last occurrence of data + *
+ * Added implementation 19990729 (kvisco) +**/ +Int32 String::lastIndexOf(UNICODE_CHAR data) const +{ + return lastIndexOf(data, strLength-1); +} //-- lastIndexOf + +/** + * Returns the index of the last occurrence of data starting at offset + *
+ * Added implementation 19990729 (kvisco) +**/ +Int32 String::lastIndexOf(UNICODE_CHAR data, Int32 offset) const +{ + if ((offset < 0) || (offset >= strLength)) return NOT_FOUND; + + Int32 searchIndex = offset; + while (searchIndex >= 0) { + if (strBuffer[searchIndex] == data) return searchIndex; + --searchIndex; + } + return NOT_FOUND; + +} //-- lastIndexOf + +/** + * Returns the index of the last occurrence of data + *
+ * Added implementation 19990729 (kvisco) +**/ +Int32 String::lastIndexOf(const String& data) const +{ + return lastIndexOf(data, strLength-1); +} //-- lastIndexOf + +/** + * Returns the index of the last occurrence of data starting at offset + *
+ * Added implementation 19990729 (kvisco) +**/ +Int32 String::lastIndexOf(const String& data, Int32 offset) const +{ + if ((offset < 0) || (offset >= strLength)) return NOT_FOUND; + return NOT_FOUND; +} + +// +//Returns the length of the String +// +Int32 String::length() const +{ + return strLength; +} + +// +//Returns a subString starting at start +// +String& String::subString(Int32 start, String& dest) const +{ + Int32 srcLoop; + Int32 destLoop = 0; + + start = start < 0? 0 : start; + + dest.clear(); + if (start < strLength) + { + dest.ensureCapacity(strLength - start); + for (srcLoop=start;srcLoop strLength? strLength : end; + + dest.clear(); + if ((start < end)) + { + dest.ensureCapacity(end - start); + for (srcLoop=start;srcLoop= 'A') && + (strBuffer[conversionLoop] <= 'Z')) + strBuffer[conversionLoop] += 32; + } +} + +// +//Convert String to uppercase +// +void String::toUpperCase() +{ + Int32 conversionLoop; + + for (conversionLoop=0;conversionLoop= 'a') && + (strBuffer[conversionLoop] <= 'z')) + strBuffer[conversionLoop] -= 32; + } +} + +// +//Trim whitespace from both ends of String +// +void String::trim() +{ + Int32 trimLoop = strLength - 1; + Int32 cutLoop; + MBool done = MB_FALSE; + + //As long as we are not working on an emtpy string, trim from the right + //first, so we don't have to move useless spaces when we trim from the left. + if (strLength > 0) + { + while (!done) + { + if (strBuffer[trimLoop] == 32) + { + --strLength; //Trim the whitespace by shorting the string. + --trimLoop; + } + else + done = MB_TRUE; + } + } + + //Now, if there are any characters left to the string, Trim to the left. + //First count the number of "left" spaces. Then move all characters to the + //left by that ammount. + if (strLength > 0) + { + done = MB_FALSE; + trimLoop = 0; + while (!done) + { + if (strBuffer[trimLoop] == 32) + ++trimLoop; + else + done = MB_TRUE; + } + + if (trimLoop < strLength) + { + for (cutLoop=trimLoop;cutLoop current length, the string will be extended + * and padded with '\0' null characters. Otherwise the String + * will be truncated + **/ + void setLength(Int32 length); + + /** + * Sets the Length of this String, if length is less than 0, it will + * be set to 0; if length > current length, the string will be extended + * and padded with given pad character. Otherwise the String + * will be truncated + **/ + void setLength(Int32 length, UNICODE_CHAR padChar); + + /** + * Returns a substring starting at start + * Note: the dest String is cleared before use + **/ + String& subString(Int32 start, String& dest) const; + + /** + * Returns the subString starting at start and ending at end + * Note: the dest String is cleared before use + **/ + String& subString(Int32 start, Int32 end, String& dest) const; + + //Convert the internal rep. to a char buffer + char* toChar(char* dest) const; + UNICODE_CHAR* toUnicode(UNICODE_CHAR* dest) const; + + void toLowerCase(); //Convert string to lowercase + void toUpperCase(); //Convert string to uppercase + void trim(); //Trim whitespace from both ends of string + + void reverse(); //Reverse the string + + private: + Int32 strLength; + Int32 bufferLength; + UNICODE_CHAR* strBuffer; + + //String copies itself to the destination + void copyString(UNICODE_CHAR* dest); + + //Compare the two string representations for equality + MBool isEqual(const UNICODE_CHAR* data, const UNICODE_CHAR* search, + Int32 length) const; + + //Convert an Int into a String + String& ConvertInt(Int32 value, String& target); + + //Calculates the length of a null terminated UNICODE_CHAR array + Int32 UnicodeLength(const UNICODE_CHAR* data); +}; + +ostream& operator<<(ostream& output, const String& source); + +#endif diff --git a/mozilla/extensions/transformiix/source/base/StringList.cpp b/mozilla/extensions/transformiix/source/base/StringList.cpp new file mode 100644 index 00000000000..072329c67b0 --- /dev/null +++ b/mozilla/extensions/transformiix/source/base/StringList.cpp @@ -0,0 +1,306 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * StringList + * @author Keith Visco +**/ + +#include +#include "StringList.h" + +/** + * Creates an empty list +**/ +StringList::StringList() { + firstItem = 0; + lastItem = 0; + itemCount = 0; +} //-- StringList; + +/** + * StringList Destructor, Cleans up pointers and will delete the String + * references, make sure you make copies of any needed Strings +*/ +StringList::~StringList() { + StringListItem* item = firstItem; + while (item) { + StringListItem* tItem = item; + item = item->nextItem; + delete tItem->strptr; + delete tItem; + } +} //-- ~StringList + +void StringList::add(String* strptr) { + StringListItem* sItem = new StringListItem; + sItem->strptr = strptr; + sItem->nextItem = 0; + sItem->prevItem = lastItem; + if (lastItem) lastItem->nextItem = sItem; + lastItem = sItem; + if (!firstItem) firstItem = sItem; + + // increase the item count + ++itemCount; +} //-- add + +MBool StringList::contains(String& search) { + StringListItem* sItem = firstItem; + while ( sItem ) { + if ( search.isEqual(*sItem->strptr)) return MB_TRUE; + sItem = sItem->nextItem; + } + return MB_FALSE; +} //-- contains + +/** + * Returns the number of Strings in this List +**/ +Int32 StringList::getLength() { + return itemCount; +} //-- getLength + + +/** + * Inserts the given String pointer as the item just after refItem. + * If refItem is a null pointer the String will inserted at the + * beginning of the List (ie, insert after nothing). + * This method assumes refItem is a member of this list, and since this + * is a private method, I feel that's a valid assumption +**/ +void StringList::insertAfter(String* strptr, StringListItem* refItem) { + + //-- if refItem == null insert at end + if (!refItem) { + if (firstItem) insertBefore(strptr, firstItem); + else add(strptr); + return; + } + + //-- if inserting at end of list + if (refItem == lastItem) { + add(strptr); + return; + } + + //-- insert into middle of list + StringListItem* sItem = new StringListItem; + sItem->strptr = strptr; + sItem->prevItem = refItem; + sItem->nextItem = refItem->nextItem; + refItem->nextItem = sItem; + + // increase the item count + ++itemCount; +} //-- insertAfter + +/** + * Inserts the given String pointer as the item just before refItem. + * If refItem is a null pointer the String will inserted at the + * end of the List (ie, insert before nothing). + * This method assumes refItem is a member of this list, and since this + * is a private method, I feel that's a valid assumption +**/ +void StringList::insertBefore(String* strptr, StringListItem* refItem) { + + //-- if refItem == null insert at end + if (!refItem) { + add(strptr); + return; + } + + StringListItem* sItem = new StringListItem; + sItem->strptr = strptr; + sItem->nextItem = refItem; + sItem->prevItem = refItem->prevItem; + refItem->prevItem = sItem; + + if (refItem == firstItem) firstItem = sItem; + if (itemCount == 0) lastItem = sItem; + + // increase the item count + ++itemCount; +} //-- insertBefore + +/** + * Returns a StringListIterator for this StringList +**/ +StringListIterator& StringList::iterator() { + return *(new StringListIterator(this)); +} + +String* StringList::remove(String* strptr) { + StringListItem* sItem = firstItem; + while (sItem) { + if (sItem->strptr == strptr) { + remove(sItem); + delete sItem; + return strptr; + } + sItem = sItem->nextItem; + } + // not in list + return 0; +} //-- remove + +StringList::StringListItem* StringList::remove(StringList::StringListItem* sItem) { + if (sItem->prevItem) { + sItem->prevItem->nextItem = sItem->nextItem; + } + if (sItem == firstItem) firstItem = sItem->nextItem; + if (sItem == lastItem) lastItem = sItem->prevItem; + //-- decrease Item count + --itemCount; + return sItem; +} //-- remove + +/** + * Removes all Strings equal to the given String from the list + * All removed strings will be destroyed +**/ +void StringList::remove(String& search) { + StringListItem* sItem = firstItem; + while (sItem) { + if (sItem->strptr->isEqual(search)) { + delete sItem->strptr; + StringListItem* temp = remove(sItem); + sItem = sItem->nextItem; + delete temp; + } + else sItem = sItem->nextItem; + } +} //-- remove + + //----------------------------------------/ + //- Implementation of StringListIterator -/ +//----------------------------------------/ + + +/** + * Creates a new StringListIterator for the given StringList +**/ +StringListIterator::StringListIterator(StringList* list) { + stringList = list; + currentItem = 0; + allowRemove = MB_FALSE; +} //-- StringListIterator + +StringListIterator::~StringListIterator() { + //-- overrides default destructor to do nothing +} //-- ~StringListIterator + +/** + * Adds the String pointer to the StringList of this StringListIterator. + * The String pointer is inserted as the next item in the StringList + * based on the current position within the StringList +**/ +void StringListIterator::add(String* strptr) { + + stringList->insertAfter(strptr,currentItem); + allowRemove = MB_FALSE; + +} //-- add + +/** + * Returns true if a sucessful call to the next() method can be made +**/ +MBool StringListIterator::hasNext() { + if (currentItem) { + return (MBool)(currentItem->nextItem); + } + return (MBool)(stringList->firstItem); +} //-- hasNext + +/** + * Returns true if a successful call to the previous() method can be made +**/ +MBool StringListIterator::hasPrevious() { + if (currentItem) { + return (MBool)(currentItem->prevItem); + } + return MB_FALSE; +} //-- hasPrevious + +/** + * Returns the next String in the list +**/ +String* StringListIterator::next() { + + if (currentItem) { + if (currentItem->nextItem) { + currentItem = currentItem->nextItem; + allowRemove = MB_TRUE; + return currentItem->strptr; + } + } + else { + currentItem = stringList->firstItem; + allowRemove = MB_TRUE; + return currentItem->strptr; + } + return 0; +} //-- next + +/** + * Returns the previous String in the list +**/ +String* StringListIterator::previous() { + + if (currentItem) { + if (currentItem->prevItem) { + currentItem = currentItem->prevItem; + allowRemove = MB_TRUE; + return currentItem->strptr; + } + } + + return 0; +} +//-- prev + +/** + * Removes the String last return by the next() or previous(); + * The removed String* is returned +**/ +String* StringListIterator::remove() { + + if (allowRemove == MB_FALSE) return 0; + + allowRemove = MB_FALSE; + + StringList::StringListItem* sItem = 0; + if (currentItem) { + // Make previous Item the current Item or null + sItem = currentItem; + if (stringList->firstItem == sItem) currentItem = 0; + stringList->remove(sItem); + return sItem->strptr; + } + return 0; +} //-- remove + +/** + * Resets the current location within the StringList to the beginning +**/ +void StringListIterator::reset() { + currentItem = 0; +} //-- reset diff --git a/mozilla/extensions/transformiix/source/base/StringList.h b/mozilla/extensions/transformiix/source/base/StringList.h new file mode 100644 index 00000000000..0db6dbaf894 --- /dev/null +++ b/mozilla/extensions/transformiix/source/base/StringList.h @@ -0,0 +1,131 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * A class for keeping an ordered list of Strings + * @author Keith Visco +**/ + +#include "String.h" +#include "baseutils.h" + +#ifndef MITREXSL_STRINGLIST_H +#define MITREXSL_STRINGLIST_H + +class StringList { + friend class StringListIterator; + + public: + + /** + * Creates an empty StringList + **/ + StringList(); + + /** + * StringList destructor + **/ + ~StringList(); + + MBool contains(String& search); + + /** + * Returns the number of Strings in this List + **/ + Int32 getLength(); + + /** + * Returns a StringListIterator for this StringList + **/ + StringListIterator& iterator(); + + /** + * Adds the given String to the list + **/ + void add(String* strptr); + + /** + * Removes the given String pointer from the list + **/ + String* remove(String* strptr); + + /** + * Removes all Strings equal to the given String from the list + * All removed strings will be destroyed + **/ + void remove(String& search); + +protected: + struct StringListItem { + StringListItem* nextItem; + StringListItem* prevItem; + String* strptr; + }; + +private: + + StringListItem* firstItem; + StringListItem* lastItem; + Int32 itemCount; + + void insertAfter(String* strptr, StringListItem* sItem); + void insertBefore(String* strptr, StringListItem* sItem); + + /** + * Removes the given StringListItem pointer from the list + **/ + StringListItem* remove(StringListItem* sItem); +}; + + + + +class StringListIterator { + +public: + + + StringListIterator(StringList* list); + ~StringListIterator(); + + void add(String* strptr); + + MBool hasNext(); + + MBool hasPrevious(); + + String* next(); + + String* previous(); + + String* remove(); + + void reset(); + +private: + + StringList::StringListItem* currentItem; + + StringList* stringList; + MBool allowRemove; +}; + +#endif diff --git a/mozilla/extensions/transformiix/source/base/Tokenizer.cpp b/mozilla/extensions/transformiix/source/base/Tokenizer.cpp new file mode 100644 index 00000000000..2e3d2fa692e --- /dev/null +++ b/mozilla/extensions/transformiix/source/base/Tokenizer.cpp @@ -0,0 +1,101 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * Tokenizer + * A simple String tokenizer + * @author Keith Visco + *
+ *
+ * Modifications:
+ * 19990806: Larry Fitzpatrick
+ *  - in method #nextToken():
+ *    - added void return type declaration
+ *    - added proper casts from Int32 to char
+ * 
+ * +**/ + +#include "Tokenizer.h" + +/** + * Creates a new Tokenizer +**/ +Tokenizer::Tokenizer() { + currentPos = 0; + size = 0; +} //-- tokenizer + +/** + * Creates a new Tokenizer using the given source string, + * uses the default set of delimiters {' ', '\r', '\n', '\t'}; +**/ +Tokenizer::Tokenizer(const String& source) { + currentPos = 0; + //-- copy source + str = source; + size = str.length(); + delimiters.append(" \n\r\t"); +} //-- Tokenizer + +/** + * Creates a new Tokenizer using the given source string + * and set of character delimiters +**/ +Tokenizer::Tokenizer(const String& source, const String& delimiters) { + currentPos = 0; + // copy source + str = source; + size = str.length(); + // copy tokens + this->delimiters.append(delimiters); +} //-- Tokenizer + + +/** + * Default Destructor +**/ +Tokenizer::~Tokenizer() {}; + +MBool Tokenizer::hasMoreTokens() { + return (MBool)(currentPos < size); +} //-- hasMoreTokens + +void Tokenizer::nextToken(String& buffer) { + buffer.clear(); + while ( currentPos < size) { + char ch = (char)str.charAt(currentPos); + //-- if character is not a delimiter..append + if (delimiters.indexOf(ch) < 0) buffer.append(ch); + else break; + ++currentPos; + } + //-- advance to next start pos + while ( currentPos < size ) { + char ch = (char)str.charAt(currentPos); + //-- if character is not a delimiter, we are at + //-- start of next token + if (delimiters.indexOf(ch) < 0) break; + ++currentPos; + } +} //-- nextToken + + diff --git a/mozilla/extensions/transformiix/source/base/Tokenizer.h b/mozilla/extensions/transformiix/source/base/Tokenizer.h new file mode 100644 index 00000000000..e8450987604 --- /dev/null +++ b/mozilla/extensions/transformiix/source/base/Tokenizer.h @@ -0,0 +1,87 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * Tokenizer + * A simple String tokenizer + * @author Keith Visco + *
+ *
+ * Modifications:
+ * 19990806: Larry Fitzpatrick
+ *  - for method #nextToken():
+ *    - added void return type declaration
+ * 
+ * +**/ + + +#include "baseutils.h" +#include "String.h" + + +#ifndef MITRE_TOKENIZER_H +#define MITRE_TOKENIZER_H + +class Tokenizer { + +public: + + //----------------/ + //- Constructors -/ + //----------------/ + + /** + * Creates a new Tokenizer + **/ + Tokenizer(); + + /** + * Creates a new Tokenizer using the given source string, + * uses the default set of tokens (' ', '\r', '\n', '\t'); + **/ + Tokenizer(const String& source); + + /** + * Creates a new Tokenizer using the given source string + * and set of character tokens + **/ + Tokenizer(const String& source, const String& tokens); + + + /** + * Default Destructor + **/ + virtual ~Tokenizer(); + + MBool hasMoreTokens(); + + void nextToken(String& buffer); + +private: + + Int32 currentPos; + Int32 size; + String str; + String delimiters; + +}; //-- Tokenizer +#endif diff --git a/mozilla/extensions/transformiix/source/base/baseutils.h b/mozilla/extensions/transformiix/source/base/baseutils.h new file mode 100644 index 00000000000..35011fa92ed --- /dev/null +++ b/mozilla/extensions/transformiix/source/base/baseutils.h @@ -0,0 +1,34 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +// Basic Definitions used throughout many of these classes + +#ifndef MITRE_BASEUTILS_H +#define MITRE_BASEUTILS_H + +typedef int Int32; + +typedef Int32 MBool; + +#define MB_TRUE (MBool)1 +#define MB_FALSE (MBool)0 + +#endif diff --git a/mozilla/extensions/transformiix/source/base/makefile.win b/mozilla/extensions/transformiix/source/base/makefile.win new file mode 100644 index 00000000000..d16547e12b0 --- /dev/null +++ b/mozilla/extensions/transformiix/source/base/makefile.win @@ -0,0 +1,70 @@ +#!nmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH=..\..\..\..\.. + +LIBRARY_NAME=transformix_base +MODULE=transformix +REQUIRES=xpcom raptor + +DEFINES=-DMOZILLA + +CPPSRCS= \ + CommandLineUtils.cpp \ + Double.cpp \ + Integer.cpp \ + List.cpp \ + MITREObjectWrapper.cpp \ + NamedMap.cpp \ + SimpleErrorObserver.cpp \ + Stack.cpp \ + String.cpp \ + StringList.cpp \ + Tokenizer.cpp \ + $(NULL) + +CPP_OBJS= \ + .\$(OBJDIR)\CommandLineUtils.obj \ + .\$(OBJDIR)\Double.obj \ + .\$(OBJDIR)\Integer.obj \ + .\$(OBJDIR)\List.obj \ + .\$(OBJDIR)\MITREObjectWrapper.obj \ + .\$(OBJDIR)\NamedMap.obj \ + .\$(OBJDIR)\SimpleErrorObserver.obj \ + .\$(OBJDIR)\Stack.obj \ + .\$(OBJDIR)\String.obj \ + .\$(OBJDIR)\StringList.obj \ + .\$(OBJDIR)\Tokenizer.obj \ + $(NULL) + +EXPORTS = \ + $(NULL) + +LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor + +LCFLAGS = \ + $(LCFLAGS) \ + $(DEFINES) \ + $(NULL) + +include <$(DEPTH)\config\rules.mak> + +libs:: $(LIBRARY) + $(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib + +clobber:: + rm -f $(DIST)\lib\$(LIBRARY_NAME).lib diff --git a/mozilla/extensions/transformiix/source/base/primitives.h b/mozilla/extensions/transformiix/source/base/primitives.h new file mode 100644 index 00000000000..883074efe1a --- /dev/null +++ b/mozilla/extensions/transformiix/source/base/primitives.h @@ -0,0 +1,173 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + + + +#ifndef MITRE_PRIMITIVES_H +#define MITRE_PRIMITIVES_H + +#include "MITREObject.h" +#include "baseutils.h" +#include "String.h" +#include + +#ifdef MOZILLA +#include +#endif + +/** + * A wrapper for the primitive double type, and provides some simple + * floating point related routines + * @author Larry Fitzpatrick + * @author Keith Visco +**/ +class Double : public MITREObject { + +public: + + static const double NaN; + static const double POSITIVE_INFINITY; + static const double NEGATIVE_INFINITY; + + /** + * Creates a new Double with it's value initialized to 0; + **/ + Double(); + + /** + * Creates a new Double with it's value initialized to the given double + **/ + Double(double dbl); + + /** + * Creates a new Double with it's value initialized from the given String. + * The String will be converted to a double. If the String does not + * represent an IEEE 754 double, the value will be initialized to NaN + **/ + Double(const String& string); + + /** + * Returns the value of this Double as a double + **/ + double doubleValue(); + + /** + * Returns the value of this Double as an int + **/ + int intValue(); + + /** + * Determins whether the given double represents positive or negative + * inifinity + **/ + static MBool isInfinite(double dbl); + + /** + * Determins whether this Double's value represents positive or + * negative inifinty + **/ + MBool isInfinite(); + + /** + * Determins whether the given double is NaN + **/ + static MBool isNaN(double dbl); + + /** + * Determins whether this Double's value is NaN + **/ + MBool isNaN(); + + /** + * Converts the value of this Double to a String, and places + * The result into the destination String. + * @return the given dest string + **/ + String& toString(String& dest); + + /** + * Converts the value of the given double to a String, and places + * The result into the destination String. + * @return the given dest string + **/ + static String& Double::toString(double value, String& dest); + + +private: + double value; + /** + * Converts the given String to a double, if the String value does not + * represent a double, NaN will be returned + **/ + static double toDouble(const String& str); +}; + + +/** + * A wrapper for the primitive int type, and provides some simple + * integer related routines + * @author Keith Visco +**/ +class Integer : public MITREObject { +public: + + /** + * Creates a new Integer initialized to 0. + **/ + Integer(); + + /** + * Creates a new Integer initialized to the given int value. + **/ + Integer(Int32 integer); + + /** + * Creates a new Integer based on the value of the given String + **/ + Integer::Integer(const String& str); + + /** + * Returns the int value of this Integer + **/ + int intValue(); + + /** + * Converts the value of this Integer to a String + **/ + String& toString(String& dest); + + /** + * Converts the given int to a String + **/ + static String& toString(int value, String& dest); + +private: + + Int32 value; + + /** + * converts the given String to an int + **/ + static int intValue(const String& src); + +}; //-- Integer + +#endif diff --git a/mozilla/extensions/transformiix/source/clean.mk b/mozilla/extensions/transformiix/source/clean.mk new file mode 100644 index 00000000000..f23235a4910 --- /dev/null +++ b/mozilla/extensions/transformiix/source/clean.mk @@ -0,0 +1,30 @@ +target: clean + +CC = g++ + +PROJ_PATH = ${PWD} +ROOT_PATH = $(PROJ_PATH) +XML_PATH = $(ROOT_PATH)/xml +XSL_PATH = $(ROOT_PATH)/xsl +BASE_PATH = $(ROOT_PATH)/base +DOM_PATH = $(XML_PATH)/dom +NET_PATH = $(ROOT_PATH)/net +EXPR_PATH = $(XSL_PATH)/expr +XSLUTIL_PATH = $(XSL_PATH)/util +XMLPRINTER_PATH = $(XML_PATH)/printer +XMLPARSER_PATH = $(XML_PATH)/parser +EXPAT_PARSER_PATH = $(XMLPARSER_PATH)/xmlparse +EXPAT_TOKEN_PATH = $(XMLPARSER_PATH)/xmltok + +clean: + cd $(BASE_PATH); rm *.o; \ + cd $(NET_PATH); rm *.o; \ + cd $(XML_PATH); rm *.o; \ + cd $(DOM_PATH); rm *.o; \ + cd $(XMLPARSER_PATH); rm *.o; \ + cd $(EXPAT_PARSER_PATH); rm *.o; \ + cd $(EXPAT_TOKEN_PATH); rm *.o; \ + cd $(XMLPRINTER_PATH); rm *.o; \ + cd $(XSL_PATH); rm *.o; \ + cd $(XSLUTIL_PATH); rm *.o; \ + cd $(EXPR_PATH); rm *.o diff --git a/mozilla/extensions/transformiix/source/examples/TEST.XML b/mozilla/extensions/transformiix/source/examples/TEST.XML new file mode 100644 index 00000000000..12e53e278a3 --- /dev/null +++ b/mozilla/extensions/transformiix/source/examples/TEST.XML @@ -0,0 +1,13 @@ + + + + + + x + y + z + + + def + + diff --git a/mozilla/extensions/transformiix/source/examples/functions.html b/mozilla/extensions/transformiix/source/examples/functions.html new file mode 100644 index 00000000000..5bdd17edc6b --- /dev/null +++ b/mozilla/extensions/transformiix/source/examples/functions.html @@ -0,0 +1,986 @@ + + + + MII TransforMiiX Test Cases + + +
+ + MITRE + +
+ MII TransforMiiX Test Cases +
+

This document serves to test XPath and XSL functions.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Boolean Functions +
+ Function: + + boolean + boolean( + object + ) +
+ Test: + <xsl:value-of select="boolean(descendant::z)"/>
+
+ Desired Result: + + true +
+
+ Result: + + true +
+ Test: + <xsl:value-of select="boolean(*)"/>
+
+ Desired Result: + + true +
+
+ Result: + + true +
+ Function: + + boolean + false() +
+ Test: + <xsl:value-of select="false()"/>
+
+ Desired Result: + + false +
+
+ Result: + + false +
+ Function: + + boolean + true() +
+ Test: + <xsl:value-of select="true()"/>
+
+ Desired Result: + + true +
+
+ Result: + + true +
+ Function: + + boolean + not( + boolean + ) +
+ Test: + <xsl:value-of select="not(true())"/>
+
+ Desired Result: + + false +
+
+ Result: + + false +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ NodeSet Functions +
+ Function: + + number + count( + node-set + ) +
+ Test: + <xsl:value-of select="count(*)"/>
+
+ Desired Result: + + 4 +
+
+ Result: + + 4 +
+ Function: + + number + position() +
+ Test: + <xsl:value-of select="*[position()=3]"/>
+
+ Desired Result: + + z +
+
+ Result: + + z +
+ Function: + + number + last() +
+ Test: + <xsl:value-of select="*[last()-1]"/>
+
+ Desired Result: + + z +
+
+ Result: + + z +
+ Function: + String local-part( + node-set? + ) +
+ Test: + <xsl:value-of select="local-part(names/abc:test-name)"/>
+
+ Desired Result: + + test-name +
+
+ Result: + + test-name +
+ Function: + String local-part( + node-set? + ) +
+ Test: + <xsl:value-of select="local-part()"/>
+
+ Desired Result: + + document +
+
+ Result: + + document +
+ Function: + Stringname( + node-set? + ) +
+ Test: + <xsl:value-of select="name(names/abc:test-name)"/>
+
+ Desired Result: + + abc:test-name +
+
+ Result: + + abc:test-name +
+ Function: + Stringnamespace( + node-set? + ) +
+ Test: + <xsl:value-of select="namespace(names/abc:test-name)"/>
+
+ Desired Result: + + abc +
+
+ Result: + + abc +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ String Functions +
+ Function: + + string + string( + object? + ) +
+ Test: + <xsl:value-of select="string()"/>
+
+ Desired Result: + + x y z +
+
+ Result: + + x y z +
+ Test: + <xsl:value-of select="string('xyz')"/>
+
+ Desired Result: + + xyz +
+
+ Result: + + xyz +
+ Function: + + string + concat( + string, string, string* + ) +
+ Test: + <xsl:value-of select="concat('abc', 'def')"/>
+
+ Desired Result: + + abcdef +
+
+ Result: + + abcdef +
+ Function: + + boolean + contains( + string, string + ) +
+ Test: + <xsl:value-of select="contains('abcdef', 'efg')"/>
+
+ Desired Result: + + false +
+
+ Result: + + false +
+ Test: + <xsl:value-of select="contains('abcdef', 'bcd')"/>
+
+ Desired Result: + + true +
+
+ Result: + + true +
+ Function: + + boolean + starts-with( + string, string + ) +
+ Test: + <xsl:value-of select="starts-with('abcdef', 'abc')"/>
+
+ Desired Result: + + true +
+
+ Result: + + true +
+ Test: + <xsl:value-of select="starts-with('abcdef', 'xyz')"/>
+
+ Desired Result: + + false +
+
+ Result: + + false +
+ Function: + + number + string-length( + string? + ) +
+ Test: + <xsl:value-of select="string-length(name())"/>
+
+ Desired Result: + + 8 +
+
+ Result: + + 8 +
+ Test: + <xsl:value-of select="string-length('abcdef')"/>
+
+ Desired Result: + + 6 +
+
+ Result: + + 6 +
+ Function: + + string + substring( + string, number, number? + ) +
+ Test: + <xsl:value-of select="substring('12345', 1.5, 2.6)"/>
+
+ Desired Result: + + 234 +
+
+ Result: + + 234 +
+ Test: + <xsl:value-of select="substring('12345', 0, 3)"/>
+
+ Desired Result: + + 12 +
+
+ Result: + + 12 +
+ Test: + <xsl:value-of select="substring('12345', 0 div 0, 3)"/>
+
+ Desired Result: + + +
+
+ Result: + + +
+ Test: + <xsl:value-of select="substring('12345', 1, 0 div 0)"/>
+
+ Desired Result: + + +
+
+ Result: + + +
+ Test: + <xsl:value-of select="substring('12345', -42, 1 div 0)"/>
+
+ Desired Result: + + 12345 +
+
+ Result: + + 12345 +
+ Test: + <xsl:value-of select="substring('12345', -1 div 0, 1 div 0)"/>
+
+ Desired Result: + + +
+
+ Result: + + +
+ Function: + + string + substring-after( + string, string + ) +
+ Test: + <xsl:value-of select="substring-after('1999/04/01', '/')"/>
+
+ Desired Result: + + 04/01 +
+
+ Result: + + 04/01 +
+ Function: + + string + substring-before( + string, string + ) +
+ Test: + <xsl:value-of select="substring-before('1999/04/01', '/')"/>
+
+ Desired Result: + + 1999 +
+
+ Result: + + 1999 +
+ Function: + + string + translate( + string, string, string + ) +
+ Test: + <xsl:value-of select="translate('bar', 'abc', 'ABC')"/>
+
+ Desired Result: + + BAr +
+
+ Result: + + BAr +
+ Test: + <xsl:value-of select="translate('---aaa---', 'abc-', 'ABC')"/>
+
+ Desired Result: + + AAA +
+
+ Result: + + AAA +
+ + diff --git a/mozilla/extensions/transformiix/source/examples/functions.xml b/mozilla/extensions/transformiix/source/examples/functions.xml new file mode 100644 index 00000000000..4d401a5e38d --- /dev/null +++ b/mozilla/extensions/transformiix/source/examples/functions.xml @@ -0,0 +1,12 @@ + + + + + + x + y + z + + + + diff --git a/mozilla/extensions/transformiix/source/examples/functions.xsl b/mozilla/extensions/transformiix/source/examples/functions.xsl new file mode 100644 index 00000000000..9c772173d4f --- /dev/null +++ b/mozilla/extensions/transformiix/source/examples/functions.xsl @@ -0,0 +1,869 @@ + + + + + + + + + + + + + + + TransforMiiX + + + + + + + MII TransforMiiX Test Cases + + +
+ MITRE
+ MII TransforMiiX Test Cases +
+

+ This document serves to test XPath and XSL functions. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Boolean Functions +
Function: + boolean boolean(object) +
Test: + <xsl:value-of select="boolean(descendant::z)"/>
+
Desired Result: + true
+
Result: + + + +
Test: + <xsl:value-of select="boolean(*)"/>
+
Desired Result: + true
+
Result: + + + +
Function: + boolean false() +
Test: + <xsl:value-of select="false()"/>
+
Desired Result: + false
+
Result: + + + +
Function: + boolean true() +
Test: + <xsl:value-of select="true()"/>
+
Desired Result: + true
+
Result: + + + +
Function: + boolean not(boolean) +
Test: + <xsl:value-of select="not(true())"/>
+
Desired Result: + false
+
Result: + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ NodeSet Functions +
Function: + number count(node-set) +
Test: + <xsl:value-of select="count(*)"/>
+
Desired Result: + 4
+
Result: + + + +
Function: + number position() +
Test: + <xsl:value-of select="*[position()=3]"/>
+
Desired Result: + z
+
Result: + + + +
Function: + number last() +
Test: + <xsl:value-of select="*[last()-1]"/>
+
Desired Result: + z
+
Result: + + + +
Function: + String local-part(node-set?) +
Test: + <xsl:value-of select="local-part(names/abc:test-name)"/>
+
Desired Result: + test-name
+
Result: + + + +
Function: + String local-part(node-set?) +
Test: + <xsl:value-of select="local-part()"/>
+
Desired Result: + document
+
Result: + + + +
Function: + String name(node-set?) +
Test: + <xsl:value-of select="name(names/abc:test-name)"/>
+
Desired Result: + abc:test-name
+
Result: + + + +
Function: + String namespace(node-set?) +
Test: + <xsl:value-of select="namespace(names/abc:test-name)"/>
+
Desired Result: + abc
+
Result: + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ String Functions +
Function: + string string(object?) +
Test: + <xsl:value-of select="string()"/>
+
Desired Result: + x y z
+
Result: + + + +
Test: + <xsl:value-of select="string('xyz')"/>
+
Desired Result: + xyz
+
Result: + + + +
Function: + string concat(string, string, string*) +
Test: + <xsl:value-of select="concat('abc', 'def')"/>
+
Desired Result: + abcdef
+
Result: + + + +
Function: + boolean contains(string, string) +
Test: + <xsl:value-of select="contains('abcdef', 'efg')"/>
+
Desired Result: + false
+
Result: + + + +
Test: + <xsl:value-of select="contains('abcdef', 'bcd')"/>
+
Desired Result: + true
+
Result: + + + +
Function: + boolean starts-with(string, string) +
Test: + <xsl:value-of select="starts-with('abcdef', 'abc')"/>
+
Desired Result: + true
+
Result: + + + +
Test: + <xsl:value-of select="starts-with('abcdef', 'xyz')"/>
+
Desired Result: + false
+
Result: + + + +
Function: + number string-length(string?) +
Test: + <xsl:value-of select="string-length(name())"/>
+
Desired Result: + 8
+
Result: + + + +
Test: + <xsl:value-of select="string-length('abcdef')"/>
+
Desired Result: + 6
+
Result: + + + +
Function: + string substring(string, number, number?) +
Test: + <xsl:value-of select="substring('12345', 1.5, 2.6)"/>
+
Desired Result: + 234
+
Result: + + + +
Test: + <xsl:value-of select="substring('12345', 0, 3)"/>
+
Desired Result: + 12
+
Result: + + + +
Test: + <xsl:value-of select="substring('12345', 0 div 0, 3)"/>
+
Desired Result: +
+
Result: + + + +
Test: + <xsl:value-of select="substring('12345', 1, 0 div 0)"/>
+
Desired Result: +
+
Result: + + + +
Test: + <xsl:value-of select="substring('12345', -42, 1 div 0)"/>
+
Desired Result: + 12345
+
Result: + + + +
Test: + <xsl:value-of select="substring('12345', -1 div 0, 1 div 0)"/>
+
Desired Result: +
+
Result: + + + +
Function: + string substring-after(string, string) +
Test: + <xsl:value-of select="substring-after('1999/04/01', '/')"/>
+
Desired Result: + 04/01
+
Result: + + + +
Function: + string substring-before(string, string) +
Test: + <xsl:value-of select="substring-before('1999/04/01', '/')"/>
+
Desired Result: + 1999
+
Result: + + + +
Function: + string translate(string, string, string) +
Test: + <xsl:value-of select="translate('bar', 'abc', 'ABC')"/>
+
Desired Result: + BAr
+
Result: + + + +
Test: + <xsl:value-of select="translate('---aaa---', 'abc-', 'ABC')"/>
+
Desired Result: + AAA
+
Result: + + + +
+ + +
+ +
+ diff --git a/mozilla/extensions/transformiix/source/examples/identity-result.xml b/mozilla/extensions/transformiix/source/examples/identity-result.xml new file mode 100644 index 00000000000..de5c0758cf3 --- /dev/null +++ b/mozilla/extensions/transformiix/source/examples/identity-result.xml @@ -0,0 +1,8 @@ + + + + + x + y + z + diff --git a/mozilla/extensions/transformiix/source/examples/identity.xml b/mozilla/extensions/transformiix/source/examples/identity.xml new file mode 100644 index 00000000000..44901e7556b --- /dev/null +++ b/mozilla/extensions/transformiix/source/examples/identity.xml @@ -0,0 +1,9 @@ + + + + + + x + y + z + diff --git a/mozilla/extensions/transformiix/source/examples/identity.xsl b/mozilla/extensions/transformiix/source/examples/identity.xsl new file mode 100644 index 00000000000..69902ea91ab --- /dev/null +++ b/mozilla/extensions/transformiix/source/examples/identity.xsl @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + diff --git a/mozilla/extensions/transformiix/source/examples/test.html b/mozilla/extensions/transformiix/source/examples/test.html new file mode 100644 index 00000000000..325f2978ba3 --- /dev/null +++ b/mozilla/extensions/transformiix/source/examples/test.html @@ -0,0 +1,486 @@ + + instruction?> + + + + MII TransforMiiX Test Cases + + +
+ + MITRE + +
+ MII TransforMiiX Test Cases +
+

This document serves to test basic XSL expressions.

+

+ Testing xsl:variable +
+ Test:<xsl:value-of select="$product-name"/>
+ Desired Result:TransforMiiX
+ Result:TransforMiiX

+

+ Testing xsl:if +
+ Test:<xsl:if test="x | y | z">true</xsl:if>
+ Desired Result:true
+ Result:true

+

+ Testing xsl:choose +
+ Test:see source
+ Desired Result:true
+ Result:true

+

+ Testing parent and ancestor ops +
+ Test:see source
+ Desired Result:true
+ Result:true
+

+

+ Testing basic xsl:apply-templates +
+ Test:<xsl:apply-templates/>
+ Desired Result:element x, element y, element z
+ Result:element x,element y,element z +

+

+ Testing basic xsl:apply-templates with mode +
+ Test:<xsl:apply-templates mode="mode-test"/>
+ Desired Result:x, y, z
+ Result:x, y, z

+

+ Testing predicates +
+ Test:see source
+ Desired Result: + z +
+ Result: + z +

+

+ Testing predicates +
+ Test:see source
+ Desired Result: +
+ Result: +

+

+ Named Template/Call Template +
+ Test:<xsl:call-template name="named-template-test"/>
+ Desired Result:named template processed!
+ Result:named template processed!

+

+ Attribute Value Templates and variables +
+ Test: +

    <xsl:variable name="color">red</xsl:variable>
    <FONT COLOR="{$color}">Red Text</FONT>
+ Desired Result: + Red Text +
+ Result: + Red Text +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Axis Identifiers (these should work, I need more test cases though) +
+ Test: + <xsl:if test="descendant::z">true</xsl:if>
+
+ Desired Result: + + true +
+
+ Result: + + true +
+ Test: + <xsl:if test="not(descendant-or-self::no-element)">true</xsl:if>
+
+ Desired Result: + + true +
+
+ Result: + + true +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Creating Elements with xsl:element and xsl:attribute +
+ Test: + <xsl:element name="FONT">
<xsl:attribute name="COLOR">blue</xsl:attribute>
Passed
</xsl:element>
+ Desired Result: + + Passed +
+
+ Result: + + Passed +
+ Using Attribute Sets +
+ Test: + <FONT xsl:use-attribute-sets="style1">
Passed
</FONT>
+ Desired Result: + + Passed +
+
+ Result: + + Passed +
+ Test: + <xsl:element name="FONT" use-attribute-sets="style1 style2">
Passed
</xsl:element>
+ Desired Result: + + Passed +
+
+ Result: + + Passed +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Additive Expressions +
+ Test: + <xsl:value-of select="70+4"/>
+
+ Desired Result: + + 74 +
+
+ Result: + + 74 +
+ Test: + <xsl:value-of select="-70+4"/>
+
+ Desired Result: + + -66 +
+
+ Result: + + -66 +
+ Test: + <xsl:value-of select="1900+70+8-4"/>
+
+ Desired Result: + + 1974 +
+
+ Result: + + 1974 +
+ Test: + <xsl:value-of select="(4+5)-(9+9)"/>
+
+ Desired Result: + + -9 +
+
+ Result: + + -9 +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Multiplicative Expressions +
+ Test: + <xsl:value-of select="7*4"/>
+
+ Desired Result: + + 28 +
+
+ Result: + + 28 +
+ Test: + <xsl:value-of select="7mod4"/>
+
+ Desired Result: + + 3 +
+
+ Result: + + 3 +
+ Test: + <xsl:value-of select="7div4"/>
+
+ Desired Result: + + 1.75 +
+
+ Result: + + 1.75 +
+ Test: + <xsl:value-of select="7div0"/>
+
+ Desired Result: + + Infinity +
+
+ Result: + + Infinity +
+ Test: + <xsl:value-of select="0 div 0"/>
+
+ Desired Result: + + NaN +
+
+ Result: + + NaN +
+ Test: + <xsl:variable name="x" expr="7*3"/>
<xsl:variable name="y" expr="3"/>
<xsl:value-of select="$x div $y"/>
+
+ Desired Result: + + 7 +
+
+ Result: + + 7 +
+ + diff --git a/mozilla/extensions/transformiix/source/examples/test.xsl b/mozilla/extensions/transformiix/source/examples/test.xsl new file mode 100644 index 00000000000..0de98a6da1c --- /dev/null +++ b/mozilla/extensions/transformiix/source/examples/test.xsl @@ -0,0 +1,557 @@ + + + + + + + blue + +0 + + + + red + +0 + + + + + + this is a test processing ?> instruction + + MITRE TransforMiiX Test cases, written by Keith Visco. + + + + + + named template processed! + + + + + + + + TransforMiiX + + + + + + MII TransforMiiX Test Cases + + +
+ MITRE
+ MII TransforMiiX Test Cases +
+

+ This document serves to test basic XSL expressions. +

+ +

+ Testing xsl:variable
+ Test: <xsl:value-of select="$product-name"/>
+ Desired Result:TransforMiiX
+ Result: +

+ +

+ Testing xsl:if
+ Test: <xsl:if test="x | y | z">true</xsl:if>
+ Desired Result: true
+ Result: true +

+ + +

+ Testing xsl:choose
+ Test:see source
+ Desired Result: true
+ Result: + + error - a + true + error - b + false + +

+ +

+ Testing parent and ancestor ops
+ Test:see source
+ Desired Result: true
+ Result:true
+ +

+ + +

+ Testing basic xsl:apply-templates
+ Test:<xsl:apply-templates/>
+ Desired Result:element x, element y, element z
+ Result: +

+ + +

+ Testing basic xsl:apply-templates with mode
+ Test:<xsl:apply-templates mode="mode-test"/>
+ Desired Result:x, y, z
+ Result: +

+ +

+ Testing predicates
+ Test:see source
+ Desired Result: z
+ Result: + + + +

+ +

+ Testing predicates
+ Test:see source
+ Desired Result:
+ Result: + + + +

+ +

+ Named Template/Call Template
+ Test:<xsl:call-template name="named-template-test"/>
+ Desired Result:named template processed!
+ Result: +

+ +

+ Attribute Value Templates and variables
+ Test: +

    + <xsl:variable name="color">red</xsl:variable>
    + <FONT COLOR="{$color}">Red Text</FONT> +
+ Desired Result: + Red Text
+ Result: + red + Red Text +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Axis Identifiers (these should work, I need more test cases though) +
Test: + <xsl:if test="descendant::z">true</xsl:if>
+
Desired Result: + true
+
Result: + + true + +
Test: + <xsl:if test="not(descendant-or-self::no-element)">true</xsl:if>
+
Desired Result: + true
+
Result: + + true + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Creating Elements with xsl:element and xsl:attribute +
Test: + <xsl:element name="FONT">
+ <xsl:attribute name="COLOR">blue</xsl:attribute>
+ Passed
+ </xsl:element> +
Desired Result: + Passed
+
Result: + + blue + Passed + +
Using Attribute Sets
Test: + <FONT xsl:use-attribute-sets="style1">
+ Passed
+ </FONT> +
Desired Result: + Passed
+
Result: + + Passed + +
Test: + <xsl:element name="FONT" use-attribute-sets="style1 style2">
+ Passed
+ </xsl:element> +
Desired Result: + Passed
+
Result: + + Passed + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Additive Expressions +
Test: + <xsl:value-of select="70+4"/>
+
Desired Result: + 74
+
Result: + + + +
Test: + <xsl:value-of select="-70+4"/>
+
Desired Result: + -66
+
Result: + + + +
Test: + <xsl:value-of select="1900+70+8-4"/>
+
Desired Result: + 1974
+
Result: + + + +
Test: + <xsl:value-of select="(4+5)-(9+9)"/>
+
Desired Result: + -9
+
Result: + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Multiplicative Expressions +
Test: + <xsl:value-of select="7*4"/>
+
Desired Result: + 28
+
Result: + + + +
Test: + <xsl:value-of select="7mod4"/>
+
Desired Result: + 3
+
Result: + + + +
Test: + <xsl:value-of select="7div4"/>
+
Desired Result: + 1.75
+
Result: + + + +
Test: + <xsl:value-of select="7div0"/>
+
Desired Result: + Infinity
+
Result: + + + +
Test: + <xsl:value-of select="0 div 0"/>
+
Desired Result: + NaN
+
Result: + + + +
Test: + <xsl:variable name="x" expr="7*3"/>
+ <xsl:variable name="y" expr="3"/>
+ <xsl:value-of select="$x div $y"/>
+
Desired Result: + 7
+
Result: + + + + + +
+ + +
+ + + + , + element + + + + , + + + + + element (z): + + +
+ diff --git a/mozilla/extensions/transformiix/source/main/transformiix.cpp b/mozilla/extensions/transformiix/source/main/transformiix.cpp new file mode 100644 index 00000000000..ddbc420b8b4 --- /dev/null +++ b/mozilla/extensions/transformiix/source/main/transformiix.cpp @@ -0,0 +1,140 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "XSLProcessor.h" + + //--------------/ + //- Prototypes -/ +//--------------/ + +/** + * Prints the command line help screen to the console +**/ +void printHelp(); + +/** + * prints the command line usage information to the console +**/ +void printUsage(); + +/** + * The TransforMiiX command line interface + * @author Keith Visco +**/ +int main(int argc, char** argv) { + + XSLProcessor xslProcessor; + + String copyright("(C) 1999 The MITRE Corporation"); + cout << xslProcessor.getAppName() << " "; + cout << xslProcessor.getAppVersion() << copyright <length()+1]; + ifstream xmlInput(xmlFilename->toChar(chars), ios::in); + delete chars; + + //-- create document base + String documentBase; + URIUtils::getDocumentBase(*xmlFilename, documentBase); + + //-- handle output stream + ostream* resultOutput = &cout; + ofstream resultFileStream; + if ( outFilename ) { + chars = new char[outFilename->length()+1]; + resultFileStream.open(outFilename->toChar(chars), ios::out); + delete chars; + if ( !resultFileStream ) { + cout << "error opening output file: " << *xmlFilename << endl; + return -1; + } + resultOutput = &resultFileStream; + } + //-- process + if ( !xslFilename ) { + xslProcessor.process(xmlInput, documentBase, *resultOutput); + } + else { + //-- open XSL file + chars = new char[xslFilename->length()+1]; + ifstream xslInput(xslFilename->toChar(chars), ios::in); + delete chars; + xslProcessor.process(xmlInput, xslInput, *resultOutput); + } + resultFileStream.close(); + return 0; +} //-- main + +void printHelp() { + cout << "The following flags are available for use with TransforMiiX -"; + cout< diff --git a/mozilla/extensions/transformiix/source/net/Makefile b/mozilla/extensions/transformiix/source/net/Makefile new file mode 100644 index 00000000000..51f295c79f3 --- /dev/null +++ b/mozilla/extensions/transformiix/source/net/Makefile @@ -0,0 +1,22 @@ +target: make_netlib + +CC = g++ + +#ifndef PROJ_PATH +BASE_PATH = ../base +#endif + +INCLUDE_PATHS = -I . -I$(BASE_PATH) -I- + +BASE_OBJS = $(BASE_PATH)/String.o + +NET_OBJS = URIUtils.o + +ALL_OBJS = $(BASE_OBJS) \ + $(NET_OBJS) + + +make_netlib: $(ALL_OBJS) + +URIUtils.o: URIUtils.h URIUtils.cpp + $(CC) $(INCLUDE_PATHS) -c URIUtils.cpp diff --git a/mozilla/extensions/transformiix/source/net/URIUtils.cpp b/mozilla/extensions/transformiix/source/net/URIUtils.cpp new file mode 100644 index 00000000000..30e28e77e54 --- /dev/null +++ b/mozilla/extensions/transformiix/source/net/URIUtils.cpp @@ -0,0 +1,335 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +//package com.kvisco.net; + +#include "URIUtils.h" + +/** + * URIUtils + * A set of utilities for handling URIs + * @author Keith Visco + *
+ *
+ * Modifications:
+ * 19990806: Larry Fitzpatrick
+ *  - moved initialization of contanst shorts and chars from
+ *    URIUtils.h to here
+ * 
+ * +**/ + +//- Constants -/ + +const String URIUtils::HTTP_PROTOCOL = "http"; +const String URIUtils::FILE_PROTOCOL = "file"; +const char URIUtils::HREF_PATH_SEP = '/'; +const char URIUtils::DEVICE_SEP = '|'; +const char URIUtils::PORT_SEP = ':'; +const char URIUtils::PROTOCOL_SEP = ':'; +const short URIUtils::PROTOCOL_MODE = 1; +const short URIUtils::HOST_MODE = 2; +const short URIUtils::PORT_MODE = 3; +const short URIUtils::PATH_MODE = 4; + + +/** + * Returns an InputStream for the file represented by the href + * argument + * @param href the href of the file to get the input stream for. + * @param documentBase the document base of the href argument, if it + * is a relative href + * set documentBase to null if there is none. + * @return an InputStream to the desired resource + * @exception java.io.FileNotFoundException when the file could not be + * found +**/ +istream* URIUtils::getInputStream + (String& href, String& documentBase, String& errMsg) +{ + + istream* inStream = 0; + + //-- check for URL + ParsedURI* uri = parseURI(href); + if ( !uri->isMalformed ) { + inStream = openStream(uri); + delete uri; + return inStream; + } + delete uri; + + //-- join document base + href + String xHref; + if (documentBase.length() > 0) { + xHref.append(documentBase); + if (documentBase.charAt(documentBase.length()-1) != HREF_PATH_SEP) + xHref.append(HREF_PATH_SEP); + } + xHref.append(href); + + //-- check new href + uri = parseURI(xHref); + if ( !uri->isMalformed ) { + inStream = openStream(uri); + } + else { + // Try local files + char* fchars = new char[xHref.length()+1]; + ifstream* inFile = new ifstream(xHref.toChar(fchars), ios::in); + delete fchars; + if ( ! *inFile ) { + fchars = new char[href.length()+1]; + (*inFile).open(href.toChar(fchars), ios::in); + delete fchars; + } + inStream = inFile; + } + delete uri; + + return inStream; + +} //-- getInputStream + +/** + * Returns the document base of the href argument + * @return the document base of the given href +**/ +void URIUtils::getDocumentBase(String& href, String& dest) { + + //-- use temp str so the subString method doesn't destroy dest + String docBase(""); + + if (href.length() != 0) { + + int idx = -1; + //-- check for URL + ParsedURI* uri = parseURI(href); + if ( !uri->isMalformed ) { + idx = href.lastIndexOf(HREF_PATH_SEP); + } + else { + //-- The following contains a fix from Shane Hathaway + //-- to handle the case when both "\" and "/" appear in filename + int idx2 = href.lastIndexOf(HREF_PATH_SEP); + //idx = href.lastIndexOf(File.separator); + idx = -1; //-- hack change later + if (idx2 > idx) idx = idx2; + } + if (idx >= 0) href.subString(0,idx, docBase); + delete uri; + } + dest.append(docBase); + +} //-- getDocumentBase + +/** + * Resolves the given href argument, using the given documentBase + * if necessary. + * The new resolved href will be appended to the given dest String +**/ +void URIUtils::resolveHref(String& href, String& documentBase, String& dest) { + + + //-- check for URL + ParsedURI* uri = parseURI(href); + if ( !uri->isMalformed ) { + dest.append(href); + delete uri; + return; + } + + + //-- join document base + href + String xHref; + if (documentBase.length() > 0) { + xHref.append(documentBase); + if (documentBase.charAt(documentBase.length()-1) != HREF_PATH_SEP) + xHref.append(HREF_PATH_SEP); + } + xHref.append(href); + + //-- check new href + ParsedURI* newUri = parseURI(xHref); + if ( !newUri->isMalformed ) { + dest.append(xHref); + } + else { + // Try local files + char* xHrefChars = new char[xHref.length()+1]; + ifstream inFile(xHref.toChar(xHrefChars), ios::in); + if ( inFile ) dest.append(xHref); + else dest.append(href); + inFile.close(); + delete xHrefChars; + } + delete uri; + delete newUri; + +} //-- resolveHref + +istream* URIUtils::openStream(ParsedURI* uri) { + if ( !uri ) return 0; + // check protocol + + istream* inStream = 0; + if ( FILE_PROTOCOL.isEqual(uri->protocol) ) { + char* fchars = new char[uri->path.length()+1]; + ifstream* inFile = new ifstream(uri->path.toChar(fchars), ios::in); + delete fchars; + inStream = inFile; + } + + return inStream; +} //-- openStream + +/* */ + +URIUtils::ParsedURI* URIUtils::parseURI(const String& uri) { + + ParsedURI* uriTokens = new ParsedURI; + uriTokens->isMalformed = MB_FALSE; + + short mode = PROTOCOL_MODE; + + // look for protocol + int totalCount = uri.length(); + int charCount = 0; + char prevCh = '\0'; + int fslash = 0; + String buffer(uri.length()); + while ( charCount < totalCount ) { + char ch = uri.charAt(charCount++); + switch(ch) { + case '.' : + if ( mode == PROTOCOL_MODE ) { + uriTokens->isMalformed = MB_TRUE; + mode = HOST_MODE; + } + buffer.append(ch); + break; + case ':' : + { + switch ( mode ) { + case PROTOCOL_MODE : + uriTokens->protocol = buffer; + buffer.clear(); + mode = HOST_MODE; + break; + case HOST_MODE : + + uriTokens->host = buffer; + buffer.clear(); + mode = PORT_MODE; + break; + default: + break; + } + break; + } + case '/' : + switch ( mode ) { + case HOST_MODE : + if ( buffer.length() != 0 ) { + mode = PATH_MODE; + buffer.append(ch); + } + else if ( fslash == 2 ) mode = PATH_MODE; + else ++fslash; + break; + case PORT_MODE : + mode = PATH_MODE; + uriTokens->port.append(buffer); + buffer.clear(); + break; + default: + buffer.append(ch); + break; + } + break; + default: + buffer.append(ch); + } + prevCh = ch; + } + + if ( mode == PROTOCOL_MODE ) { + uriTokens->isMalformed = MB_TRUE; + } + //-- finish remaining mode + if ( buffer.length() > 0 ) { + switch ( mode ) { + case PROTOCOL_MODE : + uriTokens->protocol.append(buffer); + break; + case HOST_MODE : + uriTokens->host.append(buffer); + break; + case PORT_MODE : + uriTokens->port.append(buffer); + break; + case PATH_MODE : + uriTokens->path.append(buffer); + break; + default: + break; + } + } + return uriTokens; +} //-- parseURI + +/** + * +** +void URIUtils::test(const String& str) { + cout << "parsing: " << str << endl; + ParsedURI* uri = parseURI(str); + cout << "protocol : " << uri->protocol << endl; + cout << "host : " << uri->host << endl; + cout << "port : " << uri->port << endl; + cout << "path : " << uri->path << endl; + cout << "malformed: " << uri->isMalformed << endl; + delete uri; +} //-- test + +/** + * The test class for the URIUtils +** +void main(int argc, char** argv) { + URIUtils::test("file:///c|\\test"); + URIUtils::test("http://my.domain.com"); + URIUtils::test("my.domain.com"); + URIUtils::test("http://my.domain.com:80"); + URIUtils::test("http://my.domain.com:88/foo.html"); + + String url("http://my.domain.com:88/foo.html"); + String docBase; + URIUtils::getDocumentBase(url, docBase); + cout << "url : " << url < +#include + +/** + * A utility class for URI handling + * Not yet finished, only handles file URI at this point + * @author Keith Visco + *
+ *
+ * Modifications:
+ * 19990806: Larry Fitzpatrick
+ *  - moved initialization of contanst shorts and chars to URIUtils.cpp
+ * 
+ * +**/ + +class URIUtils { + + +public: + + static const String HTTP_PROTOCOL; + static const String FILE_PROTOCOL; + + /** + * the path separator for an URI + **/ + static const char HREF_PATH_SEP; + + /** + * The Device separator for an URI + **/ + static const char DEVICE_SEP; + + /** + * The Port separator for an URI + **/ + static const char PORT_SEP; + + /** + * The Protocal separator for an URI + **/ + static const char PROTOCOL_SEP; + + + static istream* URIUtils::getInputStream + (String& href, String& documentBase, String& errMsg); + + /** + * Returns the document base of the href argument + * The document base will be appended to the given dest String + **/ + static void getDocumentBase(String& href, String& dest); + + /** + * Resolves the given href argument, using the given documentBase + * if necessary. + * The new resolved href will be appended to the given dest String + **/ + static void resolveHref(String& href, String& documentBase, String& dest); + + +private: + + static const short PROTOCOL_MODE; + static const short HOST_MODE; + static const short PORT_MODE; + static const short PATH_MODE; + + struct ParsedURI { + MBool isMalformed; + String fragmentIdentifier; + String host; + String protocol; + String port; + String path; + }; + + static istream* openStream(ParsedURI* uri); + static ParsedURI* parseURI(const String& uri); + + + +}; //-- URIUtils diff --git a/mozilla/extensions/transformiix/source/xml/Makefile b/mozilla/extensions/transformiix/source/xml/Makefile new file mode 100644 index 00000000000..36eaa348384 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/Makefile @@ -0,0 +1,20 @@ + +BASE_PATH = ../base +DOM_PATH = dom + +INCLUDE_PATH = -I . -I $(BASE_PATH) -I $(DOM_PATH) -I- + + +ALL_OBJS = XMLDOMUtils.o \ + XMLUtils.o + + +CC = g++ $(INCLUDE_PATH) + +target: $(ALL_OBJS) + +XMLDOMUtils.o: XMLDOMUtils.h XMLDOMUtils.cpp + $(CC) -c XMLDOMUtils.cpp + +XMLUtils.o: XMLUtils.h XMLUtils.cpp + $(CC) -c XMLUtils.cpp diff --git a/mozilla/extensions/transformiix/source/xml/XMLDOMUtils.cpp b/mozilla/extensions/transformiix/source/xml/XMLDOMUtils.cpp new file mode 100644 index 00000000000..90c59f6c205 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/XMLDOMUtils.cpp @@ -0,0 +1,61 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * XMLDOMUtils + * @author Keith Visco +**/ + +#include "XMLDOMUtils.h" + +void XMLDOMUtils::getNodeValue(Node* node, DOMString* target) { + + if (!node) { + return; + } + + int nodeType = node->getNodeType(); + Element* element = 0; + NodeList* nl = 0; + + switch ( nodeType ) { + case Node::ATTRIBUTE_NODE : + target->append( ((Attr*)node)->getValue() ); + break; + case Node::DOCUMENT_NODE : + getNodeValue( ((Document*)node)->getDocumentElement(), target); + break; + case Node::DOCUMENT_FRAGMENT_NODE : + case Node::ELEMENT_NODE : + { + nl = node->getChildNodes(); + for ( int i = 0; i < nl->getLength(); i++) { + getNodeValue(nl->item(i),target); + } + break; + } + case Node::TEXT_NODE : + target->append ( ((Text*)node)->getData() ); + break; + } //-- switch + +} //-- getNodeValue + diff --git a/mozilla/extensions/transformiix/source/xml/XMLDOMUtils.h b/mozilla/extensions/transformiix/source/xml/XMLDOMUtils.h new file mode 100644 index 00000000000..1d0e394d5e7 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/XMLDOMUtils.h @@ -0,0 +1,42 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * A utility class for use with XML DOM implementations + * @author Keith Visco +**/ +#include "dom.h" + +#ifndef MITRE_XMLDOMUTILS_H +#define MITRE_XMLDOMUTILS_H + +class XMLDOMUtils { + + public: + + /** + * Appends the value of the given Node to the target DOMString + **/ + static void XMLDOMUtils::getNodeValue(Node* node, DOMString* target); +}; //-- XMLDOMUtils + +#endif + diff --git a/mozilla/extensions/transformiix/source/xml/XMLUtils.cpp b/mozilla/extensions/transformiix/source/xml/XMLUtils.cpp new file mode 100644 index 00000000000..e31bba90d9e --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/XMLUtils.cpp @@ -0,0 +1,252 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * An XML utility class + * @author Keith Visco +**/ + +#include "XMLUtils.h" + + //------------------------------/ + //- Implementation of XMLUtils -/ +//------------------------------/ + +const String XMLUtils::XMLNS = "xmlns"; + +void XMLUtils::getNameSpace(const String& src, String& dest) { + + //-- anything preceding ':' is the namespace part of the name + int idx = src.indexOf(':'); + if ( idx > 0 ) { + //-- create new String to prevent any chars in dest from being + //-- lost + String tmp; + src.subString(0,idx, tmp); + dest.append(tmp); + } + else dest.append(""); + +} //-- getNameSpace + +void XMLUtils::getLocalPart(const String& src, String& dest) { + + //-- anything after ':' is the local part of the name + int idx = src.indexOf(':'); + if ( idx < -1 ) idx = -1; + //-- create new String to prevent any chars in dest from being + //-- lost + String tmp; + src.subString(idx+1, tmp); + dest.append(tmp); + +} //-- getLocalPart + +/** + * Returns true if the given character represents an Alpha letter +**/ +MBool XMLUtils::isAlphaChar(Int32 ch) { + if ((ch >= 'a' ) && (ch <= 'z' )) return MB_TRUE; + if ((ch >= 'A' ) && (ch <= 'Z' )) return MB_TRUE; + return MB_FALSE; +} //-- isAlphaChar + +/** + * Returns true if the given character represents a numeric letter (digit) +**/ +MBool XMLUtils::isDigit(Int32 ch) { + if ((ch >= '0') && (ch <= '9')) return MB_TRUE; + return MB_FALSE; +} //-- isDigit + +/** + * Returns true if the given character is an allowable QName character +**/ +MBool XMLUtils::isNCNameChar(Int32 ch) { + if (isDigit(ch) || isAlphaChar(ch)) return MB_TRUE; + return (MBool) ((ch == '.') ||(ch == '_') || (ch == '-')); +} //-- isNCNameChar + +/** + * Returns true if the given character is an allowable NCName character +**/ +MBool XMLUtils::isQNameChar(Int32 ch) { + return (MBool) (( ch == ':') || isNCNameChar(ch)); +} //-- isQNameChar + +/** + * Returns true if the given String is a valid XML QName +**/ +MBool XMLUtils::isValidQName(String& name) { + + int size = name.length(); + if ( size == 0 ) return MB_FALSE; + else if ( !isAlphaChar(name.charAt(0))) return MB_FALSE; + else { + for ( int i = 1; i < size; i++) { + if ( ! isQNameChar(name.charAt(i))) return MB_FALSE; + } + } + return MB_TRUE; +} //-- isValidQName + +/** + * Normalizes the value of an XML attribute +**/ +void XMLUtils::normalizeAttributeValue(String& attValue) { + Int32 size = attValue.length(); + //-- make copy of chars + char* chars = new char[size+1]; + attValue.toChar(chars); + //-- clear attValue + attValue.clear(); + + Int32 cc = 0; + MBool addSpace = MB_FALSE; + while ( cc < size) { + char ch = chars[cc++]; + switch (ch) { + case ' ': + if ( attValue.length() > 0) addSpace = MB_TRUE; + break; + case '\r': + break; + case '\n': + attValue.append(" "); + break; + default: + if ( addSpace) { + attValue.append(' '); + addSpace = MB_FALSE; + } + attValue.append(ch); + break; + } + } + delete chars; +} //-- normalizeAttributeValue + +/** + * Normalizes the value of a XML processing instruction +**/ +void XMLUtils::normalizePIValue(String& piValue) { + Int32 size = piValue.length(); + //-- make copy of chars + char* chars = new char[size+1]; + piValue.toChar(chars); + //-- clear attValue + piValue.clear(); + + Int32 cc = 0; + char prevCh = '\0'; + while ( cc < size) { + char ch = chars[cc++]; + switch (ch) { + case '>': + if ( prevCh == '?' ) { + piValue.append(' '); + } + piValue.append(ch); + break; + default: + piValue.append(ch); + break; + } + prevCh = ch; + } + delete chars; +} //-- noramlizePIValue + +/** + * Strips whitespace from the given String. + * Newlines (#xD), tabs (#x9), and consecutive spaces (#x20) are + * converted to a single space (#x20). + * @param data the String to strip whitespace from + * @param dest the destination String to append the result to +**/ +void XMLUtils::stripSpace (const String& data, String& dest) { + stripSpace(data,dest,MB_FALSE,MB_FALSE); +} //-- stripSpace + +/** + * Strips whitespace from the given String. + * Newlines (#xD), tabs (#x9), and consecutive spaces (#x20) are + * converted to a single space (#x20). + * @param data the String to strip whitespace from + * @param dest the destination String to append the result to + * @param stripAllLeadSpace, a boolean indicating whether or not to + * strip all leading space. If true all whitespace from the start of the + * given String will be stripped. If false, all whitespace from the start + * of the given String will be converted to a single space. + * @param stripAllTrailSpace, a boolean indicating whether or not to + * strip all trailing space. If true all whitespace at the end of the + * given String will be stripped. If false, all whitespace at the end + * of the given String will be converted to a single space. +**/ +void XMLUtils::stripSpace + ( const String& data, + String& dest, + MBool stripAllLeadSpace, + MBool stripAllTrailSpace ) +{ + + char lastToken, token; + Int32 oldSize = data.length(); + char* chars = new char[oldSize+1]; + data.toChar(chars); + + lastToken = '\0'; + Int32 total = 0; + + // indicates we have seen at least one + // non whitespace charater + MBool validChar = MB_FALSE; + + for (int i = 0; i < oldSize; i++) { + token = chars[i]; + switch(token) { + case ' ': + case '\t': + case '\n': + case '\r': + token = ' '; + if (stripAllLeadSpace && (!validChar)) break; + if (lastToken != token) chars[total++] = token; + break; + default: + chars[total++] = token; + validChar = MB_TRUE; + break; + } + lastToken = token; + } + + //-- remove last trailing space if necessary + if (stripAllTrailSpace) + if ((total > 0) && (chars[total-1] == ' ')) --total; + + if (validChar) { + chars[total] = '\0'; //-- add Null terminator + dest.append(chars); + } + delete chars; +} //-- stripSpace + diff --git a/mozilla/extensions/transformiix/source/xml/XMLUtils.h b/mozilla/extensions/transformiix/source/xml/XMLUtils.h new file mode 100644 index 00000000000..fa935158ef4 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/XMLUtils.h @@ -0,0 +1,109 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * An XML Utility class + * @author Keith Visco +**/ + +#include "String.h" +#include "baseutils.h" + +#ifndef MITRE_XMLUTILS_H +#define MITRE_XMLUTILS_H + +class XMLUtils { + +public: + + static const String XMLNS; + + static void getNameSpace(const String& src, String& dest); + static void getLocalPart(const String& src, String& dest); + + /** + * Returns true if the given String is a valid XML QName + **/ + static MBool isValidQName(String& name); + + /** + * Normalizes the value of an XML attribute + **/ + static void normalizeAttributeValue(String& attValue); + + /** + * Normalizes the value of a XML processingInstruction + **/ + static void normalizePIValue(String& attValue); + + /** + * Strips whitespace from the given String. + * Newlines (#xD), tabs (#x9), and consecutive spaces (#x20) are + * converted to a single space (#x20). + * @param data the String to strip whitespace from + * @param dest the destination String to append the result to + **/ + static void stripSpace (const String& data, String& dest); + + /** + * Strips whitespace from the given String. + * Newlines (#xD), tabs (#x9), and consecutive spaces (#x20) are + * converted to a single space (#x20). + * @param data the String to strip whitespace from + * @param dest the destination String to append the result to + * @param stripAllLeadSpace, a boolean indicating whether or not to + * strip all leading space. If true all whitespace from the start of the + * given String will be stripped. If false, all whitespace from the start + * of the given String will be converted to a single space. + * @param stripAllTrailSpace, a boolean indicating whether or not to + * strip all trailing space. If true all whitespace at the end of the + * given String will be stripped. If false, all whitespace at the end + * of the given String will be converted to a single space. + **/ + static void stripSpace (const String& data, + String& dest, + MBool stripAllLeadSpace, + MBool stripAllTrailSpace); + +private: + + /** + * Returns true if the given character represents an Alpha letter + **/ + static MBool isAlphaChar(Int32 ch); + + /** + * Returns true if the given character represents a numeric letter (digit) + **/ + static MBool isDigit(Int32 ch); + + /** + * Returns true if the given character is an allowable QName character + **/ + static MBool isQNameChar(Int32 ch); + + /** + * Returns true if the given character is an allowable NCName character + **/ + static MBool isNCNameChar(Int32 ch); + +}; //-- XMLUtils +#endif diff --git a/mozilla/extensions/transformiix/source/xml/dom/Attr.cpp b/mozilla/extensions/transformiix/source/xml/dom/Attr.cpp new file mode 100644 index 00000000000..04a4004b76e --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/Attr.cpp @@ -0,0 +1,143 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the Attr class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// LF 08/06/1999 fixed typo: defalut to default + +// + +#include "dom.h" + +// +//Construct an Attribute object using the specified name and document owner +// +Attr::Attr(const DOMString& name, Document* owner): + NodeDefinition(Node::ATTRIBUTE_NODE, name, NULL_STRING, owner) +{ + specified = MB_FALSE; +} + +// +//Retrieve the name of the attribute from the nodeName data member +// +const DOMString& Attr::getName() const +{ + return nodeName; +} + +// +//Retrieve the specified flag +// +MBool Attr::getSpecified() const +{ + return specified; +} + +// +//Retrieve the value of the attribute. This is a comma-deliminated string +//representation of the Attribute's children. +// +const DOMString& Attr::getValue() +{ + Int32 valueLoop; + nodeValue = NULL_STRING; + NodeList* childList = getChildNodes(); + Int32 numChildren = childList->getLength(); + + for (valueLoop=0;valueLoopitem(valueLoop)->getNodeType() != Node::ENTITY_REFERENCE_NODE) + { + nodeValue.append(childList->item(valueLoop)->getNodeValue()); + if (valueLoop < (numChildren-1)) + nodeValue.append(","); + } + } + + return nodeValue; +} + +// +//Create a new Text node and add it to the Attribute's list of children. Also +//set the Specified flag to true. +// +void Attr::setValue(const DOMString& newValue) +{ + NodeDefinition::DeleteChildren(); + + appendChild(getOwnerDocument()->createTextNode(newValue)); + + specified = MB_TRUE; +} + + +// +//Override the set node value member function to create a new TEXT node with +//the DOMString and to add it as the Attribute's child. +// NOTE: Not currently impemented, just execute the default setNodeValue +// +void Attr::setNodeValue(const DOMString& nodeValue) +{ + setValue(nodeValue); +} + +// +//Return a DOMString represening the value of this node. If the value is an +//Entity Reference then return the value of the reference. Otherwise, it is a +//simple conversion of the text value. +// NOTE: Not currently implemented, just execute the default getNodeValue +// +const DOMString& Attr::getNodeValue() +{ + return getValue(); +} + + +// +//First check to see if the new node is an allowable child for an Attr. If it +//is, call NodeDefinition's implementation of Insert Before. If not, return +//null as an error. +// +Node* Attr::insertBefore(Node* newChild, Node* refChild) +{ + Node* returnVal = NULL; + + switch (newChild->getNodeType()) + { + case Node::TEXT_NODE : + case Node::ENTITY_REFERENCE_NODE: + returnVal = NodeDefinition::insertBefore(newChild, refChild); + + if (returnVal) + specified = MB_TRUE; + break; + default: + returnVal = NULL; + } + + return returnVal; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/CDATASection.cpp b/mozilla/extensions/transformiix/source/xml/dom/CDATASection.cpp new file mode 100644 index 00000000000..328bba1ca63 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/CDATASection.cpp @@ -0,0 +1,64 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the CDATASection class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// + +#include "dom.h" + +// +//Construct a text object with the specified document owner and data +// +CDATASection::CDATASection(const DOMString& theData, Document* owner) : + Text(Node::CDATA_SECTION_NODE, "#cdata-section", theData, owner) +{ +} + +// +//CDATASection nodes can not have any children, so just return null from all child +//manipulation functions. +// + +Node* CDATASection::insertBefore(Node* newChild, Node* refChild) +{ + return NULL; +} + +Node* CDATASection::replaceChild(Node* newChild, Node* oldChild) +{ + return NULL; +} + +Node* CDATASection::removeChild(Node* oldChild) +{ + return NULL; +} + +Node* CDATASection::appendChild(Node* newChild) +{ + return NULL; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/CharacterData.cpp b/mozilla/extensions/transformiix/source/xml/dom/CharacterData.cpp new file mode 100644 index 00000000000..dbdc75c4371 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/CharacterData.cpp @@ -0,0 +1,113 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the CharacterData class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// + +#include "dom.h" + +// +//Protected constructor. Just pass parameters onto NodeDefinition. +// +CharacterData::CharacterData(NodeType type, const DOMString& name, + const DOMString& value, Document* owner) : + NodeDefinition(type, name, value, owner) +{ +} + +// +//Return a constant reference to the data stored by this object. +// +const DOMString& CharacterData::getData() const +{ + return nodeValue; +} + +// +//Set the data stored by this object to the string represented by "source". +// +void CharacterData::setData(const DOMString& source) +{ + nodeValue = source; +} + +// +//Returns the length of the data object. +// +Int32 CharacterData::getLength() const +{ + return nodeValue.length(); +} + +// +//Retreive the substring starting at offset anc ending count number of +//characters away. +// NOTE: An empty string will be returned in the event of an error. +// +DOMString& CharacterData::substringData(Int32 offset, Int32 count, DOMString& dest) +{ + if ((offset >= 0) && (offset < nodeValue.length()) && (count > 0)) + return nodeValue.subString(offset, offset+count, dest); + else + { + dest.clear(); + return dest; + } +} + +void CharacterData::appendData(const DOMString& arg) +{ + nodeValue.append(arg); +} + +void CharacterData::insertData(Int32 offset, const DOMString& arg) +{ + if ((offset >= 0) && (offset < nodeValue.length())) + nodeValue.insert(offset, arg); +} + +void CharacterData::deleteData(Int32 offset, Int32 count) +{ + if ((offset >= 0) && (offset < nodeValue.length()) && (count > 0)) + nodeValue.deleteChars(offset, count); +} + +void CharacterData::replaceData(Int32 offset, Int32 count, const DOMString& arg) +{ + DOMString tempString; + + if ((offset >= 0) && (offset < nodeValue.length()) && (count > 0)) + { + if (count < arg.length()) + { + tempString = arg.subString(0, count, tempString); + nodeValue.replace(offset, tempString); + } + else + nodeValue.replace(offset, arg); + } +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/Comment.cpp b/mozilla/extensions/transformiix/source/xml/dom/Comment.cpp new file mode 100644 index 00000000000..97db4507946 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/Comment.cpp @@ -0,0 +1,64 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the Comment class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// + +#include "dom.h" + +// +//Construct a text object with the specified document owner and data +// +Comment::Comment(const DOMString& theData, Document* owner) : + CharacterData(Node::COMMENT_NODE, "#comment", theData, owner) +{ +} + +// +//Comment nodes can not have any children, so just return null from all child +//manipulation functions. +// + +Node* Comment::insertBefore(Node* newChild, Node* refChild) +{ + return NULL; +} + +Node* Comment::replaceChild(Node* newChild, Node* oldChild) +{ + return NULL; +} + +Node* Comment::removeChild(Node* oldChild) +{ + return NULL; +} + +Node* Comment::appendChild(Node* newChild) +{ + return NULL; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/DOM.H b/mozilla/extensions/transformiix/source/xml/dom/DOM.H new file mode 100644 index 00000000000..72300d888dd --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/DOM.H @@ -0,0 +1,563 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// LF 08/06/1999 Changed static const short NodeType to enum +// Added "friend NamedNodeMap"; to NodeListDefinition +// + +#ifndef MITRE_DOM +#define MITRE_DOM + +#include "String.h" +#include "baseutils.h" +#ifndef NULL +typedef 0 NULL; +#endif + + +typedef String DOMString; +typedef UNICODE_CHAR DOM_CHAR; + +class NodeList; +class NamedNodeMap; +class Document; +class Element; +class Attr; +class Text; +class Comment; +class CDATASection; +class ProcessingInstruction; +class EntityReference; +class DocumentType; + +// +//Definition and Implementation the DOMImplementation class +// +class DOMImplementation +{ + public: + DOMImplementation(); + ~DOMImplementation(); + + MBool hasFeature(DOMString feature, const DOMString& version) const; + + private: + DOMString implFeature; + DOMString implVersion; +}; + +// +// Abstract Class defining the interface for a Node. See NodeDefinition below +// for the actual implementation of the WC3 node. +// +class Node +{ + public: + //Node type constants + //-- LF - changed to enum + enum NodeType { + ELEMENT_NODE = 1, + ATTRIBUTE_NODE, + TEXT_NODE, + CDATA_SECTION_NODE, + ENTITY_REFERENCE_NODE, + ENTITY_NODE, + PROCESSING_INSTRUCTION_NODE, + COMMENT_NODE, + DOCUMENT_NODE, + DOCUMENT_TYPE_NODE, + DOCUMENT_FRAGMENT_NODE, + NOTATION_NODE + }; + + virtual ~Node() {} + + //Read functions + virtual const DOMString& getNodeName() const = 0; + virtual const DOMString& getNodeValue() const = 0; + virtual const DOMString& getNodeValue() = 0; + virtual unsigned short getNodeType() const = 0; + virtual Node* getParentNode() const = 0; + virtual NodeList* getChildNodes() = 0; + virtual Node* getFirstChild() const = 0; + virtual Node* getLastChild() const = 0; + virtual Node* getPreviousSibling() const = 0; + virtual Node* getNextSibling() const = 0; + virtual NamedNodeMap* getAttributes() = 0; + virtual Document* getOwnerDocument() const = 0; + + //Write functions + virtual void setNodeValue(const DOMString& nodeValue) = 0; + + //Node manipulation functions + virtual Node* insertBefore(Node* newChild, Node* refChild) = 0; + virtual Node* replaceChild(Node* newChild, Node* oldChild) = 0; + virtual Node* removeChild(Node* oldChild) = 0; + virtual Node* appendChild(Node* newChild) = 0; + virtual Node* cloneNode(MBool deep, Node* dest) = 0; + + virtual MBool hasChildNodes() const = 0; +}; + +// +// Abstract class containing the Interface for a NodeList. See NodeDefinition +// below for the actual implementation of a WC3 NodeList as it applies to the +// getChildNodes Node function. Also see NodeListDefinition for the +// implementation of a NodeList as it applies to such functions as +// getElementByTagName. +// +class NodeList +{ + public: + virtual Node* item(Int32 index) = 0; + virtual Int32 getLength() = 0; + protected: + Int32 length; +}; + +// +//Definition of the implementation of a NodeList. This class maintains a +//linked list of pointers to Nodes. "Friends" of the class can add and remove +//pointers to Nodes as needed. +// *** NOTE: Is there any need for someone to "remove" a node from the +// list? +// +class NodeListDefinition : public NodeList +{ + friend NamedNodeMap; //-- LF + public: + NodeListDefinition(); + ~NodeListDefinition(); + + void append(Node& newNode); + void append(Node* newNode); + + //Inherited from NodeList + Node* item(Int32 index); + Int32 getLength(); + + protected: + struct ListItem { + ListItem* next; + ListItem* prev; + Node* node; + }; + + ListItem* firstItem; + ListItem* lastItem; +}; + +// +//Definition of a NamedNodeMap. For the time being it builds off the +//NodeListDefinition class. This will probably change when NamedNodeMap needs +//to move to a more efficient search algorithm for attributes. +// +class NamedNodeMap : public NodeListDefinition +{ + public: + NamedNodeMap(); + ~NamedNodeMap(); + + Node* getNamedItem(const DOMString& name); + Node* setNamedItem(Node* arg); + Node* removeNamedItem(const DOMString& name); + + private: + NodeListDefinition::ListItem* findListItemByName(const DOMString& name); +}; + +// +// Definition and Implementation of Node and NodeList functionality. This is +// the central class, from which all other DOM classes (objects) are derrived. +// Users of this DOM should work strictly with the Node interface and NodeList +// interface (see above for those definitions) +// +class NodeDefinition : public Node, public NodeList +{ + public: + NodeDefinition(NodeType type, const DOMString& name, + const DOMString& value, Document* owner); + virtual ~NodeDefinition(); //Destructor, delete all children of node + + //Read functions + const DOMString& getNodeName() const; + virtual const DOMString& getNodeValue() const; + virtual const DOMString& getNodeValue(); + unsigned short getNodeType() const; + Node* getParentNode() const; + NodeList* getChildNodes(); + Node* getFirstChild() const; + Node* getLastChild() const; + Node* getPreviousSibling() const; + Node* getNextSibling() const; + NamedNodeMap* getAttributes(); + Document* getOwnerDocument() const; + + //Write functions + virtual void setNodeValue(const DOMString& nodeValue); + + //Child node manipulation functions + virtual Node* insertBefore(Node* newChild, Node* refChild); + virtual Node* replaceChild(Node* newChild, Node* oldChild); + virtual Node* removeChild(Node* oldChild); + virtual Node* appendChild(Node* newChild); + Node* cloneNode(MBool deep, Node* dest); + + MBool hasChildNodes() const; + + //Inherrited from NodeList + Node* item(Int32 index); + Int32 getLength(); + + protected: + //Name, value, and attributes for this node. Available to derrived + //classes, since those derrived classes have a better idea how to use them, + //than the generic node does. + DOMString nodeName; + DOMString nodeValue; + NamedNodeMap attributes; + + void DeleteChildren(); + + Node* implInsertBefore(NodeDefinition* newChild, NodeDefinition* refChild); + private: + //Type of node this is + NodeType nodeType; + + //Data members for linking this Node to its parent and siblings + NodeDefinition* parentNode; + NodeDefinition* previousSibling; + NodeDefinition* nextSibling; + + //Pointer to the node's document + Document* ownerDocument; + + //Data members for maintaining a list of child nodes + NodeDefinition* firstChild; + NodeDefinition* lastChild; + +}; + +// +//Definition and Implementation of a Document Fragment. All functionality is +//inherrited directly from NodeDefinition. We just need to make sure the Type +//of the node set to Node::DOCUMENT_FRAGMENT_NODE. +// +class DocumentFragment : public NodeDefinition +{ + public: + DocumentFragment(const DOMString& name, const DOMString& value, Document* owner); + + //Override insertBefore to limit Elements to having only certain nodes as + //children + Node* insertBefore(Node* newChild, Node* refChild); +}; + +// +//Definition and Implementation of a Document. +// +class Document : public NodeDefinition +{ + public: + Document(DocumentType* theDoctype = NULL); + + Element* getDocumentElement(); + DocumentType* getDoctype(); + const DOMImplementation& getImplementation(); + + //Factory functions for various node types + DocumentFragment* createDocumentFragment(); + Element* createElement(const DOMString& tagName); + Attr* createAttribute(const DOMString& name); + Text* createTextNode(const DOMString& theData); + Comment* createComment(const DOMString& theData); + CDATASection* createCDATASection(const DOMString& theData); + ProcessingInstruction* createProcessingInstruction(const DOMString& target, + const DOMString& data); + EntityReference* createEntityReference(const DOMString& name); + + //Override functions to enforce the One Element rule for documents, as well + //as limit documents to certain types of nodes. + Node* insertBefore(Node* newChild, Node* refChild); + Node* replaceChild(Node* newChild, Node* oldChild); + Node* removeChild(Node* oldChild); + + private: + Element* documentElement; + DocumentType* doctype; + DOMImplementation implementation; +}; + +// +//Definition and Implementation of an Element +// +class Element : public NodeDefinition +{ + public: + Element(const DOMString& tagName, Document* owner); + + //Override insertBefore to limit Elements to having only certain nodes as + //children + Node* insertBefore(Node* newChild, Node* refChild); + + const DOMString& getTagName(); + const DOMString& getAttribute(const DOMString& name); + void setAttribute(const DOMString& name, const DOMString& value); + void removeAttribute(const DOMString& name); + Attr* getAttributeNode(const DOMString& name); + Attr* setAttributeNode(Attr* newAttr); + Attr* removeAttributeNode(Attr* oldAttr); + NodeList* getElementsByTagName(const DOMString& name); + void normalize(); +}; + +// +//Definition and Implementation of a Attr +// NOTE: For the time bing use just the default functionality found in the +// NodeDefinition class +// +class Attr : public NodeDefinition +{ + public: + Attr(const DOMString& name, Document* owner); + + const DOMString& getName() const; + MBool getSpecified() const; + const DOMString& getValue(); + void setValue(const DOMString& newValue); + + //Override the set and get member functions for a node's value to create a + //new TEXT node when set, and to interpret its children when read. + void setNodeValue(const DOMString& nodeValue); + const DOMString& getNodeValue(); + + //Override insertBefore to limit Attr to having only certain nodes as + //children + Node* insertBefore(Node* newChild, Node* refChild); + + private: + MBool specified; +}; + +// +//Definition and Implementation of CharacterData. This class mearly provides +//the interface and some default implementation. It is not intended to be +//instantiated by users of the DOM +// +class CharacterData : public NodeDefinition +{ + public: + const DOMString& getData() const; + void setData(const DOMString& source); + Int32 getLength() const; + + DOMString& substringData(Int32 offset, Int32 count, DOMString& dest); + void appendData(const DOMString& arg); + void insertData(Int32 offset, const DOMString& arg); + void deleteData(Int32 offset, Int32 count); + void replaceData(Int32 offset, Int32 count, const DOMString& arg); + + protected: + CharacterData(NodeType type, const DOMString& name, + const DOMString& value, Document* owner); +}; + +// +//Definition and Implementation of a Text node. The bulk of the functionality +//comes from CharacterData and NodeDefinition. +// +class Text : public CharacterData +{ + public: + Text(const DOMString& theData, Document* owner); + + Text* splitText(Int32 offset); + + //Override "child manipulation" function since Text Nodes can not have + //any children. + Node* insertBefore(Node* newChild, Node* refChild); + Node* replaceChild(Node* newChild, Node* oldChild); + Node* removeChild(Node* oldChild); + Node* appendChild(Node* newChild); + + protected: + Text(NodeType type, const DOMString& name, const DOMString& value, + Document* owner); +}; + +// +//Definition and Implementation of a Comment node. All of the functionality is +//inherrited from CharacterData and NodeDefinition. +// +class Comment : public CharacterData +{ + public: + Comment(const DOMString& theData, Document* owner); + + //Override "child manipulation" function since Comment Nodes can not have + //any children. + Node* insertBefore(Node* newChild, Node* refChild); + Node* replaceChild(Node* newChild, Node* oldChild); + Node* removeChild(Node* oldChild); + Node* appendChild(Node* newChild); +}; + +// +//Definition and Implementation of a CDATASection node. All of the +//functionality is inherrited from Text, CharacterData, and NodeDefinition +// +class CDATASection : public Text +{ + public: + CDATASection(const DOMString& theData, Document* owner); + + //Override "child manipulation" function since CDATASection Nodes can not + //have any children. + Node* insertBefore(Node* newChild, Node* refChild); + Node* replaceChild(Node* newChild, Node* oldChild); + Node* removeChild(Node* oldChild); + Node* appendChild(Node* newChild); +}; + +// +//Definition and Implemention of a ProcessingInstruction node. Most +//functionality is inherrited from NodeDefinition. +// The Target of a processing instruction is stored in the nodeName datamember +// inherrited from NodeDefinition. +// The Data of a processing instruction is stored in the nodeValue datamember +// inherrited from NodeDefinition +// +class ProcessingInstruction : public NodeDefinition +{ + public: + ProcessingInstruction(const DOMString& theTarget, const DOMString& theData, + Document* owner); + + const DOMString& getTarget() const; + const DOMString& getData() const; + + void setData(const DOMString& theData); + + //Override "child manipulation" function since ProcessingInstruction Nodes + //can not have any children. + Node* insertBefore(Node* newChild, Node* refChild); + Node* replaceChild(Node* newChild, Node* oldChild); + Node* removeChild(Node* oldChild); + Node* appendChild(Node* newChild); +}; + +// +//Definition and Implementation of a Notation. Most functionality is inherrited +//from NodeDefinition. +// +class Notation : public NodeDefinition +{ + public: + Notation(const DOMString& name, const DOMString& pubID, + const DOMString& sysID); + + const DOMString& getPublicId() const; + const DOMString& getSystemId() const; + + //Override "child manipulation" function since Notation Nodes + //can not have any children. + Node* insertBefore(Node* newChild, Node* refChild); + Node* replaceChild(Node* newChild, Node* oldChild); + Node* removeChild(Node* oldChild); + Node* appendChild(Node* newChild); + + private: + DOMString publicId; + DOMString systemId; +}; + +// +//Definition and Implementation of an Entity +// +class Entity : public NodeDefinition +{ + public: + Entity(const DOMString& name, const DOMString& pubID, + const DOMString& sysID, const DOMString& notName); + + const DOMString& getPublicId() const; + const DOMString& getSystemId() const; + const DOMString& getNotationName() const; + + //Override insertBefore to limit Entity to having only certain nodes as + //children + Node* insertBefore(Node* newChild, Node* refChild); + + private: + DOMString publicId; + DOMString systemId; + DOMString notationName; +}; + +// +//Definition and Implementation of an EntityReference +// +class EntityReference : public NodeDefinition +{ + public: + EntityReference(const DOMString& name, Document* owner); + + //Override insertBefore to limit EntityReference to having only certain + //nodes as children + Node* insertBefore(Node* newChild, Node* refChild); +}; + +// +//Definition and Implementation of the DocumentType +// +class DocumentType : public NodeDefinition +{ + public: + DocumentType(const DOMString& name, NamedNodeMap* theEntities, + NamedNodeMap* theNotations); + ~DocumentType(); + + NamedNodeMap* getEntities(); + NamedNodeMap* getNotations(); + + //Override "child manipulation" function since Notation Nodes + //can not have any children. + Node* insertBefore(Node* newChild, Node* refChild); + Node* replaceChild(Node* newChild, Node* oldChild); + Node* removeChild(Node* oldChild); + Node* appendChild(Node* newChild); + + private: + NamedNodeMap* entities; + NamedNodeMap* notations; +}; + +//NULL string for use by Element::getAttribute() for when the attribute +//spcified by "name" does not exist, and therefore shoud be "NULL". +const DOMString NULL_STRING; + +#endif diff --git a/mozilla/extensions/transformiix/source/xml/dom/DOMImplementation.cpp b/mozilla/extensions/transformiix/source/xml/dom/DOMImplementation.cpp new file mode 100644 index 00000000000..91d4974c9dd --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/DOMImplementation.cpp @@ -0,0 +1,56 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the DOMImplementation class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// + +#include "dom.h" + +DOMImplementation::DOMImplementation() +{ + implFeature = "XML"; + implVersion = "1.0"; +} + +DOMImplementation::~DOMImplementation() +{ +} + +// +//Perform a case insensitive comparison between "feature" and the +//functionality of this DOM implementation/version. +// +MBool DOMImplementation::hasFeature(DOMString feature, + const DOMString& version) const +{ + feature.toUpperCase(); + + if (feature.isEqual(implFeature) && version.isEqual(implVersion)) + return MB_TRUE; + else + return MB_FALSE; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/Document.cpp b/mozilla/extensions/transformiix/source/xml/dom/Document.cpp new file mode 100644 index 00000000000..be9b55500de --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/Document.cpp @@ -0,0 +1,258 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the Document class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// LF 08/06/1999 Removed Default argument initializer from +// Document() constructor +// LF 08/06/1999 fixed typo: defalut to default +// + +#include "dom.h" + +// +//Construct a Document. Currently no parameters are required, but the the +//node constructor is called to identify the node type. +// +Document::Document(DocumentType* theDoctype) : + NodeDefinition(Node::DOCUMENT_NODE, "#document", NULL_STRING, NULL) +{ + documentElement = NULL; + doctype = theDoctype; +} + +// +//Return the one and only element for this document +// +Element* Document::getDocumentElement() +{ + return documentElement; +} + +// +//Return the document type of this document object +// +DocumentType* Document::getDoctype() +{ + return doctype; +} + +// +//Return a constant reference to the DOM's Implementation +// +const DOMImplementation& Document::getImplementation() +{ + return implementation; +} + +// +//Ensure that no Element node is inserted if the document already has an +//associated Element child. +// +Node* Document::insertBefore(Node* newChild, Node* refChild) +{ + Node* returnVal = NULL; + + NodeDefinition* pCurrentNode = NULL; + NodeDefinition* pNextNode = NULL; + + //Convert to a NodeDefinition Pointer + NodeDefinition* pNewChild = (NodeDefinition*)newChild; + NodeDefinition* pRefChild = (NodeDefinition*)refChild; + + //Check to see if the reference node is a child of this node + if ((refChild != NULL) && (pRefChild->getParentNode() != this)) + return NULL; + + switch (pNewChild->getNodeType()) + { + case Node::DOCUMENT_FRAGMENT_NODE : + pCurrentNode = (NodeDefinition*)pNewChild->getFirstChild(); + while (pCurrentNode) + { + pNextNode = (NodeDefinition*)pCurrentNode->getNextSibling(); + + //Make sure that if the current node is an Element, the document + //doesn't already have one. + if ((pCurrentNode->getNodeType() != Node::ELEMENT_NODE) || + ((pCurrentNode->getNodeType() == Node::ELEMENT_NODE) && + (documentElement == NULL))) + { + pCurrentNode = (NodeDefinition*)pNewChild->removeChild(pCurrentNode); + implInsertBefore(pCurrentNode, pRefChild); + + if (pCurrentNode->getNodeType() == Node::ELEMENT_NODE) + documentElement = (Element*)pCurrentNode; + } + pCurrentNode = pNextNode; + } + returnVal = newChild; + break; + + case Node::PROCESSING_INSTRUCTION_NODE : + case Node::COMMENT_NODE : + case Node::DOCUMENT_TYPE_NODE : + returnVal = implInsertBefore(pNewChild, pRefChild); + break; + + case Node::ELEMENT_NODE : + if (!documentElement) + { + documentElement = (Element*)pNewChild; + returnVal = implInsertBefore(pNewChild, pRefChild); + } + else + returnVal = NULL; + break; + default: + returnVal = NULL; + } + + return returnVal; +} + +// +//Ensure that if the newChild is an Element and the Document already has an +//element, then oldChild should be specifying the existing element. If not +//then the replacement can not take place. +// +Node* Document::replaceChild(Node* newChild, Node* oldChild) +{ + Node* replacedChild = NULL; + + if (newChild->getNodeType() != Node::ELEMENT_NODE) + { + //The new child is not an Element, so perform replacement + replacedChild = NodeDefinition::replaceChild(newChild, oldChild); + + //If old node was an Element, then the document's element has been + //replaced with a non-element node. Therefore clear the documentElement + //pointer + if (replacedChild && (oldChild->getNodeType() == Node::ELEMENT_NODE)) + documentElement = NULL; + + return replacedChild; + } + else + { + //A node is being replaced with an Element. If the document does not + //have an elemet yet, then just allow the replacemetn to take place. + if (!documentElement) + replacedChild = NodeDefinition::replaceChild(newChild, oldChild); + else if (oldChild->getNodeType() == Node::ELEMENT_NODE) + replacedChild = NodeDefinition::replaceChild(newChild, oldChild); + + if (replacedChild) + documentElement = (Element*)newChild; + + return replacedChild; + } +} + +// +//Update the documentElement pointer if the associated Element node is being +//removed. +// +Node* Document::removeChild(Node* oldChild) +{ + Node* removedChild = NULL; + + removedChild = NodeDefinition::removeChild(oldChild); + + if (removedChild && (removedChild->getNodeType() == Node::ELEMENT_NODE)) + documentElement = NULL; + + return removedChild; +} + +// +//Construct an empty document fragment. +// NOTE: The caller is responsible for cleaning up this fragment's memory +// when it is no longer needed. +// +DocumentFragment* Document::createDocumentFragment() +{ + return new DocumentFragment("#document-fragment", NULL_STRING, this); +} + +// +//Construct an element with the specified tag name. +// NOTE: The caller is responsible for cleaning up the element's menory +// +Element* Document::createElement(const DOMString& tagName) +{ + return new Element(tagName, this); +} + +// +//Construct an attribute with the specified name +// +Attr* Document::createAttribute(const DOMString& name) +{ + return new Attr(name, this); +} + +// +//Construct a text node with the given data +// +Text* Document::createTextNode(const DOMString& theData) +{ + return new Text(theData, this); +} + +// +//Construct a comment node with the given data +// +Comment* Document::createComment(const DOMString& theData) +{ + return new Comment(theData, this); +} + +// +//Construct a CDATASection node with the given data +// +CDATASection* Document::createCDATASection(const DOMString& theData) +{ + return new CDATASection(theData, this); +} + +// +//Construct a ProcessingInstruction node with the given targe and data. +// +ProcessingInstruction* + Document::createProcessingInstruction(const DOMString& target, + const DOMString& data) +{ + return new ProcessingInstruction(target, data, this); +} + +// +//Construct an EntityReference with the given name +// +EntityReference* Document::createEntityReference(const DOMString& name) +{ + return new EntityReference(name, this); +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/DocumentFragment.cpp b/mozilla/extensions/transformiix/source/xml/dom/DocumentFragment.cpp new file mode 100644 index 00000000000..084fe26b543 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/DocumentFragment.cpp @@ -0,0 +1,68 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the DocumentFragment class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// LF 08/06/1999 fixed typo: defalut to default +// + +#include "dom.h" + +// +//Construct a DocumentFragment with the specified name and value. Call the +//constructor for NodeDefinition and specify the DocumentFragment Type. +// +DocumentFragment::DocumentFragment(const DOMString& name, + const DOMString& value, Document* owner) : + NodeDefinition(Node::DOCUMENT_FRAGMENT_NODE, name, value, owner) +{ +} + +// +//First check to see if the new node is an allowable child for a +//DocumentFragment. If it is, call NodeDefinition's implementation of Insert +//Before. If not, return null as an error. +// +Node* DocumentFragment::insertBefore(Node* newChild, Node* refChild) +{ + Node* returnVal = NULL; + + switch (newChild->getNodeType()) + { + case Node::ELEMENT_NODE : + case Node::PROCESSING_INSTRUCTION_NODE : + case Node::COMMENT_NODE : + case Node::TEXT_NODE : + case Node::CDATA_SECTION_NODE : + case Node::ENTITY_REFERENCE_NODE: + returnVal = NodeDefinition::insertBefore(newChild, refChild); + break; + default: + returnVal = NULL; + } + + return returnVal; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/DocumentType.cpp b/mozilla/extensions/transformiix/source/xml/dom/DocumentType.cpp new file mode 100644 index 00000000000..3c86aa204c2 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/DocumentType.cpp @@ -0,0 +1,96 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the DocumentType class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// + +#include "dom.h" + +// +//Construct a text object with the specified document owner and data +// +DocumentType::DocumentType(const DOMString& name, NamedNodeMap* theEntities, + NamedNodeMap* theNotations) : + NodeDefinition(Node::DOCUMENT_TYPE_NODE, name, NULL_STRING, NULL) +{ + entities = theEntities; + notations = theNotations; +} + +// +//When destroying the DocumentType, the entities and notations must be +//destroyed too. +// +DocumentType::~DocumentType() +{ + if (entities) + delete entities; + + if (notations) + delete notations; +} + +// +//Return a pointer to the entities contained in this Document Type +// +NamedNodeMap* DocumentType::getEntities() +{ + return entities; +} + +// +//Return a pointer to the notations contained in this Document Type +// +NamedNodeMap* DocumentType::getNotations() +{ + return notations; +} + +// +//Comment nodes can not have any children, so just return null from all child +//manipulation functions. +// + +Node* DocumentType::insertBefore(Node* newChild, Node* refChild) +{ + return NULL; +} + +Node* DocumentType::replaceChild(Node* newChild, Node* oldChild) +{ + return NULL; +} + +Node* DocumentType::removeChild(Node* oldChild) +{ + return NULL; +} + +Node* DocumentType::appendChild(Node* newChild) +{ + return NULL; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/Element.cpp b/mozilla/extensions/transformiix/source/xml/dom/Element.cpp new file mode 100644 index 00000000000..29f0da2c4af --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/Element.cpp @@ -0,0 +1,161 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the Element class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// LF 08/06/1999 fixed typo: defalut to default +// + +#include "dom.h" + +// +//Construct a new element with the specified tagName and Document owner. +//Simply call the constructor for NodeDefinition, and specify the proper node +//type. +// +Element::Element(const DOMString& tagName, Document* owner) : + NodeDefinition(Node::ELEMENT_NODE, tagName, NULL_STRING, owner) +{ +} + +// +//First check to see if the new node is an allowable child for an Element. If +//it is, call NodeDefinition's implementation of Insert Before. If not, return +//null as an error +// +Node* Element::insertBefore(Node* newChild, Node* refChild) +{ + Node* returnVal = NULL; + + switch (newChild->getNodeType()) + { + case Node::ELEMENT_NODE : + case Node::TEXT_NODE : + case Node::COMMENT_NODE : + case Node::PROCESSING_INSTRUCTION_NODE : + case Node::CDATA_SECTION_NODE : + case Node::ENTITY_REFERENCE_NODE: + returnVal = NodeDefinition::insertBefore(newChild, refChild); + break; + default: + returnVal = NULL; + } + + return returnVal; +} + +// +//Return the tagName for this element. This is simply the nodeName. +// +const DOMString& Element::getTagName() +{ + return nodeName; +} + +// +//Retreive an attribute's value by name. If the attribute does not exist, +//return a reference to the pre-created, constatnt "NULL STRING". +// +const DOMString& Element::getAttribute(const DOMString& name) +{ + Node* tempNode = attributes.getNamedItem(name); + + if (tempNode) + return attributes.getNamedItem(name)->getNodeValue(); + else + return NULL_STRING; +} + + +// +//Add an attribute to this Element. Create a new Attr object using the +//name and value specified. Then add the Attr to the the Element's +//attributes NamedNodeMap. +// +void Element::setAttribute(const DOMString& name, const DOMString& value) +{ + Attr* tempAttribute; + + //Check to see if an attribute with this name already exists. If it does + //over write its value, if not, add it. + tempAttribute = getAttributeNode(name); + if (tempAttribute) + tempAttribute->setNodeValue(value); + else + { + tempAttribute = getOwnerDocument()->createAttribute(name); + tempAttribute->setNodeValue(value); + attributes.setNamedItem(tempAttribute); + } +} + +// +//Remove an attribute from the attributes NamedNodeMap, and free its memory. +// NOTE: How do default values enter into this picture +// +void Element::removeAttribute(const DOMString& name) +{ + delete attributes.removeNamedItem(name); +} + +// +//Return the attribute specified by name +// +Attr* Element::getAttributeNode(const DOMString& name) +{ + return (Attr*)attributes.getNamedItem(name); +} + +// +//Set a new attribute specifed by the newAttr node. If an attribute with that +//name already exists, the existing Attr is removed from the list and return to +//the caller, else NULL is returned. +// +Attr* Element::setAttributeNode(Attr* newAttr) +{ + Attr* pOldAttr = (Attr*)attributes.removeNamedItem(newAttr->getNodeName()); + + attributes.setNamedItem(newAttr); + return pOldAttr; +} + +// +//Remove the Attribute from the attributes list and return to the caller. If +//the node is not found, return NULL. +// +Attr* Element::removeAttributeNode(Attr* oldAttr) +{ + return (Attr*)attributes.removeNamedItem(oldAttr->getNodeName()); +} + +NodeList* Element::getElementsByTagName(const DOMString& name) +{ + return 0; +} + +void Element::normalize() +{ +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/Entity.cpp b/mozilla/extensions/transformiix/source/xml/dom/Entity.cpp new file mode 100644 index 00000000000..5f690d71e8c --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/Entity.cpp @@ -0,0 +1,95 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the Entity class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// LF 08/06/1999 fixed typo: defalut to default + +// + +#include "dom.h" + +// +//Construct a text object with the specified document owner and data +// +Entity::Entity(const DOMString& name, const DOMString& pubID, + const DOMString& sysID, const DOMString& notName) : + NodeDefinition(Node::ENTITY_NODE, name, NULL_STRING, NULL) +{ + publicId = pubID; + systemId = sysID; + notationName = notName; +} + +// +//Return the Public ID of the Entity +// +const DOMString& Entity::getPublicId() const +{ + return publicId; +} + +// +//Return the System ID of the Entity +// +const DOMString& Entity::getSystemId() const +{ + return systemId; +} + +// +//Return the Notation Name of the Entity +// +const DOMString& Entity::getNotationName() const +{ + return notationName; +} + +// +//First check to see if the new node is an allowable child for an Entity. If +//it is, call NodeDefinition's implementation of Insert Before. If not, return +//null as an error. +// +Node* Entity::insertBefore(Node* newChild, Node* refChild) +{ + Node* returnVal = NULL; + + switch (newChild->getNodeType()) + { + case Node::ELEMENT_NODE: + case Node::PROCESSING_INSTRUCTION_NODE: + case Node::COMMENT_NODE: + case Node::TEXT_NODE : + case Node::CDATA_SECTION_NODE: + case Node::ENTITY_REFERENCE_NODE: + returnVal = NodeDefinition::insertBefore(newChild, refChild); + break; + default: + returnVal = NULL; + } + + return returnVal; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/EntityReference.cpp b/mozilla/extensions/transformiix/source/xml/dom/EntityReference.cpp new file mode 100644 index 00000000000..2fbe9ee86b1 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/EntityReference.cpp @@ -0,0 +1,66 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the EntityReference class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// LF 08/06/1999 fixed typo: defalut to default +// + +#include "dom.h" + +// +//Construct a text object with the specified document owner and data +// +EntityReference::EntityReference(const DOMString& name, Document* owner) : + NodeDefinition(Node::ENTITY_REFERENCE_NODE, name, NULL_STRING, owner) +{ +} + +// +//First check to see if the new node is an allowable child for an +//EntityReference. If it is, call NodeDefinition's implementation of Insert +//Before. If not, return null as an error. +// +Node* EntityReference::insertBefore(Node* newChild, Node* refChild) +{ + Node* returnVal = NULL; + + switch (newChild->getNodeType()) + { + case Node::ELEMENT_NODE: + case Node::PROCESSING_INSTRUCTION_NODE: + case Node::COMMENT_NODE: + case Node::TEXT_NODE : + case Node::CDATA_SECTION_NODE: + case Node::ENTITY_REFERENCE_NODE: + returnVal = NodeDefinition::insertBefore(newChild, refChild); + break; + default: + returnVal = NULL; + } + + return returnVal; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/Makefile b/mozilla/extensions/transformiix/source/xml/dom/Makefile new file mode 100644 index 00000000000..58293717c99 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/Makefile @@ -0,0 +1,81 @@ + +#ifndef PROJ_PATH +BASE_PATH = ../../base +DOM_PATH = . +#endif + +INCLUDE_PATHS = -I$(BASE_PATH) -I . -I- + + +CC = g++ $(INCLUDE_PATHS) + +DOM_OBJS = NodeDefinition.o \ + Document.o \ + DocumentFragment.o \ + NamedNodeMap.o \ + NodeListDefinition.o \ + Element.o \ + Attr.o \ + CharacterData.o \ + Text.o \ + Comment.o \ + CDATASection.o \ + ProcessingInstruction.o \ + Notation.o \ + Entity.o \ + EntityReference.o \ + DocumentType.o \ + DOMImplementation.o + +target: $(DOM_OBJS) + +NodeDefinition.o: NodeDefinition.cpp dom.h + $(CC) -c NodeDefinition.cpp + +Document.o: Document.cpp dom.h + $(CC) -c Document.cpp + +DocumentFragment.o: DocumentFragment.cpp dom.h + $(CC) -c DocumentFragment.cpp + +NamedNodeMap.o: NamedNodeMap.cpp dom.h + $(CC) -c NamedNodeMap.cpp + +NodeListDefinition.o: NodeListDefinition.cpp dom.h + $(CC) -c NodeListDefinition.cpp + +Element.o: Element.cpp dom.h + $(CC) -c Element.cpp + +Attr.o: Attr.cpp dom.h + $(CC) -c Attr.cpp + +CharacterData.o: CharacterData.cpp dom.h + $(CC) -c CharacterData.cpp + +Text.o: Text.cpp dom.h + $(CC) -c Text.cpp + +Comment.o: Comment.cpp dom.h + $(CC) -c Comment.cpp + +CDATASection.o: CDATASection.cpp dom.h + $(CC) -c CDATASection.cpp + +ProcessingInstruction.o: ProcessingInstruction.cpp dom.h + $(CC) -c ProcessingInstruction.cpp + +Notation.o: Notation.cpp dom.h + $(CC) -c Notation.cpp + +Entity.o: Entity.cpp dom.h + $(CC) -c Entity.cpp + +EntityReference.o: EntityReference.cpp dom.h + $(CC) -c EntityReference.cpp + +DocumentType.o: DocumentType.cpp dom.h + $(CC) -c DocumentType.cpp + +DOMImplementation.o: DOMImplementation.cpp dom.h + $(CC) -c DOMImplementation.cpp diff --git a/mozilla/extensions/transformiix/source/xml/dom/NamedNodeMap.cpp b/mozilla/extensions/transformiix/source/xml/dom/NamedNodeMap.cpp new file mode 100644 index 00000000000..414c05a1e47 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/NamedNodeMap.cpp @@ -0,0 +1,111 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the NamedNodeMap class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// + +#include "dom.h" + +NamedNodeMap::NamedNodeMap() +{ +} + +NamedNodeMap::~NamedNodeMap() +{ +} + +Node* NamedNodeMap::getNamedItem(const DOMString& name) +{ + ListItem* pSearchItem = findListItemByName(name); + + if (pSearchItem) + return pSearchItem->node; + else + return NULL; +} + +Node* NamedNodeMap::setNamedItem(Node* arg) +{ + //Since the DOM does not specify any ording for the NamedNodeMap, just + //try and remove the new node (arg). If successful, return a pointer to + //the removed item. Reguardless of wheter the node already existed or not, + //insert the new node at the end of the list. + Node* pReplacedNode = removeNamedItem(arg->getNodeName()); + + NodeListDefinition::append(arg); + + return pReplacedNode; +} + +Node* NamedNodeMap::removeNamedItem(const DOMString& name) +{ + NodeListDefinition::ListItem* pSearchItem; + Node* returnNode; + + pSearchItem = findListItemByName(name); + + if (pSearchItem) + { + if (pSearchItem != firstItem) + pSearchItem->prev->next = pSearchItem->next; + else + firstItem = pSearchItem->next; + + if (pSearchItem != lastItem) + pSearchItem->next->prev = pSearchItem->prev; + else + lastItem = pSearchItem->prev; + + pSearchItem->next = NULL; + pSearchItem->prev = NULL; + + length--; + returnNode = pSearchItem->node; + delete pSearchItem; + + return returnNode; + } + + + return NULL; +} + +NodeListDefinition::ListItem* + NamedNodeMap::findListItemByName(const DOMString& name) +{ + NodeListDefinition::ListItem* pSearchItem = firstItem; + + while (pSearchItem) + { + if (name.isEqual(pSearchItem->node->getNodeName())) + return pSearchItem; + + pSearchItem = pSearchItem->next; + } + + return NULL; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/NodeDefinition.cpp b/mozilla/extensions/transformiix/source/xml/dom/NodeDefinition.cpp new file mode 100644 index 00000000000..ab5ea836256 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/NodeDefinition.cpp @@ -0,0 +1,356 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the NodeDefinition Class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// + +#include "dom.h" + +NodeDefinition::NodeDefinition(NodeType type, const DOMString& name, + const DOMString& value, Document* owner) +{ + + nodeName = name; + nodeValue = value; + nodeType = type; + + parentNode = NULL; + previousSibling = NULL; + nextSibling = NULL;; + firstChild = NULL; + lastChild = NULL; + + ownerDocument = owner; + length = 0; + +} + +// +// This node is being destroyed, so loop through and destroy all the children. +// Also, destroy all attributes stored in the attributes NamedNodeMap. +// +NodeDefinition::~NodeDefinition() +{ + Int32 numAttributes = attributes.getLength(); + Int32 killAttrLoop; + + DeleteChildren(); + + for (killAttrLoop=0;killAttrLoopgetNodeName()); +} + +// +//Remove and delete all children of this node +// +void NodeDefinition::DeleteChildren() +{ + NodeDefinition* pCurrent = firstChild; + NodeDefinition* pDestroyer; + + while (pCurrent) + { + pDestroyer = pCurrent; + pCurrent = pCurrent->nextSibling; + delete pDestroyer; + } + + length = 0; + firstChild = NULL; + lastChild = NULL; +} + +const DOMString& NodeDefinition::getNodeName() const +{ + return nodeName; +} + +const DOMString& NodeDefinition::getNodeValue() const +{ + return nodeValue; +} + +const DOMString& NodeDefinition::getNodeValue() +{ + return nodeValue; +} + +unsigned short NodeDefinition::getNodeType() const +{ + return nodeType; +} + +Node* NodeDefinition::getParentNode() const +{ + return parentNode; +} + +NodeList* NodeDefinition::getChildNodes() +{ + return this; +} + +Node* NodeDefinition::getFirstChild() const +{ + return firstChild; +} + +Node* NodeDefinition::getLastChild() const +{ + return lastChild; +} + +Node* NodeDefinition::getPreviousSibling() const +{ + return previousSibling; +} + +Node* NodeDefinition::getNextSibling() const +{ + return nextSibling; +} + +NamedNodeMap* NodeDefinition::getAttributes() +{ + return &attributes; +} + +Document* NodeDefinition::getOwnerDocument() const +{ + return ownerDocument; +} + +Node* NodeDefinition::item(Int32 index) +{ + Int32 selectLoop; + NodeDefinition* pSelectNode = firstChild; + + if (index < length) + { + for (selectLoop=0;selectLoopnextSibling; + + return pSelectNode; + } + + return NULL; +} + +Int32 NodeDefinition::getLength() +{ + return length; +} + +void NodeDefinition::setNodeValue(const DOMString& newNodeValue) +{ + nodeValue = newNodeValue; +} + +// +//Insert the "newChild" node before the "refChild" node. Return a pointer to +//the inserted child. If the node to insert is a document fragment, then +//insert each child of the document fragment, and return the document fragment +//which should be empty if all the inserts suceeded. +//This function's responsibility is to check for and handle document fragments +//vs. plain nodes. +// *** NOTE: Need to check the document types before inserting. +// +// The decision to return the possibly empty document fragment +// was an implementation choice. The spec did not dictate what +// whould occur. +// +Node* NodeDefinition::insertBefore(Node* newChild, + Node* refChild) +{ + NodeDefinition* pCurrentNode = NULL; + NodeDefinition* pNextNode = NULL; + + //Convert to a NodeDefinition Pointer + NodeDefinition* pNewChild = (NodeDefinition*)newChild; + NodeDefinition* pRefChild = (NodeDefinition*)refChild; + + //Check to see if the reference node is a child of this node + if ((refChild != NULL) && (pRefChild->parentNode != this)) + return NULL; + + if (pNewChild->getNodeType() == Node::DOCUMENT_FRAGMENT_NODE) + { + pCurrentNode = pNewChild->firstChild; + while (pCurrentNode) + { + pNextNode = pCurrentNode->nextSibling; + pCurrentNode = (NodeDefinition*)pNewChild->removeChild(pCurrentNode); + implInsertBefore(pCurrentNode, pRefChild); + pCurrentNode = pNextNode; + } + return newChild; + } + else + return implInsertBefore(pNewChild, pRefChild); +} + +// +//The code that actually insert one node before another. +// +Node* NodeDefinition::implInsertBefore(NodeDefinition* pNewChild, + NodeDefinition* pRefChild) +{ + //Remove the "newChild" if it is already a child of this node + if (pNewChild->parentNode == this) + pNewChild = (NodeDefinition*)removeChild(pNewChild); + + //The new child should not be a child of any other node + if ((pNewChild->previousSibling == NULL) && + (pNewChild->nextSibling == NULL) && + (pNewChild->parentNode == NULL)) + { + if (pRefChild == NULL) + { + //Append + pNewChild->previousSibling = lastChild; + + if (lastChild) + lastChild->nextSibling = pNewChild; + + lastChild = pNewChild; + } + else + { + //Insert before the reference node + if (pRefChild->previousSibling) + pRefChild->previousSibling->nextSibling = pNewChild; + pNewChild->nextSibling = pRefChild; + pNewChild->previousSibling = pRefChild->previousSibling; + pRefChild->previousSibling = pNewChild; + } + + pNewChild->parentNode = this; + + if (pNewChild->previousSibling == NULL) + firstChild = pNewChild; + + length++; + + return pNewChild; + } + + return NULL; +} + + +// +//Replace "oldChild" with "newChild". Return the replaced node, or NULL +//otherwise. +// *** NOTE: Need to check that the documents match *** +// +Node* NodeDefinition::replaceChild(Node* newChild, + Node* oldChild) +{ + NodeDefinition* pOldChild = (NodeDefinition*)oldChild; + NodeDefinition* pNextSibling = NULL; + + //If the newChild is replacing itself then we don't need to do anything + if (pOldChild == newChild) + return pOldChild; + + //If "oldChild" is a child of this node, remove it from the list. + pOldChild = (NodeDefinition*)removeChild(oldChild); + + //If the removal was successful... Else, return null + if (pOldChild) + { + //Try to insert the new node before the old node's next sibling. If + //successful, just returned the replaced child. If not succesful, + //reinsert the old node, and return NULL. + pNextSibling = pOldChild->nextSibling; + if (!insertBefore(newChild, pNextSibling)) + { + insertBefore(pOldChild, pNextSibling); + pOldChild = NULL; + } + } + + return pOldChild; +} + +// +//Remove the specified "oldChild" from this node's children. First make sure +//the specified node is a child of this node. Return the removed node, NULL +//otherwise. +// +Node* NodeDefinition::removeChild(Node* oldChild) +{ + NodeDefinition* pOldChild = (NodeDefinition*)oldChild; + + //If "oldChild" is a child of this node, adjust pointers to remove it, and + //clear "oldChild"'s sibling and parent pointers. + if (pOldChild->parentNode == this) + { + if (pOldChild != firstChild) + pOldChild->previousSibling->nextSibling = pOldChild->nextSibling; + else + firstChild = pOldChild->nextSibling; + + if (pOldChild != lastChild) + pOldChild->nextSibling->previousSibling = pOldChild->previousSibling; + else + lastChild = pOldChild->previousSibling; + + pOldChild->nextSibling = NULL; + pOldChild->previousSibling = NULL; + pOldChild->parentNode = NULL; + + length--; + + return pOldChild; + } + + return NULL; +} + +// +//Append a new child node. First make sure the new child is not already a +//child of another node. Return the appended node. +// *** NOTE *** Need to eventually check to make sure the documents match *** +// +Node* NodeDefinition::appendChild(Node* newChild) +{ + return insertBefore(newChild, NULL); +} + +Node* NodeDefinition::cloneNode(MBool deep, Node* dest) +{ + return 0; +} + +MBool NodeDefinition::hasChildNodes() const +{ + if (firstChild != NULL) + return MB_TRUE; + else + return MB_FALSE; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/NodeListDefinition.cpp b/mozilla/extensions/transformiix/source/xml/dom/NodeListDefinition.cpp new file mode 100644 index 00000000000..4bb1983ffd1 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/NodeListDefinition.cpp @@ -0,0 +1,117 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the NodeListDefinition class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// + +#include "dom.h" + +// +//Create an empty node list. +// +NodeListDefinition::NodeListDefinition() +{ + firstItem = NULL; + lastItem = NULL; + length = 0; +} + +// +//Free up the memory used by the List of Items. Don't delete the actual nodes +//though. +// +NodeListDefinition::~NodeListDefinition() +{ + ListItem* pDeleteItem; + ListItem* pListTraversal = firstItem; + + while (pListTraversal) + { + pDeleteItem = pListTraversal; + pListTraversal = pListTraversal->next; + delete pDeleteItem; + } +} + +// +//Create a new ListItem, point it to the newNode, and append it to the current +//list of nodes. +// +void NodeListDefinition::append(Node* newNode) +{ + append(*newNode); +} + +void NodeListDefinition::append(Node& newNode) +{ + ListItem* newListItem = new ListItem; + + // Setup the new list item + newListItem->node = &newNode; + newListItem->prev = lastItem; + newListItem->next = NULL; + + //Append the list item + if (lastItem) + lastItem->next = newListItem; + + lastItem = newListItem; + + //Adjust firstItem if this new item is being added to an empty list + if (!firstItem) + firstItem = lastItem; + + //Need to increment the length of the list. Inherited from NodeList + length++; +} + +// +// Return the Node contained in the item specified +// +Node* NodeListDefinition::item(Int32 index) +{ + Int32 selectLoop; + ListItem* pListItem = firstItem; + + if (index < length) + { + for (selectLoop=0;selectLoopnext; + + return pListItem->node; + } + + return NULL; +} + +// +// Return the number of items in the list +// +Int32 NodeListDefinition::getLength() +{ + return length; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/Notation.cpp b/mozilla/extensions/transformiix/source/xml/dom/Notation.cpp new file mode 100644 index 00000000000..8aad385b6c5 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/Notation.cpp @@ -0,0 +1,81 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the Notation class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// + +#include "dom.h" + +// +//Construct a text object with the specified document owner and data +// +Notation::Notation(const DOMString& name, const DOMString& pubID, + const DOMString& sysID) : + NodeDefinition(Node::NOTATION_NODE, name, NULL_STRING, NULL) +{ + publicId = pubID; + systemId = sysID; +} + +// +//Return the Public ID of the Notation +// +const DOMString& Notation::getPublicId() const +{ + return publicId; +} + +//Return the System ID of the Notation +const DOMString& Notation::getSystemId() const +{ + return systemId; +} + +// +//Notation nodes can not have any children, so just return null from all child +//manipulation functions. +// + +Node* Notation::insertBefore(Node* newChild, Node* refChild) +{ + return NULL; +} + +Node* Notation::replaceChild(Node* newChild, Node* oldChild) +{ + return NULL; +} + +Node* Notation::removeChild(Node* oldChild) +{ + return NULL; +} + +Node* Notation::appendChild(Node* newChild) +{ + return NULL; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/ProcessingInstruction.cpp b/mozilla/extensions/transformiix/source/xml/dom/ProcessingInstruction.cpp new file mode 100644 index 00000000000..ffc8e56f001 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/ProcessingInstruction.cpp @@ -0,0 +1,93 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the ProcessingInstruction class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// + +#include "dom.h" + +// +//Construct a text object with the specified document owner and data +// +ProcessingInstruction::ProcessingInstruction(const DOMString& theTarget, + const DOMString& theData, + Document* owner) : + NodeDefinition(Node::PROCESSING_INSTRUCTION_NODE, + theTarget, theData, owner) +{ +} + +// +//Return the Target of the processing instruction. This is simply the +//nodeName. +// +const DOMString& ProcessingInstruction::getTarget() const +{ + return nodeName; +} + +// +//Return the Data of the processing instruction. This is simply the value +//of the node, "nodeValue" +// +const DOMString& ProcessingInstruction::getData() const +{ + return nodeValue; +} + +// +//Set the Data element of the processing instruction. +void ProcessingInstruction::setData(const DOMString& theData) +{ + nodeValue = theData; +} + + +// +//ProcessingInstruction nodes can not have any children, so just return null +//from all child manipulation functions. +// + +Node* ProcessingInstruction::insertBefore(Node* newChild, Node* refChild) +{ + return NULL; +} + +Node* ProcessingInstruction::replaceChild(Node* newChild, Node* oldChild) +{ + return NULL; +} + +Node* ProcessingInstruction::removeChild(Node* oldChild) +{ + return NULL; +} + +Node* ProcessingInstruction::appendChild(Node* newChild) +{ + return NULL; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/Text.cpp b/mozilla/extensions/transformiix/source/xml/dom/Text.cpp new file mode 100644 index 00000000000..71492901491 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/Text.cpp @@ -0,0 +1,93 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the Text class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// + +#include "dom.h" + +// +//Construct a text object with the specified document owner and data +// +Text::Text(const DOMString& theData, Document* owner) : + CharacterData(Node::TEXT_NODE, "#text", theData, owner) +{ +} + +// +//Protected constructor for children of the Text Class. Currently only +//CDATASection needs to use this function. +Text::Text(NodeType type, const DOMString& name, const DOMString& value, + Document* owner) : + CharacterData(type, name, value, owner) +{ +} + + +// +//Split the text node at Offset into two siblings. Return a pointer to the new +//sibling. +// +Text* Text::splitText(Int32 offset) +{ + Text* newTextSibling = NULL; + DOMString newData; + + if ((offset >= 0) && (offset < nodeValue.length())) + { + newTextSibling = getOwnerDocument()->createTextNode(nodeValue.subString(offset, newData)); + getParentNode()->insertBefore(newTextSibling, getNextSibling()); + nodeValue.deleteChars(offset, nodeValue.length() - offset); + } + + return newTextSibling; +} + +// +//Text nodes can not have any children, so just return null from all child +//manipulation functions. +// + +Node* Text::insertBefore(Node* newChild, Node* refChild) +{ + return NULL; +} + +Node* Text::replaceChild(Node* newChild, Node* oldChild) +{ + return NULL; +} + +Node* Text::removeChild(Node* oldChild) +{ + return NULL; +} + +Node* Text::appendChild(Node* newChild) +{ + return NULL; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/makefile.win b/mozilla/extensions/transformiix/source/xml/dom/makefile.win new file mode 100644 index 00000000000..5060709e5af --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/makefile.win @@ -0,0 +1,22 @@ +#!nmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH=..\..\..\..\..\.. + +DIRS=mozImpl + +include <$(DEPTH)\config\rules.mak> diff --git a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/Attr.cpp b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/Attr.cpp new file mode 100644 index 00000000000..04a4004b76e --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/Attr.cpp @@ -0,0 +1,143 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the Attr class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// LF 08/06/1999 fixed typo: defalut to default + +// + +#include "dom.h" + +// +//Construct an Attribute object using the specified name and document owner +// +Attr::Attr(const DOMString& name, Document* owner): + NodeDefinition(Node::ATTRIBUTE_NODE, name, NULL_STRING, owner) +{ + specified = MB_FALSE; +} + +// +//Retrieve the name of the attribute from the nodeName data member +// +const DOMString& Attr::getName() const +{ + return nodeName; +} + +// +//Retrieve the specified flag +// +MBool Attr::getSpecified() const +{ + return specified; +} + +// +//Retrieve the value of the attribute. This is a comma-deliminated string +//representation of the Attribute's children. +// +const DOMString& Attr::getValue() +{ + Int32 valueLoop; + nodeValue = NULL_STRING; + NodeList* childList = getChildNodes(); + Int32 numChildren = childList->getLength(); + + for (valueLoop=0;valueLoopitem(valueLoop)->getNodeType() != Node::ENTITY_REFERENCE_NODE) + { + nodeValue.append(childList->item(valueLoop)->getNodeValue()); + if (valueLoop < (numChildren-1)) + nodeValue.append(","); + } + } + + return nodeValue; +} + +// +//Create a new Text node and add it to the Attribute's list of children. Also +//set the Specified flag to true. +// +void Attr::setValue(const DOMString& newValue) +{ + NodeDefinition::DeleteChildren(); + + appendChild(getOwnerDocument()->createTextNode(newValue)); + + specified = MB_TRUE; +} + + +// +//Override the set node value member function to create a new TEXT node with +//the DOMString and to add it as the Attribute's child. +// NOTE: Not currently impemented, just execute the default setNodeValue +// +void Attr::setNodeValue(const DOMString& nodeValue) +{ + setValue(nodeValue); +} + +// +//Return a DOMString represening the value of this node. If the value is an +//Entity Reference then return the value of the reference. Otherwise, it is a +//simple conversion of the text value. +// NOTE: Not currently implemented, just execute the default getNodeValue +// +const DOMString& Attr::getNodeValue() +{ + return getValue(); +} + + +// +//First check to see if the new node is an allowable child for an Attr. If it +//is, call NodeDefinition's implementation of Insert Before. If not, return +//null as an error. +// +Node* Attr::insertBefore(Node* newChild, Node* refChild) +{ + Node* returnVal = NULL; + + switch (newChild->getNodeType()) + { + case Node::TEXT_NODE : + case Node::ENTITY_REFERENCE_NODE: + returnVal = NodeDefinition::insertBefore(newChild, refChild); + + if (returnVal) + specified = MB_TRUE; + break; + default: + returnVal = NULL; + } + + return returnVal; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/CDATASection.cpp b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/CDATASection.cpp new file mode 100644 index 00000000000..328bba1ca63 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/CDATASection.cpp @@ -0,0 +1,64 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the CDATASection class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// + +#include "dom.h" + +// +//Construct a text object with the specified document owner and data +// +CDATASection::CDATASection(const DOMString& theData, Document* owner) : + Text(Node::CDATA_SECTION_NODE, "#cdata-section", theData, owner) +{ +} + +// +//CDATASection nodes can not have any children, so just return null from all child +//manipulation functions. +// + +Node* CDATASection::insertBefore(Node* newChild, Node* refChild) +{ + return NULL; +} + +Node* CDATASection::replaceChild(Node* newChild, Node* oldChild) +{ + return NULL; +} + +Node* CDATASection::removeChild(Node* oldChild) +{ + return NULL; +} + +Node* CDATASection::appendChild(Node* newChild) +{ + return NULL; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/CharacterData.cpp b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/CharacterData.cpp new file mode 100644 index 00000000000..dbdc75c4371 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/CharacterData.cpp @@ -0,0 +1,113 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the CharacterData class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// + +#include "dom.h" + +// +//Protected constructor. Just pass parameters onto NodeDefinition. +// +CharacterData::CharacterData(NodeType type, const DOMString& name, + const DOMString& value, Document* owner) : + NodeDefinition(type, name, value, owner) +{ +} + +// +//Return a constant reference to the data stored by this object. +// +const DOMString& CharacterData::getData() const +{ + return nodeValue; +} + +// +//Set the data stored by this object to the string represented by "source". +// +void CharacterData::setData(const DOMString& source) +{ + nodeValue = source; +} + +// +//Returns the length of the data object. +// +Int32 CharacterData::getLength() const +{ + return nodeValue.length(); +} + +// +//Retreive the substring starting at offset anc ending count number of +//characters away. +// NOTE: An empty string will be returned in the event of an error. +// +DOMString& CharacterData::substringData(Int32 offset, Int32 count, DOMString& dest) +{ + if ((offset >= 0) && (offset < nodeValue.length()) && (count > 0)) + return nodeValue.subString(offset, offset+count, dest); + else + { + dest.clear(); + return dest; + } +} + +void CharacterData::appendData(const DOMString& arg) +{ + nodeValue.append(arg); +} + +void CharacterData::insertData(Int32 offset, const DOMString& arg) +{ + if ((offset >= 0) && (offset < nodeValue.length())) + nodeValue.insert(offset, arg); +} + +void CharacterData::deleteData(Int32 offset, Int32 count) +{ + if ((offset >= 0) && (offset < nodeValue.length()) && (count > 0)) + nodeValue.deleteChars(offset, count); +} + +void CharacterData::replaceData(Int32 offset, Int32 count, const DOMString& arg) +{ + DOMString tempString; + + if ((offset >= 0) && (offset < nodeValue.length()) && (count > 0)) + { + if (count < arg.length()) + { + tempString = arg.subString(0, count, tempString); + nodeValue.replace(offset, tempString); + } + else + nodeValue.replace(offset, arg); + } +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/Comment.cpp b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/Comment.cpp new file mode 100644 index 00000000000..97db4507946 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/Comment.cpp @@ -0,0 +1,64 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the Comment class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// + +#include "dom.h" + +// +//Construct a text object with the specified document owner and data +// +Comment::Comment(const DOMString& theData, Document* owner) : + CharacterData(Node::COMMENT_NODE, "#comment", theData, owner) +{ +} + +// +//Comment nodes can not have any children, so just return null from all child +//manipulation functions. +// + +Node* Comment::insertBefore(Node* newChild, Node* refChild) +{ + return NULL; +} + +Node* Comment::replaceChild(Node* newChild, Node* oldChild) +{ + return NULL; +} + +Node* Comment::removeChild(Node* oldChild) +{ + return NULL; +} + +Node* Comment::appendChild(Node* newChild) +{ + return NULL; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/DOMImplementation.cpp b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/DOMImplementation.cpp new file mode 100644 index 00000000000..91d4974c9dd --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/DOMImplementation.cpp @@ -0,0 +1,56 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the DOMImplementation class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// + +#include "dom.h" + +DOMImplementation::DOMImplementation() +{ + implFeature = "XML"; + implVersion = "1.0"; +} + +DOMImplementation::~DOMImplementation() +{ +} + +// +//Perform a case insensitive comparison between "feature" and the +//functionality of this DOM implementation/version. +// +MBool DOMImplementation::hasFeature(DOMString feature, + const DOMString& version) const +{ + feature.toUpperCase(); + + if (feature.isEqual(implFeature) && version.isEqual(implVersion)) + return MB_TRUE; + else + return MB_FALSE; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/Document.cpp b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/Document.cpp new file mode 100644 index 00000000000..be9b55500de --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/Document.cpp @@ -0,0 +1,258 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the Document class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// LF 08/06/1999 Removed Default argument initializer from +// Document() constructor +// LF 08/06/1999 fixed typo: defalut to default +// + +#include "dom.h" + +// +//Construct a Document. Currently no parameters are required, but the the +//node constructor is called to identify the node type. +// +Document::Document(DocumentType* theDoctype) : + NodeDefinition(Node::DOCUMENT_NODE, "#document", NULL_STRING, NULL) +{ + documentElement = NULL; + doctype = theDoctype; +} + +// +//Return the one and only element for this document +// +Element* Document::getDocumentElement() +{ + return documentElement; +} + +// +//Return the document type of this document object +// +DocumentType* Document::getDoctype() +{ + return doctype; +} + +// +//Return a constant reference to the DOM's Implementation +// +const DOMImplementation& Document::getImplementation() +{ + return implementation; +} + +// +//Ensure that no Element node is inserted if the document already has an +//associated Element child. +// +Node* Document::insertBefore(Node* newChild, Node* refChild) +{ + Node* returnVal = NULL; + + NodeDefinition* pCurrentNode = NULL; + NodeDefinition* pNextNode = NULL; + + //Convert to a NodeDefinition Pointer + NodeDefinition* pNewChild = (NodeDefinition*)newChild; + NodeDefinition* pRefChild = (NodeDefinition*)refChild; + + //Check to see if the reference node is a child of this node + if ((refChild != NULL) && (pRefChild->getParentNode() != this)) + return NULL; + + switch (pNewChild->getNodeType()) + { + case Node::DOCUMENT_FRAGMENT_NODE : + pCurrentNode = (NodeDefinition*)pNewChild->getFirstChild(); + while (pCurrentNode) + { + pNextNode = (NodeDefinition*)pCurrentNode->getNextSibling(); + + //Make sure that if the current node is an Element, the document + //doesn't already have one. + if ((pCurrentNode->getNodeType() != Node::ELEMENT_NODE) || + ((pCurrentNode->getNodeType() == Node::ELEMENT_NODE) && + (documentElement == NULL))) + { + pCurrentNode = (NodeDefinition*)pNewChild->removeChild(pCurrentNode); + implInsertBefore(pCurrentNode, pRefChild); + + if (pCurrentNode->getNodeType() == Node::ELEMENT_NODE) + documentElement = (Element*)pCurrentNode; + } + pCurrentNode = pNextNode; + } + returnVal = newChild; + break; + + case Node::PROCESSING_INSTRUCTION_NODE : + case Node::COMMENT_NODE : + case Node::DOCUMENT_TYPE_NODE : + returnVal = implInsertBefore(pNewChild, pRefChild); + break; + + case Node::ELEMENT_NODE : + if (!documentElement) + { + documentElement = (Element*)pNewChild; + returnVal = implInsertBefore(pNewChild, pRefChild); + } + else + returnVal = NULL; + break; + default: + returnVal = NULL; + } + + return returnVal; +} + +// +//Ensure that if the newChild is an Element and the Document already has an +//element, then oldChild should be specifying the existing element. If not +//then the replacement can not take place. +// +Node* Document::replaceChild(Node* newChild, Node* oldChild) +{ + Node* replacedChild = NULL; + + if (newChild->getNodeType() != Node::ELEMENT_NODE) + { + //The new child is not an Element, so perform replacement + replacedChild = NodeDefinition::replaceChild(newChild, oldChild); + + //If old node was an Element, then the document's element has been + //replaced with a non-element node. Therefore clear the documentElement + //pointer + if (replacedChild && (oldChild->getNodeType() == Node::ELEMENT_NODE)) + documentElement = NULL; + + return replacedChild; + } + else + { + //A node is being replaced with an Element. If the document does not + //have an elemet yet, then just allow the replacemetn to take place. + if (!documentElement) + replacedChild = NodeDefinition::replaceChild(newChild, oldChild); + else if (oldChild->getNodeType() == Node::ELEMENT_NODE) + replacedChild = NodeDefinition::replaceChild(newChild, oldChild); + + if (replacedChild) + documentElement = (Element*)newChild; + + return replacedChild; + } +} + +// +//Update the documentElement pointer if the associated Element node is being +//removed. +// +Node* Document::removeChild(Node* oldChild) +{ + Node* removedChild = NULL; + + removedChild = NodeDefinition::removeChild(oldChild); + + if (removedChild && (removedChild->getNodeType() == Node::ELEMENT_NODE)) + documentElement = NULL; + + return removedChild; +} + +// +//Construct an empty document fragment. +// NOTE: The caller is responsible for cleaning up this fragment's memory +// when it is no longer needed. +// +DocumentFragment* Document::createDocumentFragment() +{ + return new DocumentFragment("#document-fragment", NULL_STRING, this); +} + +// +//Construct an element with the specified tag name. +// NOTE: The caller is responsible for cleaning up the element's menory +// +Element* Document::createElement(const DOMString& tagName) +{ + return new Element(tagName, this); +} + +// +//Construct an attribute with the specified name +// +Attr* Document::createAttribute(const DOMString& name) +{ + return new Attr(name, this); +} + +// +//Construct a text node with the given data +// +Text* Document::createTextNode(const DOMString& theData) +{ + return new Text(theData, this); +} + +// +//Construct a comment node with the given data +// +Comment* Document::createComment(const DOMString& theData) +{ + return new Comment(theData, this); +} + +// +//Construct a CDATASection node with the given data +// +CDATASection* Document::createCDATASection(const DOMString& theData) +{ + return new CDATASection(theData, this); +} + +// +//Construct a ProcessingInstruction node with the given targe and data. +// +ProcessingInstruction* + Document::createProcessingInstruction(const DOMString& target, + const DOMString& data) +{ + return new ProcessingInstruction(target, data, this); +} + +// +//Construct an EntityReference with the given name +// +EntityReference* Document::createEntityReference(const DOMString& name) +{ + return new EntityReference(name, this); +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/DocumentFragment.cpp b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/DocumentFragment.cpp new file mode 100644 index 00000000000..084fe26b543 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/DocumentFragment.cpp @@ -0,0 +1,68 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the DocumentFragment class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// LF 08/06/1999 fixed typo: defalut to default +// + +#include "dom.h" + +// +//Construct a DocumentFragment with the specified name and value. Call the +//constructor for NodeDefinition and specify the DocumentFragment Type. +// +DocumentFragment::DocumentFragment(const DOMString& name, + const DOMString& value, Document* owner) : + NodeDefinition(Node::DOCUMENT_FRAGMENT_NODE, name, value, owner) +{ +} + +// +//First check to see if the new node is an allowable child for a +//DocumentFragment. If it is, call NodeDefinition's implementation of Insert +//Before. If not, return null as an error. +// +Node* DocumentFragment::insertBefore(Node* newChild, Node* refChild) +{ + Node* returnVal = NULL; + + switch (newChild->getNodeType()) + { + case Node::ELEMENT_NODE : + case Node::PROCESSING_INSTRUCTION_NODE : + case Node::COMMENT_NODE : + case Node::TEXT_NODE : + case Node::CDATA_SECTION_NODE : + case Node::ENTITY_REFERENCE_NODE: + returnVal = NodeDefinition::insertBefore(newChild, refChild); + break; + default: + returnVal = NULL; + } + + return returnVal; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/DocumentType.cpp b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/DocumentType.cpp new file mode 100644 index 00000000000..3c86aa204c2 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/DocumentType.cpp @@ -0,0 +1,96 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the DocumentType class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// + +#include "dom.h" + +// +//Construct a text object with the specified document owner and data +// +DocumentType::DocumentType(const DOMString& name, NamedNodeMap* theEntities, + NamedNodeMap* theNotations) : + NodeDefinition(Node::DOCUMENT_TYPE_NODE, name, NULL_STRING, NULL) +{ + entities = theEntities; + notations = theNotations; +} + +// +//When destroying the DocumentType, the entities and notations must be +//destroyed too. +// +DocumentType::~DocumentType() +{ + if (entities) + delete entities; + + if (notations) + delete notations; +} + +// +//Return a pointer to the entities contained in this Document Type +// +NamedNodeMap* DocumentType::getEntities() +{ + return entities; +} + +// +//Return a pointer to the notations contained in this Document Type +// +NamedNodeMap* DocumentType::getNotations() +{ + return notations; +} + +// +//Comment nodes can not have any children, so just return null from all child +//manipulation functions. +// + +Node* DocumentType::insertBefore(Node* newChild, Node* refChild) +{ + return NULL; +} + +Node* DocumentType::replaceChild(Node* newChild, Node* oldChild) +{ + return NULL; +} + +Node* DocumentType::removeChild(Node* oldChild) +{ + return NULL; +} + +Node* DocumentType::appendChild(Node* newChild) +{ + return NULL; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/Element.cpp b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/Element.cpp new file mode 100644 index 00000000000..29f0da2c4af --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/Element.cpp @@ -0,0 +1,161 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the Element class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// LF 08/06/1999 fixed typo: defalut to default +// + +#include "dom.h" + +// +//Construct a new element with the specified tagName and Document owner. +//Simply call the constructor for NodeDefinition, and specify the proper node +//type. +// +Element::Element(const DOMString& tagName, Document* owner) : + NodeDefinition(Node::ELEMENT_NODE, tagName, NULL_STRING, owner) +{ +} + +// +//First check to see if the new node is an allowable child for an Element. If +//it is, call NodeDefinition's implementation of Insert Before. If not, return +//null as an error +// +Node* Element::insertBefore(Node* newChild, Node* refChild) +{ + Node* returnVal = NULL; + + switch (newChild->getNodeType()) + { + case Node::ELEMENT_NODE : + case Node::TEXT_NODE : + case Node::COMMENT_NODE : + case Node::PROCESSING_INSTRUCTION_NODE : + case Node::CDATA_SECTION_NODE : + case Node::ENTITY_REFERENCE_NODE: + returnVal = NodeDefinition::insertBefore(newChild, refChild); + break; + default: + returnVal = NULL; + } + + return returnVal; +} + +// +//Return the tagName for this element. This is simply the nodeName. +// +const DOMString& Element::getTagName() +{ + return nodeName; +} + +// +//Retreive an attribute's value by name. If the attribute does not exist, +//return a reference to the pre-created, constatnt "NULL STRING". +// +const DOMString& Element::getAttribute(const DOMString& name) +{ + Node* tempNode = attributes.getNamedItem(name); + + if (tempNode) + return attributes.getNamedItem(name)->getNodeValue(); + else + return NULL_STRING; +} + + +// +//Add an attribute to this Element. Create a new Attr object using the +//name and value specified. Then add the Attr to the the Element's +//attributes NamedNodeMap. +// +void Element::setAttribute(const DOMString& name, const DOMString& value) +{ + Attr* tempAttribute; + + //Check to see if an attribute with this name already exists. If it does + //over write its value, if not, add it. + tempAttribute = getAttributeNode(name); + if (tempAttribute) + tempAttribute->setNodeValue(value); + else + { + tempAttribute = getOwnerDocument()->createAttribute(name); + tempAttribute->setNodeValue(value); + attributes.setNamedItem(tempAttribute); + } +} + +// +//Remove an attribute from the attributes NamedNodeMap, and free its memory. +// NOTE: How do default values enter into this picture +// +void Element::removeAttribute(const DOMString& name) +{ + delete attributes.removeNamedItem(name); +} + +// +//Return the attribute specified by name +// +Attr* Element::getAttributeNode(const DOMString& name) +{ + return (Attr*)attributes.getNamedItem(name); +} + +// +//Set a new attribute specifed by the newAttr node. If an attribute with that +//name already exists, the existing Attr is removed from the list and return to +//the caller, else NULL is returned. +// +Attr* Element::setAttributeNode(Attr* newAttr) +{ + Attr* pOldAttr = (Attr*)attributes.removeNamedItem(newAttr->getNodeName()); + + attributes.setNamedItem(newAttr); + return pOldAttr; +} + +// +//Remove the Attribute from the attributes list and return to the caller. If +//the node is not found, return NULL. +// +Attr* Element::removeAttributeNode(Attr* oldAttr) +{ + return (Attr*)attributes.removeNamedItem(oldAttr->getNodeName()); +} + +NodeList* Element::getElementsByTagName(const DOMString& name) +{ + return 0; +} + +void Element::normalize() +{ +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/Entity.cpp b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/Entity.cpp new file mode 100644 index 00000000000..5f690d71e8c --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/Entity.cpp @@ -0,0 +1,95 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the Entity class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// LF 08/06/1999 fixed typo: defalut to default + +// + +#include "dom.h" + +// +//Construct a text object with the specified document owner and data +// +Entity::Entity(const DOMString& name, const DOMString& pubID, + const DOMString& sysID, const DOMString& notName) : + NodeDefinition(Node::ENTITY_NODE, name, NULL_STRING, NULL) +{ + publicId = pubID; + systemId = sysID; + notationName = notName; +} + +// +//Return the Public ID of the Entity +// +const DOMString& Entity::getPublicId() const +{ + return publicId; +} + +// +//Return the System ID of the Entity +// +const DOMString& Entity::getSystemId() const +{ + return systemId; +} + +// +//Return the Notation Name of the Entity +// +const DOMString& Entity::getNotationName() const +{ + return notationName; +} + +// +//First check to see if the new node is an allowable child for an Entity. If +//it is, call NodeDefinition's implementation of Insert Before. If not, return +//null as an error. +// +Node* Entity::insertBefore(Node* newChild, Node* refChild) +{ + Node* returnVal = NULL; + + switch (newChild->getNodeType()) + { + case Node::ELEMENT_NODE: + case Node::PROCESSING_INSTRUCTION_NODE: + case Node::COMMENT_NODE: + case Node::TEXT_NODE : + case Node::CDATA_SECTION_NODE: + case Node::ENTITY_REFERENCE_NODE: + returnVal = NodeDefinition::insertBefore(newChild, refChild); + break; + default: + returnVal = NULL; + } + + return returnVal; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/EntityReference.cpp b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/EntityReference.cpp new file mode 100644 index 00000000000..2fbe9ee86b1 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/EntityReference.cpp @@ -0,0 +1,66 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the EntityReference class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// LF 08/06/1999 fixed typo: defalut to default +// + +#include "dom.h" + +// +//Construct a text object with the specified document owner and data +// +EntityReference::EntityReference(const DOMString& name, Document* owner) : + NodeDefinition(Node::ENTITY_REFERENCE_NODE, name, NULL_STRING, owner) +{ +} + +// +//First check to see if the new node is an allowable child for an +//EntityReference. If it is, call NodeDefinition's implementation of Insert +//Before. If not, return null as an error. +// +Node* EntityReference::insertBefore(Node* newChild, Node* refChild) +{ + Node* returnVal = NULL; + + switch (newChild->getNodeType()) + { + case Node::ELEMENT_NODE: + case Node::PROCESSING_INSTRUCTION_NODE: + case Node::COMMENT_NODE: + case Node::TEXT_NODE : + case Node::CDATA_SECTION_NODE: + case Node::ENTITY_REFERENCE_NODE: + returnVal = NodeDefinition::insertBefore(newChild, refChild); + break; + default: + returnVal = NULL; + } + + return returnVal; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/NamedNodeMap.cpp b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/NamedNodeMap.cpp new file mode 100644 index 00000000000..414c05a1e47 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/NamedNodeMap.cpp @@ -0,0 +1,111 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the NamedNodeMap class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// + +#include "dom.h" + +NamedNodeMap::NamedNodeMap() +{ +} + +NamedNodeMap::~NamedNodeMap() +{ +} + +Node* NamedNodeMap::getNamedItem(const DOMString& name) +{ + ListItem* pSearchItem = findListItemByName(name); + + if (pSearchItem) + return pSearchItem->node; + else + return NULL; +} + +Node* NamedNodeMap::setNamedItem(Node* arg) +{ + //Since the DOM does not specify any ording for the NamedNodeMap, just + //try and remove the new node (arg). If successful, return a pointer to + //the removed item. Reguardless of wheter the node already existed or not, + //insert the new node at the end of the list. + Node* pReplacedNode = removeNamedItem(arg->getNodeName()); + + NodeListDefinition::append(arg); + + return pReplacedNode; +} + +Node* NamedNodeMap::removeNamedItem(const DOMString& name) +{ + NodeListDefinition::ListItem* pSearchItem; + Node* returnNode; + + pSearchItem = findListItemByName(name); + + if (pSearchItem) + { + if (pSearchItem != firstItem) + pSearchItem->prev->next = pSearchItem->next; + else + firstItem = pSearchItem->next; + + if (pSearchItem != lastItem) + pSearchItem->next->prev = pSearchItem->prev; + else + lastItem = pSearchItem->prev; + + pSearchItem->next = NULL; + pSearchItem->prev = NULL; + + length--; + returnNode = pSearchItem->node; + delete pSearchItem; + + return returnNode; + } + + + return NULL; +} + +NodeListDefinition::ListItem* + NamedNodeMap::findListItemByName(const DOMString& name) +{ + NodeListDefinition::ListItem* pSearchItem = firstItem; + + while (pSearchItem) + { + if (name.isEqual(pSearchItem->node->getNodeName())) + return pSearchItem; + + pSearchItem = pSearchItem->next; + } + + return NULL; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/NodeDefinition.cpp b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/NodeDefinition.cpp new file mode 100644 index 00000000000..ab5ea836256 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/NodeDefinition.cpp @@ -0,0 +1,356 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the NodeDefinition Class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// + +#include "dom.h" + +NodeDefinition::NodeDefinition(NodeType type, const DOMString& name, + const DOMString& value, Document* owner) +{ + + nodeName = name; + nodeValue = value; + nodeType = type; + + parentNode = NULL; + previousSibling = NULL; + nextSibling = NULL;; + firstChild = NULL; + lastChild = NULL; + + ownerDocument = owner; + length = 0; + +} + +// +// This node is being destroyed, so loop through and destroy all the children. +// Also, destroy all attributes stored in the attributes NamedNodeMap. +// +NodeDefinition::~NodeDefinition() +{ + Int32 numAttributes = attributes.getLength(); + Int32 killAttrLoop; + + DeleteChildren(); + + for (killAttrLoop=0;killAttrLoopgetNodeName()); +} + +// +//Remove and delete all children of this node +// +void NodeDefinition::DeleteChildren() +{ + NodeDefinition* pCurrent = firstChild; + NodeDefinition* pDestroyer; + + while (pCurrent) + { + pDestroyer = pCurrent; + pCurrent = pCurrent->nextSibling; + delete pDestroyer; + } + + length = 0; + firstChild = NULL; + lastChild = NULL; +} + +const DOMString& NodeDefinition::getNodeName() const +{ + return nodeName; +} + +const DOMString& NodeDefinition::getNodeValue() const +{ + return nodeValue; +} + +const DOMString& NodeDefinition::getNodeValue() +{ + return nodeValue; +} + +unsigned short NodeDefinition::getNodeType() const +{ + return nodeType; +} + +Node* NodeDefinition::getParentNode() const +{ + return parentNode; +} + +NodeList* NodeDefinition::getChildNodes() +{ + return this; +} + +Node* NodeDefinition::getFirstChild() const +{ + return firstChild; +} + +Node* NodeDefinition::getLastChild() const +{ + return lastChild; +} + +Node* NodeDefinition::getPreviousSibling() const +{ + return previousSibling; +} + +Node* NodeDefinition::getNextSibling() const +{ + return nextSibling; +} + +NamedNodeMap* NodeDefinition::getAttributes() +{ + return &attributes; +} + +Document* NodeDefinition::getOwnerDocument() const +{ + return ownerDocument; +} + +Node* NodeDefinition::item(Int32 index) +{ + Int32 selectLoop; + NodeDefinition* pSelectNode = firstChild; + + if (index < length) + { + for (selectLoop=0;selectLoopnextSibling; + + return pSelectNode; + } + + return NULL; +} + +Int32 NodeDefinition::getLength() +{ + return length; +} + +void NodeDefinition::setNodeValue(const DOMString& newNodeValue) +{ + nodeValue = newNodeValue; +} + +// +//Insert the "newChild" node before the "refChild" node. Return a pointer to +//the inserted child. If the node to insert is a document fragment, then +//insert each child of the document fragment, and return the document fragment +//which should be empty if all the inserts suceeded. +//This function's responsibility is to check for and handle document fragments +//vs. plain nodes. +// *** NOTE: Need to check the document types before inserting. +// +// The decision to return the possibly empty document fragment +// was an implementation choice. The spec did not dictate what +// whould occur. +// +Node* NodeDefinition::insertBefore(Node* newChild, + Node* refChild) +{ + NodeDefinition* pCurrentNode = NULL; + NodeDefinition* pNextNode = NULL; + + //Convert to a NodeDefinition Pointer + NodeDefinition* pNewChild = (NodeDefinition*)newChild; + NodeDefinition* pRefChild = (NodeDefinition*)refChild; + + //Check to see if the reference node is a child of this node + if ((refChild != NULL) && (pRefChild->parentNode != this)) + return NULL; + + if (pNewChild->getNodeType() == Node::DOCUMENT_FRAGMENT_NODE) + { + pCurrentNode = pNewChild->firstChild; + while (pCurrentNode) + { + pNextNode = pCurrentNode->nextSibling; + pCurrentNode = (NodeDefinition*)pNewChild->removeChild(pCurrentNode); + implInsertBefore(pCurrentNode, pRefChild); + pCurrentNode = pNextNode; + } + return newChild; + } + else + return implInsertBefore(pNewChild, pRefChild); +} + +// +//The code that actually insert one node before another. +// +Node* NodeDefinition::implInsertBefore(NodeDefinition* pNewChild, + NodeDefinition* pRefChild) +{ + //Remove the "newChild" if it is already a child of this node + if (pNewChild->parentNode == this) + pNewChild = (NodeDefinition*)removeChild(pNewChild); + + //The new child should not be a child of any other node + if ((pNewChild->previousSibling == NULL) && + (pNewChild->nextSibling == NULL) && + (pNewChild->parentNode == NULL)) + { + if (pRefChild == NULL) + { + //Append + pNewChild->previousSibling = lastChild; + + if (lastChild) + lastChild->nextSibling = pNewChild; + + lastChild = pNewChild; + } + else + { + //Insert before the reference node + if (pRefChild->previousSibling) + pRefChild->previousSibling->nextSibling = pNewChild; + pNewChild->nextSibling = pRefChild; + pNewChild->previousSibling = pRefChild->previousSibling; + pRefChild->previousSibling = pNewChild; + } + + pNewChild->parentNode = this; + + if (pNewChild->previousSibling == NULL) + firstChild = pNewChild; + + length++; + + return pNewChild; + } + + return NULL; +} + + +// +//Replace "oldChild" with "newChild". Return the replaced node, or NULL +//otherwise. +// *** NOTE: Need to check that the documents match *** +// +Node* NodeDefinition::replaceChild(Node* newChild, + Node* oldChild) +{ + NodeDefinition* pOldChild = (NodeDefinition*)oldChild; + NodeDefinition* pNextSibling = NULL; + + //If the newChild is replacing itself then we don't need to do anything + if (pOldChild == newChild) + return pOldChild; + + //If "oldChild" is a child of this node, remove it from the list. + pOldChild = (NodeDefinition*)removeChild(oldChild); + + //If the removal was successful... Else, return null + if (pOldChild) + { + //Try to insert the new node before the old node's next sibling. If + //successful, just returned the replaced child. If not succesful, + //reinsert the old node, and return NULL. + pNextSibling = pOldChild->nextSibling; + if (!insertBefore(newChild, pNextSibling)) + { + insertBefore(pOldChild, pNextSibling); + pOldChild = NULL; + } + } + + return pOldChild; +} + +// +//Remove the specified "oldChild" from this node's children. First make sure +//the specified node is a child of this node. Return the removed node, NULL +//otherwise. +// +Node* NodeDefinition::removeChild(Node* oldChild) +{ + NodeDefinition* pOldChild = (NodeDefinition*)oldChild; + + //If "oldChild" is a child of this node, adjust pointers to remove it, and + //clear "oldChild"'s sibling and parent pointers. + if (pOldChild->parentNode == this) + { + if (pOldChild != firstChild) + pOldChild->previousSibling->nextSibling = pOldChild->nextSibling; + else + firstChild = pOldChild->nextSibling; + + if (pOldChild != lastChild) + pOldChild->nextSibling->previousSibling = pOldChild->previousSibling; + else + lastChild = pOldChild->previousSibling; + + pOldChild->nextSibling = NULL; + pOldChild->previousSibling = NULL; + pOldChild->parentNode = NULL; + + length--; + + return pOldChild; + } + + return NULL; +} + +// +//Append a new child node. First make sure the new child is not already a +//child of another node. Return the appended node. +// *** NOTE *** Need to eventually check to make sure the documents match *** +// +Node* NodeDefinition::appendChild(Node* newChild) +{ + return insertBefore(newChild, NULL); +} + +Node* NodeDefinition::cloneNode(MBool deep, Node* dest) +{ + return 0; +} + +MBool NodeDefinition::hasChildNodes() const +{ + if (firstChild != NULL) + return MB_TRUE; + else + return MB_FALSE; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/NodeListDefinition.cpp b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/NodeListDefinition.cpp new file mode 100644 index 00000000000..4bb1983ffd1 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/NodeListDefinition.cpp @@ -0,0 +1,117 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the NodeListDefinition class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// + +#include "dom.h" + +// +//Create an empty node list. +// +NodeListDefinition::NodeListDefinition() +{ + firstItem = NULL; + lastItem = NULL; + length = 0; +} + +// +//Free up the memory used by the List of Items. Don't delete the actual nodes +//though. +// +NodeListDefinition::~NodeListDefinition() +{ + ListItem* pDeleteItem; + ListItem* pListTraversal = firstItem; + + while (pListTraversal) + { + pDeleteItem = pListTraversal; + pListTraversal = pListTraversal->next; + delete pDeleteItem; + } +} + +// +//Create a new ListItem, point it to the newNode, and append it to the current +//list of nodes. +// +void NodeListDefinition::append(Node* newNode) +{ + append(*newNode); +} + +void NodeListDefinition::append(Node& newNode) +{ + ListItem* newListItem = new ListItem; + + // Setup the new list item + newListItem->node = &newNode; + newListItem->prev = lastItem; + newListItem->next = NULL; + + //Append the list item + if (lastItem) + lastItem->next = newListItem; + + lastItem = newListItem; + + //Adjust firstItem if this new item is being added to an empty list + if (!firstItem) + firstItem = lastItem; + + //Need to increment the length of the list. Inherited from NodeList + length++; +} + +// +// Return the Node contained in the item specified +// +Node* NodeListDefinition::item(Int32 index) +{ + Int32 selectLoop; + ListItem* pListItem = firstItem; + + if (index < length) + { + for (selectLoop=0;selectLoopnext; + + return pListItem->node; + } + + return NULL; +} + +// +// Return the number of items in the list +// +Int32 NodeListDefinition::getLength() +{ + return length; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/Notation.cpp b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/Notation.cpp new file mode 100644 index 00000000000..8aad385b6c5 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/Notation.cpp @@ -0,0 +1,81 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the Notation class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// + +#include "dom.h" + +// +//Construct a text object with the specified document owner and data +// +Notation::Notation(const DOMString& name, const DOMString& pubID, + const DOMString& sysID) : + NodeDefinition(Node::NOTATION_NODE, name, NULL_STRING, NULL) +{ + publicId = pubID; + systemId = sysID; +} + +// +//Return the Public ID of the Notation +// +const DOMString& Notation::getPublicId() const +{ + return publicId; +} + +//Return the System ID of the Notation +const DOMString& Notation::getSystemId() const +{ + return systemId; +} + +// +//Notation nodes can not have any children, so just return null from all child +//manipulation functions. +// + +Node* Notation::insertBefore(Node* newChild, Node* refChild) +{ + return NULL; +} + +Node* Notation::replaceChild(Node* newChild, Node* oldChild) +{ + return NULL; +} + +Node* Notation::removeChild(Node* oldChild) +{ + return NULL; +} + +Node* Notation::appendChild(Node* newChild) +{ + return NULL; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/ProcessingInstruction.cpp b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/ProcessingInstruction.cpp new file mode 100644 index 00000000000..ffc8e56f001 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/ProcessingInstruction.cpp @@ -0,0 +1,93 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the ProcessingInstruction class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// + +#include "dom.h" + +// +//Construct a text object with the specified document owner and data +// +ProcessingInstruction::ProcessingInstruction(const DOMString& theTarget, + const DOMString& theData, + Document* owner) : + NodeDefinition(Node::PROCESSING_INSTRUCTION_NODE, + theTarget, theData, owner) +{ +} + +// +//Return the Target of the processing instruction. This is simply the +//nodeName. +// +const DOMString& ProcessingInstruction::getTarget() const +{ + return nodeName; +} + +// +//Return the Data of the processing instruction. This is simply the value +//of the node, "nodeValue" +// +const DOMString& ProcessingInstruction::getData() const +{ + return nodeValue; +} + +// +//Set the Data element of the processing instruction. +void ProcessingInstruction::setData(const DOMString& theData) +{ + nodeValue = theData; +} + + +// +//ProcessingInstruction nodes can not have any children, so just return null +//from all child manipulation functions. +// + +Node* ProcessingInstruction::insertBefore(Node* newChild, Node* refChild) +{ + return NULL; +} + +Node* ProcessingInstruction::replaceChild(Node* newChild, Node* oldChild) +{ + return NULL; +} + +Node* ProcessingInstruction::removeChild(Node* oldChild) +{ + return NULL; +} + +Node* ProcessingInstruction::appendChild(Node* newChild) +{ + return NULL; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/Text.cpp b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/Text.cpp new file mode 100644 index 00000000000..71492901491 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/Text.cpp @@ -0,0 +1,93 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ +// Tom Kneeland (3/29/99) +// +// Implementation of the Document Object Model Level 1 Core +// Implementation of the Text class +// +// Modification History: +// Who When What +// TK 03/29/99 Created +// + +#include "dom.h" + +// +//Construct a text object with the specified document owner and data +// +Text::Text(const DOMString& theData, Document* owner) : + CharacterData(Node::TEXT_NODE, "#text", theData, owner) +{ +} + +// +//Protected constructor for children of the Text Class. Currently only +//CDATASection needs to use this function. +Text::Text(NodeType type, const DOMString& name, const DOMString& value, + Document* owner) : + CharacterData(type, name, value, owner) +{ +} + + +// +//Split the text node at Offset into two siblings. Return a pointer to the new +//sibling. +// +Text* Text::splitText(Int32 offset) +{ + Text* newTextSibling = NULL; + DOMString newData; + + if ((offset >= 0) && (offset < nodeValue.length())) + { + newTextSibling = getOwnerDocument()->createTextNode(nodeValue.subString(offset, newData)); + getParentNode()->insertBefore(newTextSibling, getNextSibling()); + nodeValue.deleteChars(offset, nodeValue.length() - offset); + } + + return newTextSibling; +} + +// +//Text nodes can not have any children, so just return null from all child +//manipulation functions. +// + +Node* Text::insertBefore(Node* newChild, Node* refChild) +{ + return NULL; +} + +Node* Text::replaceChild(Node* newChild, Node* oldChild) +{ + return NULL; +} + +Node* Text::removeChild(Node* oldChild) +{ + return NULL; +} + +Node* Text::appendChild(Node* newChild) +{ + return NULL; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/makefile.win b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/makefile.win new file mode 100644 index 00000000000..efd165843a8 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/makefile.win @@ -0,0 +1,80 @@ +#!nmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH=..\..\..\..\..\..\.. + +LIBRARY_NAME=transformix_xml_dom_mozImpl +MODULE=transformix +REQUIRES=xpcom raptor + +CPPSRCS= \ + Attr.cpp \ + CDATASection.cpp \ + CharacterData.cpp \ + Comment.cpp \ + Document.cpp \ + DocumentFragment.cpp \ + DocumentType.cpp \ + DOMImplementation.cpp \ + Element.cpp \ + Entity.cpp \ + EntityReference.cpp \ + NamedNodeMap.cpp \ + NodeDefinition.cpp \ + NodeListDefinition.cpp \ + Notation.cpp \ + ProcessingInstruction.cpp \ + Text.cpp \ + $(NULL) + +CPP_OBJS= \ + .\$(OBJDIR)\Attr.obj \ + .\$(OBJDIR)\CDATASection.obj \ + .\$(OBJDIR)\CharacterData.obj \ + .\$(OBJDIR)\Comment.obj \ + .\$(OBJDIR)\Document.obj \ + .\$(OBJDIR)\DocumentFragment.obj \ + .\$(OBJDIR)\DocumentType.obj \ + .\$(OBJDIR)\DOMImplementation.obj \ + .\$(OBJDIR)\Element.obj \ + .\$(OBJDIR)\Entity.obj \ + .\$(OBJDIR)\EntityReference.obj \ + .\$(OBJDIR)\NamedNodeMap.obj \ + .\$(OBJDIR)\NodeDefinition.obj \ + .\$(OBJDIR)\NodeListDefinition.obj \ + .\$(OBJDIR)\Notation.obj \ + .\$(OBJDIR)\ProcessingInstruction.obj \ + .\$(OBJDIR)\Text.obj \ + $(NULL) + +EXPORTS = \ + $(NULL) + +LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor -I..\..\..\base -I..\..\dom + +LCFLAGS = \ + $(LCFLAGS) \ + $(DEFINES) \ + $(NULL) + +include <$(DEPTH)\config\rules.mak> + +libs:: $(LIBRARY) + $(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib + +clobber:: + rm -f $(DIST)\lib\$(LIBRARY_NAME).lib diff --git a/mozilla/extensions/transformiix/source/xml/makefile.win b/mozilla/extensions/transformiix/source/xml/makefile.win new file mode 100644 index 00000000000..7c89a32846e --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/makefile.win @@ -0,0 +1,52 @@ +#!nmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH=..\..\..\..\.. + +DIRS=dom + +LIBRARY_NAME=transformix_xml +MODULE=transformix +REQUIRES=xpcom raptor + +CPPSRCS= \ + XMLDOMUtils.cpp \ + XMLUtils.cpp \ + $(NULL) + +CPP_OBJS= \ + .\$(OBJDIR)\XMLDOMUtils.obj \ + .\$(OBJDIR)\XMLUtils.obj \ + $(NULL) + +EXPORTS = \ + $(NULL) + +LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor -I..\base -Idom + +LCFLAGS = \ + $(LCFLAGS) \ + $(DEFINES) \ + $(NULL) + +include <$(DEPTH)\config\rules.mak> + +libs:: $(LIBRARY) + $(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib + +clobber:: + rm -f $(DIST)\lib\$(LIBRARY_NAME).lib diff --git a/mozilla/extensions/transformiix/source/xml/parser/Makefile b/mozilla/extensions/transformiix/source/xml/parser/Makefile new file mode 100644 index 00000000000..c7c11b54a3f --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/Makefile @@ -0,0 +1,57 @@ +target: xml_parser + + +BASE_PATH = ../../base +DOM_PATH = ../dom +PARSER_PATH = . + +EXPAT_PARSER_PATH = xmlparse +EXPAT_TOKEN_PATH = xmltok + +INCLUDE_PATH = -I $(PARSER_PATH) -I $(BASE_PATH) -I $(DOM_PATH) \ + -I $(EXPAT_TOKEN_PATH) -I $(EXPAT_PARSER_PATH) -I- + +BASE_OBJS = $(BASE_PATH)/String.o + +DOM_OBJS = $(DOM_PATH)/NodeDefinition.o \ + $(DOM_PATH)/Document.o \ + $(DOM_PATH)/DocumentFragment.o \ + $(DOM_PATH)/NamedNodeMap.o \ + $(DOM_PATH)/NodeListDefinition.o \ + $(DOM_PATH)/Element.o \ + $(DOM_PATH)/Attr.o \ + $(DOM_PATH)/CharacterData.o \ + $(DOM_PATH)/Text.o \ + $(DOM_PATH)/Comment.o \ + $(DOM_PATH)/CDATASection.o \ + $(DOM_PATH)/ProcessingInstruction.o \ + $(DOM_PATH)/Notation.o \ + $(DOM_PATH)/Entity.o $(DOM_PATH)EntityReference.o \ + $(DOM_PATH)/DocumentType.o \ + $(DOM_PATH)/DOMImplementation.o + +EXPAT_OBJS = $(EXPAT_TOKEN_PATH)/xmltok.o \ + $(EXPAT_TOKEN_PATH)/xmlrole.o \ + $(EXPAT_PARSER_PATH)/xmlparse.o \ + $(EXPAT_PARSER_PATH)/hashtable.o + +PARSER_OBJS = $(PARSER_PATH)/XMLParser.o + +ALL_OBJS = $(BASE_OBJS) $(DOM_OBJS) $(EXPAT_OBJS) $(PARSER_OBJS) + + +CC = g++ -D XML_UNICODE -D __cplusplus + +xml_parser: $(ALL_OBJS) + +XMLParser.o: XMLParser.h XMLParser.cpp + $(CC) $(INCLUDE_PATH) -c XMLParser.cpp + +$(EXPAT_OBJS): + make -f expat.mk + +$(DOM_OBJS): + cd $(DOM_PATH); make + +$(BASE_OBJS): + cd $(BASE_PATH); make diff --git a/mozilla/extensions/transformiix/source/xml/parser/XMLParser.cpp b/mozilla/extensions/transformiix/source/xml/parser/XMLParser.cpp new file mode 100644 index 00000000000..22b1e776199 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/XMLParser.cpp @@ -0,0 +1,154 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The program is provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + */ + +#include "xmlparser.h" + +/** + * Implementation of an In-Memory DOM based XML parser. The actual XML + * parsing is provided by EXPAT. + * + * @author Tom Kneeland + * @author Keith Visco + * + * Modification History: + * Who When What + * TK 05/03/99 Created + * KV 06/15/1999 Fixed bug in parse method which read from cin instead of + * the istream parameter. + * KV 06/15/1999 Changed #parse method to return a Document + * KV 06/17/1999 made a bunch of changes + * +**/ + +/** + * Creates a new XMLParser +**/ +XMLParser::XMLParser() +{ + errorState = MB_FALSE; +} //-- XMLParser + + +XMLParser::~XMLParser() +{ + //-- clean up +} //-- ~XMLParser + + /** + * Parses the given input stream and returns a DOM Document. + * A NULL pointer will be returned if errors occurred + **/ +Document* XMLParser::parse(istream& inputStream) +{ + const int bufferSize = 1000; + + char buf[bufferSize]; + int done; + errorState = MB_FALSE; + errorString.clear(); + if ( !inputStream ) { + errorString.append("unable to parse xml, invalid or unopen stream"); + return NULL; + } + XML_Parser parser = XML_ParserCreate(NULL); + ParserState ps; + ps.document = new Document(); + ps.currentNode = ps.document; + + XML_SetUserData(parser, &ps); + XML_SetElementHandler(parser, startElement, endElement); + XML_SetCharacterDataHandler(parser, charData); + XML_SetProcessingInstructionHandler(parser, piHandler); + do + { + inputStream.read(buf, bufferSize); + done = inputStream.eof(); + + if (!XML_Parse(parser, buf, inputStream.gcount(), done)) + { + errorString.append(XML_ErrorString(XML_GetErrorCode(parser))); + errorString.append(" at line "); + errorString.append(XML_GetCurrentLineNumber(parser)); + done = true; + errorState = MB_TRUE; + delete ps.document; + ps.document = NULL; + } + } while (!done); + inputStream.clear(); + + //if (currentElement) + //theDocument->appendChild(currentElement); + + // clean up + XML_ParserFree(parser); + + return ps.document; +} + +const DOMString& XMLParser::getErrorString() +{ + return errorString; +} + +void startElement(void *userData, const XML_Char *name, const XML_Char **atts) +{ + ParserState* ps = (ParserState*)userData; + Element* newElement; + Attr* newAttribute; + DOM_CHAR* attName; + DOM_CHAR* attValue; + XML_Char** theAtts = (XML_Char**)atts; + + newElement = ps->document->createElement((DOM_CHAR*) name); + + while (*theAtts) + { + attName = (DOM_CHAR*)*theAtts++; + attValue = (DOM_CHAR*)*theAtts++; + newElement->setAttribute(attName, attValue); + } + + ps->currentNode->appendChild(newElement); + ps->currentNode = newElement; + +} //-- startElement + +void endElement(void *userData, const XML_Char* name) +{ + ParserState* ps = (ParserState*)userData; + if (ps->currentNode->getParentNode()) + ps->currentNode = ps->currentNode->getParentNode(); +} //-- endElement + +void charData(void* userData, const XML_Char* s, int len) +{ + ParserState* ps = (ParserState*)userData; + DOMString data; + data.append((const DOM_CHAR*)s, len); + ps->currentNode->appendChild(ps->document->createTextNode(data)); +} //-- charData + +/** + * Handles ProcessingInstructions +**/ +void piHandler(void *userData, const XML_Char *target, const XML_Char *data) { + ParserState* ps = (ParserState*)userData; + DOMString targetStr((const DOM_CHAR*) target); + DOMString dataStr((const DOM_CHAR*) data); + + ps->currentNode->appendChild( + ps->document->createProcessingInstruction(targetStr, dataStr)); + +} //-- piHandler + diff --git a/mozilla/extensions/transformiix/source/xml/parser/XMLParser.h b/mozilla/extensions/transformiix/source/xml/parser/XMLParser.h new file mode 100644 index 00000000000..4acbe69d4ef --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/XMLParser.h @@ -0,0 +1,71 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The program is provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + */ + +#include +#include "baseutils.h" +#include "xmlparse.h" +#include "DOM.h" + +typedef struct { + Document* document; + Node* currentNode; +} ParserState; + +/** + * Implementation of an In-Memory DOM based XML parser. The actual XML + * parsing is provided by EXPAT. + * + * @author Tom Kneeland + * @author Keith Visco + * + * Modification History: + * Who When What + * TK 05/03/99 Created + * KV 06/15/1999 Changed #parse method to return document + * KV 06/17/1999 Made many changes + * +**/ +class XMLParser +{ + /*-----------------6/18/99 12:43PM------------------ + * Sax related methods for XML parsers + * --------------------------------------------------*/ + friend void charData(void* userData, const XML_Char* s, int len); + friend void startElement(void *userData, const XML_Char* name, + const XML_Char** atts); + friend void endElement(void *userData, const XML_Char* name); + + friend void piHandler(void *userData, const XML_Char *target, const XML_Char *data); + + public: + XMLParser(); + ~XMLParser(); + + Document* parse(istream& inputStream); + const DOMString& getErrorString(); + + protected: + + Document* theDocument; + Element* currentElement; + MBool errorState; + DOMString errorString; +}; + +/*-----------------6/18/99 12:43PM------------------ + * Sax related methods for XML parsers + * --------------------------------------------------*/ +void charData(void* userData, const XML_Char* s, int len); +void startElement(void *userData, const XML_Char* name, const XML_Char** atts); +void endElement(void *userData, const XML_Char* name); +void piHandler(void *userData, const XML_Char *target, const XML_Char *data); diff --git a/mozilla/extensions/transformiix/source/xml/parser/expat.mk b/mozilla/extensions/transformiix/source/xml/parser/expat.mk new file mode 100644 index 00000000000..b69d55cefae --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/expat.mk @@ -0,0 +1,25 @@ +EXPAT_PARSER_PATH = xmlparse +EXPAT_TOKEN_PATH = xmltok + +EXPAT_OBJS = $(EXPAT_TOKEN_PATH)/xmltok.o \ + $(EXPAT_TOKEN_PATH)/xmlrole.o \ + $(EXPAT_PARSER_PATH)/xmlparse.o \ + $(EXPAT_PARSER_PATH)/hashtable.o + + +INCLUDE_PATH = -I . -I $(EXPAT_PARSER_PATH) -I $(EXPAT_TOKEN_PATH) -I- + +FLAGS = -D XML_UNICODE +CC = gcc $(FLAGS) $(INCLUDE_PATH) + +target: $(EXPAT_OBJS) + + +xmltok.o xmlrole.o: + cd $(EXPAT_TOKEN_PATH); \ + $(CC) -c xmltok.c xmlrole.c + + +xmlparse.o hashtable.o: + cd $(EXPAT_PARSER_PATH); \ + $(CC) -c xmlparse.c hashtable.c diff --git a/mozilla/extensions/transformiix/source/xml/parser/xmlparse/hashtable.c b/mozilla/extensions/transformiix/source/xml/parser/xmlparse/hashtable.c new file mode 100644 index 00000000000..2876975bd2b --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/xmlparse/hashtable.c @@ -0,0 +1,134 @@ +/* +The contents of this file are subject to the Mozilla Public License +Version 1.0 (the "License"); you may not use this file except in +csompliance with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" +basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific language governing rights and limitations +under the License. + +The Original Code is expat. + +The Initial Developer of the Original Code is James Clark. +Portions created by James Clark are Copyright (C) 1998 +James Clark. All Rights Reserved. + +Contributor(s): +*/ + +#include +#include + +#include "xmldef.h" +#include "hashtable.h" + +#ifdef XML_UNICODE +#define keycmp wcscmp +#else +#define keycmp strcmp +#endif + +#define INIT_SIZE 64 + +static +unsigned long hash(KEY s) +{ + unsigned long h = 0; + while (*s) + h = (h << 5) + h + (unsigned char)*s++; + return h; +} + +NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize) +{ + size_t i; + if (table->size == 0) { + if (!createSize) + return 0; + table->v = calloc(INIT_SIZE, sizeof(NAMED *)); + if (!table->v) + return 0; + table->size = INIT_SIZE; + table->usedLim = INIT_SIZE / 2; + i = hash(name) & (table->size - 1); + } + else { + unsigned long h = hash(name); + for (i = h & (table->size - 1); + table->v[i]; + i == 0 ? i = table->size - 1 : --i) { + if (keycmp(name, table->v[i]->name) == 0) + return table->v[i]; + } + if (!createSize) + return 0; + if (table->used == table->usedLim) { + /* check for overflow */ + size_t newSize = table->size * 2; + NAMED **newV = calloc(newSize, sizeof(NAMED *)); + if (!newV) + return 0; + for (i = 0; i < table->size; i++) + if (table->v[i]) { + size_t j; + for (j = hash(table->v[i]->name) & (newSize - 1); + newV[j]; + j == 0 ? j = newSize - 1 : --j) + ; + newV[j] = table->v[i]; + } + free(table->v); + table->v = newV; + table->size = newSize; + table->usedLim = newSize/2; + for (i = h & (table->size - 1); + table->v[i]; + i == 0 ? i = table->size - 1 : --i) + ; + } + } + table->v[i] = calloc(1, createSize); + if (!table->v[i]) + return 0; + table->v[i]->name = name; + (table->used)++; + return table->v[i]; +} + +void hashTableDestroy(HASH_TABLE *table) +{ + size_t i; + for (i = 0; i < table->size; i++) { + NAMED *p = table->v[i]; + if (p) + free(p); + } + free(table->v); +} + +void hashTableInit(HASH_TABLE *p) +{ + p->size = 0; + p->usedLim = 0; + p->used = 0; + p->v = 0; +} + +void hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) +{ + iter->p = table->v; + iter->end = iter->p + table->size; +} + +NAMED *hashTableIterNext(HASH_TABLE_ITER *iter) +{ + while (iter->p != iter->end) { + NAMED *tem = *(iter->p)++; + if (tem) + return tem; + } + return 0; +} + diff --git a/mozilla/extensions/transformiix/source/xml/parser/xmlparse/hashtable.h b/mozilla/extensions/transformiix/source/xml/parser/xmlparse/hashtable.h new file mode 100644 index 00000000000..d10e591c7ff --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/xmlparse/hashtable.h @@ -0,0 +1,51 @@ +/* +The contents of this file are subject to the Mozilla Public License +Version 1.0 (the "License"); you may not use this file except in +compliance with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" +basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific language governing rights and limitations +under the License. + +The Original Code is expat. + +The Initial Developer of the Original Code is James Clark. +Portions created by James Clark are Copyright (C) 1998 +James Clark. All Rights Reserved. + +Contributor(s): +*/ + + +#include + +#ifdef XML_UNICODE +typedef const wchar_t *KEY; +#else +typedef const char *KEY; +#endif + +typedef struct { + KEY name; +} NAMED; + +typedef struct { + NAMED **v; + size_t size; + size_t used; + size_t usedLim; +} HASH_TABLE; + +NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize); +void hashTableInit(HASH_TABLE *); +void hashTableDestroy(HASH_TABLE *); + +typedef struct { + NAMED **p; + NAMED **end; +} HASH_TABLE_ITER; + +void hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *); +NAMED *hashTableIterNext(HASH_TABLE_ITER *); diff --git a/mozilla/extensions/transformiix/source/xml/parser/xmlparse/xmlparse.c b/mozilla/extensions/transformiix/source/xml/parser/xmlparse/xmlparse.c new file mode 100644 index 00000000000..f11f62c0e30 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/xmlparse/xmlparse.c @@ -0,0 +1,2577 @@ +/* +The contents of this file are subject to the Mozilla Public License +Version 1.0 (the "License"); you may not use this file except in +compliance with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" +basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific language governing rights and limitations +under the License. + +The Original Code is expat. + +The Initial Developer of the Original Code is James Clark. +Portions created by James Clark are Copyright (C) 1998 +James Clark. All Rights Reserved. + +Contributor(s): +*/ + +#include +#include +#include + +#include "xmldef.h" + +#ifdef XML_UNICODE +#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX +#define XmlConvert XmlUtf16Convert +#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding +#define XmlEncode XmlUtf16Encode +#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1)) +typedef unsigned short ICHAR; +#else +#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX +#define XmlConvert XmlUtf8Convert +#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding +#define XmlEncode XmlUtf8Encode +#define MUST_CONVERT(enc, s) (!(enc)->isUtf8) +typedef char ICHAR; +#endif + +#ifdef XML_UNICODE_WCHAR_T +#define XML_T(x) L ## x +#else +#define XML_T(x) x +#endif + +/* Round up n to be a multiple of sz, where sz is a power of 2. */ +#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1)) + +#include "xmlparse.h" +#include "xmltok.h" +#include "xmlrole.h" +#include "hashtable.h" + +#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */ +#define INIT_DATA_BUF_SIZE 1024 +#define INIT_ATTS_SIZE 16 +#define INIT_BLOCK_SIZE 1024 +#define INIT_BUFFER_SIZE 1024 + +typedef struct tag { + struct tag *parent; + const char *rawName; + int rawNameLength; + const XML_Char *name; + char *buf; + char *bufEnd; +} TAG; + +typedef struct { + const XML_Char *name; + const XML_Char *textPtr; + int textLen; + const XML_Char *systemId; + const XML_Char *base; + const XML_Char *publicId; + const XML_Char *notation; + char open; +} ENTITY; + +typedef struct block { + struct block *next; + int size; + XML_Char s[1]; +} BLOCK; + +typedef struct { + BLOCK *blocks; + BLOCK *freeBlocks; + const XML_Char *end; + XML_Char *ptr; + XML_Char *start; +} STRING_POOL; + +/* The XML_Char before the name is used to determine whether +an attribute has been specified. */ +typedef struct { + XML_Char *name; + char maybeTokenized; +} ATTRIBUTE_ID; + +typedef struct { + const ATTRIBUTE_ID *id; + char isCdata; + const XML_Char *value; +} DEFAULT_ATTRIBUTE; + +typedef struct { + const XML_Char *name; + int nDefaultAtts; + int allocDefaultAtts; + DEFAULT_ATTRIBUTE *defaultAtts; +} ELEMENT_TYPE; + +typedef struct { + HASH_TABLE generalEntities; + HASH_TABLE elementTypes; + HASH_TABLE attributeIds; + STRING_POOL pool; + int complete; + int standalone; + const XML_Char *base; +} DTD; + +typedef enum XML_Error Processor(XML_Parser parser, + const char *start, + const char *end, + const char **endPtr); + +static Processor prologProcessor; +static Processor prologInitProcessor; +static Processor contentProcessor; +static Processor cdataSectionProcessor; +static Processor epilogProcessor; +static Processor errorProcessor; +static Processor externalEntityInitProcessor; +static Processor externalEntityInitProcessor2; +static Processor externalEntityInitProcessor3; +static Processor externalEntityContentProcessor; + +static enum XML_Error +handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName); +static enum XML_Error +processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *, const char *); +static enum XML_Error +initializeEncoding(XML_Parser parser); +static enum XML_Error +doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, + const char *start, const char *end, const char **endPtr); +static enum XML_Error +doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr); +static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, const XML_Char *tagName, const char *s); +static int +defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, int isCdata, const XML_Char *dfltValue); +static enum XML_Error +storeAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *, + STRING_POOL *); +static enum XML_Error +appendAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *, + STRING_POOL *); +static ATTRIBUTE_ID * +getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); +static enum XML_Error +storeEntityValue(XML_Parser parser, const char *start, const char *end); +static int +reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); +static void +reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); + +static const XML_Char *getOpenEntityNames(XML_Parser parser); +static int setOpenEntityNames(XML_Parser parser, const XML_Char *openEntityNames); +static void normalizePublicId(XML_Char *s); +static int dtdInit(DTD *); +static void dtdDestroy(DTD *); +static int dtdCopy(DTD *newDtd, const DTD *oldDtd); +static void poolInit(STRING_POOL *); +static void poolClear(STRING_POOL *); +static void poolDestroy(STRING_POOL *); +static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc, + const char *ptr, const char *end); +static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc, + const char *ptr, const char *end); +static int poolGrow(STRING_POOL *pool); +static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s); +static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n); + +#define poolStart(pool) ((pool)->start) +#define poolEnd(pool) ((pool)->ptr) +#define poolLength(pool) ((pool)->ptr - (pool)->start) +#define poolChop(pool) ((void)--(pool->ptr)) +#define poolLastChar(pool) (((pool)->ptr)[-1]) +#define poolDiscard(pool) ((pool)->ptr = (pool)->start) +#define poolFinish(pool) ((pool)->start = (pool)->ptr) +#define poolAppendChar(pool, c) \ + (((pool)->ptr == (pool)->end && !poolGrow(pool)) \ + ? 0 \ + : ((*((pool)->ptr)++ = c), 1)) + +typedef struct { + /* The first member must be userData so that the XML_GetUserData macro works. */ + void *userData; + void *handlerArg; + char *buffer; + /* first character to be parsed */ + const char *bufferPtr; + /* past last character to be parsed */ + char *bufferEnd; + /* allocated end of buffer */ + const char *bufferLim; + long parseEndByteIndex; + const char *parseEndPtr; + XML_Char *dataBuf; + XML_Char *dataBufEnd; + XML_StartElementHandler startElementHandler; + XML_EndElementHandler endElementHandler; + XML_CharacterDataHandler characterDataHandler; + XML_ProcessingInstructionHandler processingInstructionHandler; + XML_DefaultHandler defaultHandler; + XML_UnparsedEntityDeclHandler unparsedEntityDeclHandler; + XML_NotationDeclHandler notationDeclHandler; + XML_ExternalEntityRefHandler externalEntityRefHandler; + XML_UnknownEncodingHandler unknownEncodingHandler; + const ENCODING *encoding; + INIT_ENCODING initEncoding; + const XML_Char *protocolEncodingName; + void *unknownEncodingMem; + void *unknownEncodingData; + void *unknownEncodingHandlerData; + void (*unknownEncodingRelease)(void *); + PROLOG_STATE prologState; + Processor *processor; + enum XML_Error errorCode; + const char *eventPtr; + const char *eventEndPtr; + const char *positionPtr; + int tagLevel; + ENTITY *declEntity; + const XML_Char *declNotationName; + const XML_Char *declNotationPublicId; + ELEMENT_TYPE *declElementType; + ATTRIBUTE_ID *declAttributeId; + char declAttributeIsCdata; + DTD dtd; + TAG *tagStack; + TAG *freeTagList; + int attsSize; + ATTRIBUTE *atts; + POSITION position; + STRING_POOL tempPool; + STRING_POOL temp2Pool; + char *groupConnector; + unsigned groupSize; + int hadExternalDoctype; +} Parser; + +#define userData (((Parser *)parser)->userData) +#define handlerArg (((Parser *)parser)->handlerArg) +#define startElementHandler (((Parser *)parser)->startElementHandler) +#define endElementHandler (((Parser *)parser)->endElementHandler) +#define characterDataHandler (((Parser *)parser)->characterDataHandler) +#define processingInstructionHandler (((Parser *)parser)->processingInstructionHandler) +#define defaultHandler (((Parser *)parser)->defaultHandler) +#define unparsedEntityDeclHandler (((Parser *)parser)->unparsedEntityDeclHandler) +#define notationDeclHandler (((Parser *)parser)->notationDeclHandler) +#define externalEntityRefHandler (((Parser *)parser)->externalEntityRefHandler) +#define unknownEncodingHandler (((Parser *)parser)->unknownEncodingHandler) +#define encoding (((Parser *)parser)->encoding) +#define initEncoding (((Parser *)parser)->initEncoding) +#define unknownEncodingMem (((Parser *)parser)->unknownEncodingMem) +#define unknownEncodingData (((Parser *)parser)->unknownEncodingData) +#define unknownEncodingHandlerData \ + (((Parser *)parser)->unknownEncodingHandlerData) +#define unknownEncodingRelease (((Parser *)parser)->unknownEncodingRelease) +#define protocolEncodingName (((Parser *)parser)->protocolEncodingName) +#define prologState (((Parser *)parser)->prologState) +#define processor (((Parser *)parser)->processor) +#define errorCode (((Parser *)parser)->errorCode) +#define eventPtr (((Parser *)parser)->eventPtr) +#define eventEndPtr (((Parser *)parser)->eventEndPtr) +#define positionPtr (((Parser *)parser)->positionPtr) +#define position (((Parser *)parser)->position) +#define tagLevel (((Parser *)parser)->tagLevel) +#define buffer (((Parser *)parser)->buffer) +#define bufferPtr (((Parser *)parser)->bufferPtr) +#define bufferEnd (((Parser *)parser)->bufferEnd) +#define parseEndByteIndex (((Parser *)parser)->parseEndByteIndex) +#define parseEndPtr (((Parser *)parser)->parseEndPtr) +#define bufferLim (((Parser *)parser)->bufferLim) +#define dataBuf (((Parser *)parser)->dataBuf) +#define dataBufEnd (((Parser *)parser)->dataBufEnd) +#define dtd (((Parser *)parser)->dtd) +#define declEntity (((Parser *)parser)->declEntity) +#define declNotationName (((Parser *)parser)->declNotationName) +#define declNotationPublicId (((Parser *)parser)->declNotationPublicId) +#define declElementType (((Parser *)parser)->declElementType) +#define declAttributeId (((Parser *)parser)->declAttributeId) +#define declAttributeIsCdata (((Parser *)parser)->declAttributeIsCdata) +#define freeTagList (((Parser *)parser)->freeTagList) +#define tagStack (((Parser *)parser)->tagStack) +#define atts (((Parser *)parser)->atts) +#define attsSize (((Parser *)parser)->attsSize) +#define tempPool (((Parser *)parser)->tempPool) +#define temp2Pool (((Parser *)parser)->temp2Pool) +#define groupConnector (((Parser *)parser)->groupConnector) +#define groupSize (((Parser *)parser)->groupSize) +#define hadExternalDoctype (((Parser *)parser)->hadExternalDoctype) + +XML_Parser XML_ParserCreate(const XML_Char *encodingName) +{ + XML_Parser parser = malloc(sizeof(Parser)); + if (!parser) + return parser; + processor = prologInitProcessor; + XmlPrologStateInit(&prologState); + userData = 0; + handlerArg = 0; + startElementHandler = 0; + endElementHandler = 0; + characterDataHandler = 0; + processingInstructionHandler = 0; + defaultHandler = 0; + unparsedEntityDeclHandler = 0; + notationDeclHandler = 0; + externalEntityRefHandler = 0; + unknownEncodingHandler = 0; + buffer = 0; + bufferPtr = 0; + bufferEnd = 0; + parseEndByteIndex = 0; + parseEndPtr = 0; + bufferLim = 0; + declElementType = 0; + declAttributeId = 0; + declEntity = 0; + declNotationName = 0; + declNotationPublicId = 0; + memset(&position, 0, sizeof(POSITION)); + errorCode = XML_ERROR_NONE; + eventPtr = 0; + eventEndPtr = 0; + positionPtr = 0; + tagLevel = 0; + tagStack = 0; + freeTagList = 0; + attsSize = INIT_ATTS_SIZE; + atts = malloc(attsSize * sizeof(ATTRIBUTE)); + dataBuf = malloc(INIT_DATA_BUF_SIZE * sizeof(XML_Char)); + groupSize = 0; + groupConnector = 0; + hadExternalDoctype = 0; + unknownEncodingMem = 0; + unknownEncodingRelease = 0; + unknownEncodingData = 0; + unknownEncodingHandlerData = 0; + poolInit(&tempPool); + poolInit(&temp2Pool); + protocolEncodingName = encodingName ? poolCopyString(&tempPool, encodingName) : 0; + if (!dtdInit(&dtd) || !atts || !dataBuf + || (encodingName && !protocolEncodingName)) { + XML_ParserFree(parser); + return 0; + } + dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE; + XmlInitEncoding(&initEncoding, &encoding, 0); + return parser; +} + +XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser, + const XML_Char *openEntityNames, + const XML_Char *encodingName) +{ + XML_Parser parser = oldParser; + DTD *oldDtd = &dtd; + XML_StartElementHandler oldStartElementHandler = startElementHandler; + XML_EndElementHandler oldEndElementHandler = endElementHandler; + XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler; + XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler; + XML_DefaultHandler oldDefaultHandler = defaultHandler; + XML_ExternalEntityRefHandler oldExternalEntityRefHandler = externalEntityRefHandler; + XML_UnknownEncodingHandler oldUnknownEncodingHandler = unknownEncodingHandler; + void *oldUserData = userData; + void *oldHandlerArg = handlerArg; + + parser = XML_ParserCreate(encodingName); + if (!parser) + return 0; + startElementHandler = oldStartElementHandler; + endElementHandler = oldEndElementHandler; + characterDataHandler = oldCharacterDataHandler; + processingInstructionHandler = oldProcessingInstructionHandler; + defaultHandler = oldDefaultHandler; + externalEntityRefHandler = oldExternalEntityRefHandler; + unknownEncodingHandler = oldUnknownEncodingHandler; + userData = oldUserData; + if (oldUserData == oldHandlerArg) + handlerArg = userData; + else + handlerArg = parser; + if (!dtdCopy(&dtd, oldDtd) || !setOpenEntityNames(parser, openEntityNames)) { + XML_ParserFree(parser); + return 0; + } + processor = externalEntityInitProcessor; + return parser; +} + +void XML_ParserFree(XML_Parser parser) +{ + for (;;) { + TAG *p; + if (tagStack == 0) { + if (freeTagList == 0) + break; + tagStack = freeTagList; + freeTagList = 0; + } + p = tagStack; + tagStack = tagStack->parent; + free(p->buf); + free(p); + } + poolDestroy(&tempPool); + poolDestroy(&temp2Pool); + dtdDestroy(&dtd); + free((void *)atts); + free(groupConnector); + free(buffer); + free(dataBuf); + free(unknownEncodingMem); + if (unknownEncodingRelease) + unknownEncodingRelease(unknownEncodingData); + free(parser); +} + +void XML_UseParserAsHandlerArg(XML_Parser parser) +{ + handlerArg = parser; +} + +void XML_SetUserData(XML_Parser parser, void *p) +{ + if (handlerArg == userData) + handlerArg = userData = p; + else + userData = p; +} + +int XML_SetBase(XML_Parser parser, const XML_Char *p) +{ + if (p) { + p = poolCopyString(&dtd.pool, p); + if (!p) + return 0; + dtd.base = p; + } + else + dtd.base = 0; + return 1; +} + +const XML_Char *XML_GetBase(XML_Parser parser) +{ + return dtd.base; +} + +void XML_SetElementHandler(XML_Parser parser, + XML_StartElementHandler start, + XML_EndElementHandler end) +{ + startElementHandler = start; + endElementHandler = end; +} + +void XML_SetCharacterDataHandler(XML_Parser parser, + XML_CharacterDataHandler handler) +{ + characterDataHandler = handler; +} + +void XML_SetProcessingInstructionHandler(XML_Parser parser, + XML_ProcessingInstructionHandler handler) +{ + processingInstructionHandler = handler; +} + +void XML_SetDefaultHandler(XML_Parser parser, + XML_DefaultHandler handler) +{ + defaultHandler = handler; +} + +void XML_SetUnparsedEntityDeclHandler(XML_Parser parser, + XML_UnparsedEntityDeclHandler handler) +{ + unparsedEntityDeclHandler = handler; +} + +void XML_SetNotationDeclHandler(XML_Parser parser, + XML_NotationDeclHandler handler) +{ + notationDeclHandler = handler; +} + +void XML_SetExternalEntityRefHandler(XML_Parser parser, + XML_ExternalEntityRefHandler handler) +{ + externalEntityRefHandler = handler; +} + +void XML_SetUnknownEncodingHandler(XML_Parser parser, + XML_UnknownEncodingHandler handler, + void *data) +{ + unknownEncodingHandler = handler; + unknownEncodingHandlerData = data; +} + +int XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) +{ + if (len == 0) { + if (!isFinal) + return 1; + errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0); + if (errorCode == XML_ERROR_NONE) + return 1; + eventEndPtr = eventPtr; + return 0; + } + else if (bufferPtr == bufferEnd) { + const char *end; + int nLeftOver; + parseEndByteIndex += len; + positionPtr = s; + if (isFinal) { + errorCode = processor(parser, s, parseEndPtr = s + len, 0); + if (errorCode == XML_ERROR_NONE) + return 1; + eventEndPtr = eventPtr; + return 0; + } + errorCode = processor(parser, s, parseEndPtr = s + len, &end); + if (errorCode != XML_ERROR_NONE) { + eventEndPtr = eventPtr; + return 0; + } + XmlUpdatePosition(encoding, positionPtr, end, &position); + nLeftOver = s + len - end; + if (nLeftOver) { + if (buffer == 0 || nLeftOver > bufferLim - buffer) { + /* FIXME avoid integer overflow */ + buffer = buffer == 0 ? malloc(len * 2) : realloc(buffer, len * 2); + if (!buffer) { + errorCode = XML_ERROR_NO_MEMORY; + eventPtr = eventEndPtr = 0; + return 0; + } + bufferLim = buffer + len * 2; + } + memcpy(buffer, end, nLeftOver); + bufferPtr = buffer; + bufferEnd = buffer + nLeftOver; + } + return 1; + } + else { + memcpy(XML_GetBuffer(parser, len), s, len); + return XML_ParseBuffer(parser, len, isFinal); + } +} + +int XML_ParseBuffer(XML_Parser parser, int len, int isFinal) +{ + const char *start = bufferPtr; + positionPtr = start; + bufferEnd += len; + parseEndByteIndex += len; + errorCode = processor(parser, start, parseEndPtr = bufferEnd, + isFinal ? (const char **)0 : &bufferPtr); + if (errorCode == XML_ERROR_NONE) { + if (!isFinal) + XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position); + return 1; + } + else { + eventEndPtr = eventPtr; + return 0; + } +} + +void *XML_GetBuffer(XML_Parser parser, int len) +{ + if (len > bufferLim - bufferEnd) { + /* FIXME avoid integer overflow */ + int neededSize = len + (bufferEnd - bufferPtr); + if (neededSize <= bufferLim - buffer) { + memmove(buffer, bufferPtr, bufferEnd - bufferPtr); + bufferEnd = buffer + (bufferEnd - bufferPtr); + bufferPtr = buffer; + } + else { + char *newBuf; + int bufferSize = bufferLim - bufferPtr; + if (bufferSize == 0) + bufferSize = INIT_BUFFER_SIZE; + do { + bufferSize *= 2; + } while (bufferSize < neededSize); + newBuf = malloc(bufferSize); + if (newBuf == 0) { + errorCode = XML_ERROR_NO_MEMORY; + return 0; + } + bufferLim = newBuf + bufferSize; + if (bufferPtr) { + memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr); + free(buffer); + } + bufferEnd = newBuf + (bufferEnd - bufferPtr); + bufferPtr = buffer = newBuf; + } + } + return bufferEnd; +} + +enum XML_Error XML_GetErrorCode(XML_Parser parser) +{ + return errorCode; +} + +long XML_GetCurrentByteIndex(XML_Parser parser) +{ + if (eventPtr) + return parseEndByteIndex - (parseEndPtr - eventPtr); + return -1; +} + +int XML_GetCurrentLineNumber(XML_Parser parser) +{ + if (eventPtr) { + XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); + positionPtr = eventPtr; + } + return position.lineNumber + 1; +} + +int XML_GetCurrentColumnNumber(XML_Parser parser) +{ + if (eventPtr) { + XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); + positionPtr = eventPtr; + } + return position.columnNumber; +} + +void XML_DefaultCurrent(XML_Parser parser) +{ + if (defaultHandler) + reportDefault(parser, encoding, eventPtr, eventEndPtr); +} + +const XML_LChar *XML_ErrorString(int code) +{ + static const XML_LChar *message[] = { + 0, + XML_T("out of memory"), + XML_T("syntax error"), + XML_T("no element found"), + XML_T("not well-formed"), + XML_T("unclosed token"), + XML_T("unclosed token"), + XML_T("mismatched tag"), + XML_T("duplicate attribute"), + XML_T("junk after document element"), + XML_T("illegal parameter entity reference"), + XML_T("undefined entity"), + XML_T("recursive entity reference"), + XML_T("asynchronous entity"), + XML_T("reference to invalid character number"), + XML_T("reference to binary entity"), + XML_T("reference to external entity in attribute"), + XML_T("xml processing instruction not at start of external entity"), + XML_T("unknown encoding"), + XML_T("encoding specified in XML declaration is incorrect"), + XML_T("unclosed CDATA section"), + XML_T("error in processing external entity reference") + }; + if (code > 0 && code < sizeof(message)/sizeof(message[0])) + return message[code]; + return 0; +} + +static +enum XML_Error contentProcessor(XML_Parser parser, + const char *start, + const char *end, + const char **endPtr) +{ + return doContent(parser, 0, encoding, start, end, endPtr); +} + +static +enum XML_Error externalEntityInitProcessor(XML_Parser parser, + const char *start, + const char *end, + const char **endPtr) +{ + enum XML_Error result = initializeEncoding(parser); + if (result != XML_ERROR_NONE) + return result; + processor = externalEntityInitProcessor2; + return externalEntityInitProcessor2(parser, start, end, endPtr); +} + +static +enum XML_Error externalEntityInitProcessor2(XML_Parser parser, + const char *start, + const char *end, + const char **endPtr) +{ + const char *next; + int tok = XmlContentTok(encoding, start, end, &next); + switch (tok) { + case XML_TOK_BOM: + start = next; + break; + case XML_TOK_PARTIAL: + if (endPtr) { + *endPtr = start; + return XML_ERROR_NONE; + } + eventPtr = start; + return XML_ERROR_UNCLOSED_TOKEN; + case XML_TOK_PARTIAL_CHAR: + if (endPtr) { + *endPtr = start; + return XML_ERROR_NONE; + } + eventPtr = start; + return XML_ERROR_PARTIAL_CHAR; + } + processor = externalEntityInitProcessor3; + return externalEntityInitProcessor3(parser, start, end, endPtr); +} + +static +enum XML_Error externalEntityInitProcessor3(XML_Parser parser, + const char *start, + const char *end, + const char **endPtr) +{ + const char *next; + int tok = XmlContentTok(encoding, start, end, &next); + switch (tok) { + case XML_TOK_XML_DECL: + { + enum XML_Error result = processXmlDecl(parser, 1, start, next); + if (result != XML_ERROR_NONE) + return result; + start = next; + } + break; + case XML_TOK_PARTIAL: + if (endPtr) { + *endPtr = start; + return XML_ERROR_NONE; + } + eventPtr = start; + return XML_ERROR_UNCLOSED_TOKEN; + case XML_TOK_PARTIAL_CHAR: + if (endPtr) { + *endPtr = start; + return XML_ERROR_NONE; + } + eventPtr = start; + return XML_ERROR_PARTIAL_CHAR; + } + processor = externalEntityContentProcessor; + tagLevel = 1; + return doContent(parser, 1, encoding, start, end, endPtr); +} + +static +enum XML_Error externalEntityContentProcessor(XML_Parser parser, + const char *start, + const char *end, + const char **endPtr) +{ + return doContent(parser, 1, encoding, start, end, endPtr); +} + +static enum XML_Error +doContent(XML_Parser parser, + int startTagLevel, + const ENCODING *enc, + const char *s, + const char *end, + const char **nextPtr) +{ + const ENCODING *internalEnc = XmlGetInternalEncoding(); + const char *dummy; + const char **eventPP; + const char **eventEndPP; + if (enc == encoding) { + eventPP = &eventPtr; + *eventPP = s; + eventEndPP = &eventEndPtr; + } + else + eventPP = eventEndPP = &dummy; + for (;;) { + const char *next; + int tok = XmlContentTok(enc, s, end, &next); + *eventEndPP = next; + switch (tok) { + case XML_TOK_TRAILING_CR: + if (nextPtr) { + *nextPtr = s; + return XML_ERROR_NONE; + } + *eventEndPP = end; + if (characterDataHandler) { + XML_Char c = XML_T('\n'); + characterDataHandler(handlerArg, &c, 1); + } + else if (defaultHandler) + reportDefault(parser, enc, s, end); + if (startTagLevel == 0) + return XML_ERROR_NO_ELEMENTS; + if (tagLevel != startTagLevel) + return XML_ERROR_ASYNC_ENTITY; + return XML_ERROR_NONE; + case XML_TOK_NONE: + if (nextPtr) { + *nextPtr = s; + return XML_ERROR_NONE; + } + if (startTagLevel > 0) { + if (tagLevel != startTagLevel) + return XML_ERROR_ASYNC_ENTITY; + return XML_ERROR_NONE; + } + return XML_ERROR_NO_ELEMENTS; + case XML_TOK_INVALID: + *eventPP = next; + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_PARTIAL: + if (nextPtr) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_UNCLOSED_TOKEN; + case XML_TOK_PARTIAL_CHAR: + if (nextPtr) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_PARTIAL_CHAR; + case XML_TOK_ENTITY_REF: + { + const XML_Char *name; + ENTITY *entity; + XML_Char ch = XmlPredefinedEntityName(enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (ch) { + if (characterDataHandler) + characterDataHandler(handlerArg, &ch, 1); + else if (defaultHandler) + reportDefault(parser, enc, s, next); + break; + } + name = poolStoreString(&dtd.pool, enc, + s + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (!name) + return XML_ERROR_NO_MEMORY; + entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0); + poolDiscard(&dtd.pool); + if (!entity) { + if (dtd.complete || dtd.standalone) + return XML_ERROR_UNDEFINED_ENTITY; + if (defaultHandler) + reportDefault(parser, enc, s, next); + break; + } + if (entity->open) + return XML_ERROR_RECURSIVE_ENTITY_REF; + if (entity->notation) + return XML_ERROR_BINARY_ENTITY_REF; + if (entity) { + if (entity->textPtr) { + enum XML_Error result; + if (defaultHandler) { + reportDefault(parser, enc, s, next); + break; + } + /* Protect against the possibility that somebody sets + the defaultHandler from inside another handler. */ + *eventEndPP = *eventPP; + entity->open = 1; + result = doContent(parser, + tagLevel, + internalEnc, + (char *)entity->textPtr, + (char *)(entity->textPtr + entity->textLen), + 0); + entity->open = 0; + if (result) + return result; + } + else if (externalEntityRefHandler) { + const XML_Char *openEntityNames; + entity->open = 1; + openEntityNames = getOpenEntityNames(parser); + entity->open = 0; + if (!openEntityNames) + return XML_ERROR_NO_MEMORY; + if (!externalEntityRefHandler(parser, openEntityNames, dtd.base, entity->systemId, entity->publicId)) + return XML_ERROR_EXTERNAL_ENTITY_HANDLING; + poolDiscard(&tempPool); + } + else if (defaultHandler) + reportDefault(parser, enc, s, next); + } + break; + } + case XML_TOK_START_TAG_WITH_ATTS: + if (!startElementHandler) { + enum XML_Error result = storeAtts(parser, enc, 0, s); + if (result) + return result; + } + /* fall through */ + case XML_TOK_START_TAG_NO_ATTS: + { + TAG *tag; + if (freeTagList) { + tag = freeTagList; + freeTagList = freeTagList->parent; + } + else { + tag = malloc(sizeof(TAG)); + if (!tag) + return XML_ERROR_NO_MEMORY; + tag->buf = malloc(INIT_TAG_BUF_SIZE); + if (!tag->buf) + return XML_ERROR_NO_MEMORY; + tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE; + } + tag->parent = tagStack; + tagStack = tag; + tag->rawName = s + enc->minBytesPerChar; + tag->rawNameLength = XmlNameLength(enc, tag->rawName); + if (nextPtr) { + if (tag->rawNameLength > tag->bufEnd - tag->buf) { + int bufSize = tag->rawNameLength * 4; + bufSize = ROUND_UP(bufSize, sizeof(XML_Char)); + tag->buf = realloc(tag->buf, bufSize); + if (!tag->buf) + return XML_ERROR_NO_MEMORY; + tag->bufEnd = tag->buf + bufSize; + } + memcpy(tag->buf, tag->rawName, tag->rawNameLength); + tag->rawName = tag->buf; + } + ++tagLevel; + if (startElementHandler) { + enum XML_Error result; + XML_Char *toPtr; + for (;;) { + const char *rawNameEnd = tag->rawName + tag->rawNameLength; + const char *fromPtr = tag->rawName; + int bufSize; + if (nextPtr) + toPtr = (XML_Char *)(tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char))); + else + toPtr = (XML_Char *)tag->buf; + tag->name = toPtr; + XmlConvert(enc, + &fromPtr, rawNameEnd, + (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1); + if (fromPtr == rawNameEnd) + break; + bufSize = (tag->bufEnd - tag->buf) << 1; + tag->buf = realloc(tag->buf, bufSize); + if (!tag->buf) + return XML_ERROR_NO_MEMORY; + tag->bufEnd = tag->buf + bufSize; + if (nextPtr) + tag->rawName = tag->buf; + } + *toPtr = XML_T('\0'); + result = storeAtts(parser, enc, tag->name, s); + if (result) + return result; + startElementHandler(handlerArg, tag->name, (const XML_Char **)atts); + poolClear(&tempPool); + } + else { + tag->name = 0; + if (defaultHandler) + reportDefault(parser, enc, s, next); + } + break; + } + case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: + if (!startElementHandler) { + enum XML_Error result = storeAtts(parser, enc, 0, s); + if (result) + return result; + } + /* fall through */ + case XML_TOK_EMPTY_ELEMENT_NO_ATTS: + if (startElementHandler || endElementHandler) { + const char *rawName = s + enc->minBytesPerChar; + const XML_Char *name = poolStoreString(&tempPool, enc, rawName, + rawName + + XmlNameLength(enc, rawName)); + if (!name) + return XML_ERROR_NO_MEMORY; + poolFinish(&tempPool); + if (startElementHandler) { + enum XML_Error result = storeAtts(parser, enc, name, s); + if (result) + return result; + startElementHandler(handlerArg, name, (const XML_Char **)atts); + } + if (endElementHandler) { + if (startElementHandler) + *eventPP = *eventEndPP; + endElementHandler(handlerArg, name); + } + poolClear(&tempPool); + } + else if (defaultHandler) + reportDefault(parser, enc, s, next); + if (tagLevel == 0) + return epilogProcessor(parser, next, end, nextPtr); + break; + case XML_TOK_END_TAG: + if (tagLevel == startTagLevel) + return XML_ERROR_ASYNC_ENTITY; + else { + int len; + const char *rawName; + TAG *tag = tagStack; + tagStack = tag->parent; + tag->parent = freeTagList; + freeTagList = tag; + rawName = s + enc->minBytesPerChar*2; + len = XmlNameLength(enc, rawName); + if (len != tag->rawNameLength + || memcmp(tag->rawName, rawName, len) != 0) { + *eventPP = rawName; + return XML_ERROR_TAG_MISMATCH; + } + --tagLevel; + if (endElementHandler) { + if (tag->name) + endElementHandler(handlerArg, tag->name); + else { + const XML_Char *name = poolStoreString(&tempPool, enc, rawName, + rawName + len); + if (!name) + return XML_ERROR_NO_MEMORY; + endElementHandler(handlerArg, name); + poolClear(&tempPool); + } + } + else if (defaultHandler) + reportDefault(parser, enc, s, next); + if (tagLevel == 0) + return epilogProcessor(parser, next, end, nextPtr); + } + break; + case XML_TOK_CHAR_REF: + { + int n = XmlCharRefNumber(enc, s); + if (n < 0) + return XML_ERROR_BAD_CHAR_REF; + if (characterDataHandler) { + XML_Char buf[XML_ENCODE_MAX]; + characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf)); + } + else if (defaultHandler) + reportDefault(parser, enc, s, next); + } + break; + case XML_TOK_XML_DECL: + return XML_ERROR_MISPLACED_XML_PI; + case XML_TOK_DATA_NEWLINE: + if (characterDataHandler) { + XML_Char c = XML_T('\n'); + characterDataHandler(handlerArg, &c, 1); + } + else if (defaultHandler) + reportDefault(parser, enc, s, next); + break; + case XML_TOK_CDATA_SECT_OPEN: + { + enum XML_Error result; + if (characterDataHandler) + characterDataHandler(handlerArg, dataBuf, 0); + else if (defaultHandler) + reportDefault(parser, enc, s, next); + result = doCdataSection(parser, enc, &next, end, nextPtr); + if (!next) { + processor = cdataSectionProcessor; + return result; + } + } + break; + case XML_TOK_TRAILING_RSQB: + if (nextPtr) { + *nextPtr = s; + return XML_ERROR_NONE; + } + if (characterDataHandler) { + if (MUST_CONVERT(enc, s)) { + ICHAR *dataPtr = (ICHAR *)dataBuf; + XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd); + characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf); + } + else + characterDataHandler(handlerArg, + (XML_Char *)s, + (XML_Char *)end - (XML_Char *)s); + } + else if (defaultHandler) + reportDefault(parser, enc, s, end); + if (startTagLevel == 0) { + *eventPP = end; + return XML_ERROR_NO_ELEMENTS; + } + if (tagLevel != startTagLevel) { + *eventPP = end; + return XML_ERROR_ASYNC_ENTITY; + } + return XML_ERROR_NONE; + case XML_TOK_DATA_CHARS: + if (characterDataHandler) { + if (MUST_CONVERT(enc, s)) { + for (;;) { + ICHAR *dataPtr = (ICHAR *)dataBuf; + XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd); + *eventEndPP = s; + characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf); + if (s == next) + break; + *eventPP = s; + } + } + else + characterDataHandler(handlerArg, + (XML_Char *)s, + (XML_Char *)next - (XML_Char *)s); + } + else if (defaultHandler) + reportDefault(parser, enc, s, next); + break; + case XML_TOK_PI: + if (!reportProcessingInstruction(parser, enc, s, next)) + return XML_ERROR_NO_MEMORY; + break; + default: + if (defaultHandler) + reportDefault(parser, enc, s, next); + break; + } + *eventPP = s = next; + } + /* not reached */ +} + +/* If tagName is non-null, build a real list of attributes, +otherwise just check the attributes for well-formedness. */ + +static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc, + const XML_Char *tagName, const char *s) +{ + ELEMENT_TYPE *elementType = 0; + int nDefaultAtts = 0; + const XML_Char **appAtts; + int i; + int n; + + if (tagName) { + elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagName, 0); + if (elementType) + nDefaultAtts = elementType->nDefaultAtts; + } + + n = XmlGetAttributes(enc, s, attsSize, atts); + if (n + nDefaultAtts > attsSize) { + int oldAttsSize = attsSize; + attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; + atts = realloc((void *)atts, attsSize * sizeof(ATTRIBUTE)); + if (!atts) + return XML_ERROR_NO_MEMORY; + if (n > oldAttsSize) + XmlGetAttributes(enc, s, n, atts); + } + appAtts = (const XML_Char **)atts; + for (i = 0; i < n; i++) { + ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name, + atts[i].name + + XmlNameLength(enc, atts[i].name)); + if (!attId) + return XML_ERROR_NO_MEMORY; + if ((attId->name)[-1]) { + if (enc == encoding) + eventPtr = atts[i].name; + return XML_ERROR_DUPLICATE_ATTRIBUTE; + } + (attId->name)[-1] = 1; + appAtts[i << 1] = attId->name; + if (!atts[i].normalized) { + enum XML_Error result; + int isCdata = 1; + + if (attId->maybeTokenized) { + int j; + for (j = 0; j < nDefaultAtts; j++) { + if (attId == elementType->defaultAtts[j].id) { + isCdata = elementType->defaultAtts[j].isCdata; + break; + } + } + } + + result = storeAttributeValue(parser, enc, isCdata, + atts[i].valuePtr, atts[i].valueEnd, + &tempPool); + if (result) + return result; + if (tagName) { + appAtts[(i << 1) + 1] = poolStart(&tempPool); + poolFinish(&tempPool); + } + else + poolDiscard(&tempPool); + } + else if (tagName) { + appAtts[(i << 1) + 1] = poolStoreString(&tempPool, enc, atts[i].valuePtr, atts[i].valueEnd); + if (appAtts[(i << 1) + 1] == 0) + return XML_ERROR_NO_MEMORY; + poolFinish(&tempPool); + } + } + if (tagName) { + int j; + for (j = 0; j < nDefaultAtts; j++) { + const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j; + if (!(da->id->name)[-1] && da->value) { + (da->id->name)[-1] = 1; + appAtts[i << 1] = da->id->name; + appAtts[(i << 1) + 1] = da->value; + i++; + } + } + appAtts[i << 1] = 0; + } + while (i-- > 0) + ((XML_Char *)appAtts[i << 1])[-1] = 0; + return XML_ERROR_NONE; +} + +/* The idea here is to avoid using stack for each CDATA section when +the whole file is parsed with one call. */ + +static +enum XML_Error cdataSectionProcessor(XML_Parser parser, + const char *start, + const char *end, + const char **endPtr) +{ + enum XML_Error result = doCdataSection(parser, encoding, &start, end, endPtr); + if (start) { + processor = contentProcessor; + return contentProcessor(parser, start, end, endPtr); + } + return result; +} + +/* startPtr gets set to non-null is the section is closed, and to null if +the section is not yet closed. */ + +static +enum XML_Error doCdataSection(XML_Parser parser, + const ENCODING *enc, + const char **startPtr, + const char *end, + const char **nextPtr) +{ + const char *s = *startPtr; + const char *dummy; + const char **eventPP; + const char **eventEndPP; + if (enc == encoding) { + eventPP = &eventPtr; + *eventPP = s; + eventEndPP = &eventEndPtr; + } + else + eventPP = eventEndPP = &dummy; + *startPtr = 0; + for (;;) { + const char *next; + int tok = XmlCdataSectionTok(enc, s, end, &next); + *eventEndPP = next; + switch (tok) { + case XML_TOK_CDATA_SECT_CLOSE: + if (characterDataHandler) + characterDataHandler(handlerArg, dataBuf, 0); + else if (defaultHandler) + reportDefault(parser, enc, s, next); + *startPtr = next; + return XML_ERROR_NONE; + case XML_TOK_DATA_NEWLINE: + if (characterDataHandler) { + XML_Char c = XML_T('\n'); + characterDataHandler(handlerArg, &c, 1); + } + else if (defaultHandler) + reportDefault(parser, enc, s, next); + break; + case XML_TOK_DATA_CHARS: + if (characterDataHandler) { + if (MUST_CONVERT(enc, s)) { + for (;;) { + ICHAR *dataPtr = (ICHAR *)dataBuf; + XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd); + *eventEndPP = next; + characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf); + if (s == next) + break; + *eventPP = s; + } + } + else + characterDataHandler(handlerArg, + (XML_Char *)s, + (XML_Char *)next - (XML_Char *)s); + } + else if (defaultHandler) + reportDefault(parser, enc, s, next); + break; + case XML_TOK_INVALID: + *eventPP = next; + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_PARTIAL_CHAR: + if (nextPtr) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_PARTIAL_CHAR; + case XML_TOK_PARTIAL: + case XML_TOK_NONE: + if (nextPtr) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_UNCLOSED_CDATA_SECTION; + default: + abort(); + } + *eventPP = s = next; + } + /* not reached */ +} + +static enum XML_Error +initializeEncoding(XML_Parser parser) +{ + const char *s; +#ifdef XML_UNICODE + char encodingBuf[128]; + if (!protocolEncodingName) + s = 0; + else { + int i; + for (i = 0; protocolEncodingName[i]; i++) { + if (i == sizeof(encodingBuf) - 1 + || protocolEncodingName[i] >= 0x80 + || protocolEncodingName[i] < 0) { + encodingBuf[0] = '\0'; + break; + } + encodingBuf[i] = (char)protocolEncodingName[i]; + } + encodingBuf[i] = '\0'; + s = encodingBuf; + } +#else + s = protocolEncodingName; +#endif + if (XmlInitEncoding(&initEncoding, &encoding, s)) + return XML_ERROR_NONE; + return handleUnknownEncoding(parser, protocolEncodingName); +} + +static enum XML_Error +processXmlDecl(XML_Parser parser, int isGeneralTextEntity, + const char *s, const char *next) +{ + const char *encodingName = 0; + const ENCODING *newEncoding = 0; + const char *version; + int standalone = -1; + if (!XmlParseXmlDecl(isGeneralTextEntity, + encoding, + s, + next, + &eventPtr, + &version, + &encodingName, + &newEncoding, + &standalone)) + return XML_ERROR_SYNTAX; + if (!isGeneralTextEntity && standalone == 1) + dtd.standalone = 1; + if (defaultHandler) + reportDefault(parser, encoding, s, next); + if (!protocolEncodingName) { + if (newEncoding) { + if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) { + eventPtr = encodingName; + return XML_ERROR_INCORRECT_ENCODING; + } + encoding = newEncoding; + } + else if (encodingName) { + enum XML_Error result; + const XML_Char *s = poolStoreString(&tempPool, + encoding, + encodingName, + encodingName + + XmlNameLength(encoding, encodingName)); + if (!s) + return XML_ERROR_NO_MEMORY; + result = handleUnknownEncoding(parser, s); + poolDiscard(&tempPool); + if (result == XML_ERROR_UNKNOWN_ENCODING) + eventPtr = encodingName; + return result; + } + } + return XML_ERROR_NONE; +} + +static enum XML_Error +handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) +{ + if (unknownEncodingHandler) { + XML_Encoding info; + int i; + for (i = 0; i < 256; i++) + info.map[i] = -1; + info.convert = 0; + info.data = 0; + info.release = 0; + if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, &info)) { + ENCODING *enc; + unknownEncodingMem = malloc(XmlSizeOfUnknownEncoding()); + if (!unknownEncodingMem) { + if (info.release) + info.release(info.data); + return XML_ERROR_NO_MEMORY; + } + enc = XmlInitUnknownEncoding(unknownEncodingMem, + info.map, + info.convert, + info.data); + if (enc) { + unknownEncodingData = info.data; + unknownEncodingRelease = info.release; + encoding = enc; + return XML_ERROR_NONE; + } + } + if (info.release) + info.release(info.data); + } + return XML_ERROR_UNKNOWN_ENCODING; +} + +static enum XML_Error +prologInitProcessor(XML_Parser parser, + const char *s, + const char *end, + const char **nextPtr) +{ + enum XML_Error result = initializeEncoding(parser); + if (result != XML_ERROR_NONE) + return result; + processor = prologProcessor; + return prologProcessor(parser, s, end, nextPtr); +} + +static enum XML_Error +prologProcessor(XML_Parser parser, + const char *s, + const char *end, + const char **nextPtr) +{ + for (;;) { + const char *next; + int tok = XmlPrologTok(encoding, s, end, &next); + if (tok <= 0) { + if (nextPtr != 0 && tok != XML_TOK_INVALID) { + *nextPtr = s; + return XML_ERROR_NONE; + } + switch (tok) { + case XML_TOK_INVALID: + eventPtr = next; + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_NONE: + return XML_ERROR_NO_ELEMENTS; + case XML_TOK_PARTIAL: + return XML_ERROR_UNCLOSED_TOKEN; + case XML_TOK_PARTIAL_CHAR: + return XML_ERROR_PARTIAL_CHAR; + case XML_TOK_TRAILING_CR: + eventPtr = s + encoding->minBytesPerChar; + return XML_ERROR_NO_ELEMENTS; + default: + abort(); + } + } + switch (XmlTokenRole(&prologState, tok, s, next, encoding)) { + case XML_ROLE_XML_DECL: + { + enum XML_Error result = processXmlDecl(parser, 0, s, next); + if (result != XML_ERROR_NONE) + return result; + } + break; + case XML_ROLE_DOCTYPE_SYSTEM_ID: + hadExternalDoctype = 1; + break; + case XML_ROLE_DOCTYPE_PUBLIC_ID: + case XML_ROLE_ENTITY_PUBLIC_ID: + if (!XmlIsPublicId(encoding, s, next, &eventPtr)) + return XML_ERROR_SYNTAX; + if (declEntity) { + XML_Char *tem = poolStoreString(&dtd.pool, + encoding, + s + encoding->minBytesPerChar, + next - encoding->minBytesPerChar); + if (!tem) + return XML_ERROR_NO_MEMORY; + normalizePublicId(tem); + declEntity->publicId = tem; + poolFinish(&dtd.pool); + } + break; + case XML_ROLE_INSTANCE_START: + processor = contentProcessor; + if (hadExternalDoctype) + dtd.complete = 0; + return contentProcessor(parser, s, end, nextPtr); + case XML_ROLE_ATTLIST_ELEMENT_NAME: + { + const XML_Char *name = poolStoreString(&dtd.pool, encoding, s, next); + if (!name) + return XML_ERROR_NO_MEMORY; + declElementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE)); + if (!declElementType) + return XML_ERROR_NO_MEMORY; + if (declElementType->name != name) + poolDiscard(&dtd.pool); + else + poolFinish(&dtd.pool); + break; + } + case XML_ROLE_ATTRIBUTE_NAME: + declAttributeId = getAttributeId(parser, encoding, s, next); + if (!declAttributeId) + return XML_ERROR_NO_MEMORY; + declAttributeIsCdata = 0; + break; + case XML_ROLE_ATTRIBUTE_TYPE_CDATA: + declAttributeIsCdata = 1; + break; + case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE: + case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE: + if (dtd.complete + && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, 0)) + return XML_ERROR_NO_MEMORY; + break; + case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE: + case XML_ROLE_FIXED_ATTRIBUTE_VALUE: + { + const XML_Char *attVal; + enum XML_Error result + = storeAttributeValue(parser, encoding, declAttributeIsCdata, + s + encoding->minBytesPerChar, + next - encoding->minBytesPerChar, + &dtd.pool); + if (result) + return result; + attVal = poolStart(&dtd.pool); + poolFinish(&dtd.pool); + if (dtd.complete + && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, attVal)) + return XML_ERROR_NO_MEMORY; + break; + } + case XML_ROLE_ENTITY_VALUE: + { + enum XML_Error result = storeEntityValue(parser, s, next); + if (result != XML_ERROR_NONE) + return result; + } + break; + case XML_ROLE_ENTITY_SYSTEM_ID: + if (declEntity) { + declEntity->systemId = poolStoreString(&dtd.pool, encoding, + s + encoding->minBytesPerChar, + next - encoding->minBytesPerChar); + if (!declEntity->systemId) + return XML_ERROR_NO_MEMORY; + declEntity->base = dtd.base; + poolFinish(&dtd.pool); + } + break; + case XML_ROLE_ENTITY_NOTATION_NAME: + if (declEntity) { + declEntity->notation = poolStoreString(&dtd.pool, encoding, s, next); + if (!declEntity->notation) + return XML_ERROR_NO_MEMORY; + poolFinish(&dtd.pool); + if (unparsedEntityDeclHandler) { + eventPtr = eventEndPtr = s; + unparsedEntityDeclHandler(handlerArg, + declEntity->name, + declEntity->base, + declEntity->systemId, + declEntity->publicId, + declEntity->notation); + } + + } + break; + case XML_ROLE_GENERAL_ENTITY_NAME: + { + const XML_Char *name; + if (XmlPredefinedEntityName(encoding, s, next)) { + declEntity = 0; + break; + } + name = poolStoreString(&dtd.pool, encoding, s, next); + if (!name) + return XML_ERROR_NO_MEMORY; + if (dtd.complete) { + declEntity = (ENTITY *)lookup(&dtd.generalEntities, name, sizeof(ENTITY)); + if (!declEntity) + return XML_ERROR_NO_MEMORY; + if (declEntity->name != name) { + poolDiscard(&dtd.pool); + declEntity = 0; + } + else + poolFinish(&dtd.pool); + } + else { + poolDiscard(&dtd.pool); + declEntity = 0; + } + } + break; + case XML_ROLE_PARAM_ENTITY_NAME: + declEntity = 0; + break; + case XML_ROLE_NOTATION_NAME: + declNotationPublicId = 0; + declNotationName = 0; + if (notationDeclHandler) { + declNotationName = poolStoreString(&tempPool, encoding, s, next); + if (!declNotationName) + return XML_ERROR_NO_MEMORY; + poolFinish(&tempPool); + } + break; + case XML_ROLE_NOTATION_PUBLIC_ID: + if (!XmlIsPublicId(encoding, s, next, &eventPtr)) + return XML_ERROR_SYNTAX; + if (declNotationName) { + XML_Char *tem = poolStoreString(&tempPool, + encoding, + s + encoding->minBytesPerChar, + next - encoding->minBytesPerChar); + if (!tem) + return XML_ERROR_NO_MEMORY; + normalizePublicId(tem); + declNotationPublicId = tem; + poolFinish(&tempPool); + } + break; + case XML_ROLE_NOTATION_SYSTEM_ID: + if (declNotationName && notationDeclHandler) { + const XML_Char *systemId + = poolStoreString(&tempPool, encoding, + s + encoding->minBytesPerChar, + next - encoding->minBytesPerChar); + if (!systemId) + return XML_ERROR_NO_MEMORY; + eventPtr = eventEndPtr = s; + notationDeclHandler(handlerArg, + declNotationName, + dtd.base, + systemId, + declNotationPublicId); + } + poolClear(&tempPool); + break; + case XML_ROLE_NOTATION_NO_SYSTEM_ID: + if (declNotationPublicId && notationDeclHandler) { + eventPtr = eventEndPtr = s; + notationDeclHandler(handlerArg, + declNotationName, + dtd.base, + 0, + declNotationPublicId); + } + poolClear(&tempPool); + break; + case XML_ROLE_ERROR: + eventPtr = s; + switch (tok) { + case XML_TOK_PARAM_ENTITY_REF: + return XML_ERROR_PARAM_ENTITY_REF; + case XML_TOK_XML_DECL: + return XML_ERROR_MISPLACED_XML_PI; + default: + return XML_ERROR_SYNTAX; + } + case XML_ROLE_GROUP_OPEN: + if (prologState.level >= groupSize) { + if (groupSize) + groupConnector = realloc(groupConnector, groupSize *= 2); + else + groupConnector = malloc(groupSize = 32); + if (!groupConnector) + return XML_ERROR_NO_MEMORY; + } + groupConnector[prologState.level] = 0; + break; + case XML_ROLE_GROUP_SEQUENCE: + if (groupConnector[prologState.level] == '|') { + eventPtr = s; + return XML_ERROR_SYNTAX; + } + groupConnector[prologState.level] = ','; + break; + case XML_ROLE_GROUP_CHOICE: + if (groupConnector[prologState.level] == ',') { + eventPtr = s; + return XML_ERROR_SYNTAX; + } + groupConnector[prologState.level] = '|'; + break; + case XML_ROLE_PARAM_ENTITY_REF: + dtd.complete = 0; + break; + case XML_ROLE_NONE: + switch (tok) { + case XML_TOK_PI: + eventPtr = s; + eventEndPtr = next; + if (!reportProcessingInstruction(parser, encoding, s, next)) + return XML_ERROR_NO_MEMORY; + break; + } + break; + } + if (defaultHandler) { + switch (tok) { + case XML_TOK_PI: + case XML_TOK_BOM: + case XML_TOK_XML_DECL: + break; + default: + eventPtr = s; + eventEndPtr = next; + reportDefault(parser, encoding, s, next); + } + } + s = next; + } + /* not reached */ +} + +static +enum XML_Error epilogProcessor(XML_Parser parser, + const char *s, + const char *end, + const char **nextPtr) +{ + processor = epilogProcessor; + eventPtr = s; + for (;;) { + const char *next; + int tok = XmlPrologTok(encoding, s, end, &next); + eventEndPtr = next; + switch (tok) { + case XML_TOK_TRAILING_CR: + if (defaultHandler) { + eventEndPtr = end; + reportDefault(parser, encoding, s, end); + } + /* fall through */ + case XML_TOK_NONE: + if (nextPtr) + *nextPtr = end; + return XML_ERROR_NONE; + case XML_TOK_PROLOG_S: + case XML_TOK_COMMENT: + if (defaultHandler) + reportDefault(parser, encoding, s, next); + break; + case XML_TOK_PI: + if (!reportProcessingInstruction(parser, encoding, s, next)) + return XML_ERROR_NO_MEMORY; + break; + case XML_TOK_INVALID: + eventPtr = next; + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_PARTIAL: + if (nextPtr) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_UNCLOSED_TOKEN; + case XML_TOK_PARTIAL_CHAR: + if (nextPtr) { + *nextPtr = s; + return XML_ERROR_NONE; + } + return XML_ERROR_PARTIAL_CHAR; + default: + return XML_ERROR_JUNK_AFTER_DOC_ELEMENT; + } + eventPtr = s = next; + } +} + +static +enum XML_Error errorProcessor(XML_Parser parser, + const char *s, + const char *end, + const char **nextPtr) +{ + return errorCode; +} + +static enum XML_Error +storeAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata, + const char *ptr, const char *end, + STRING_POOL *pool) +{ + enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, end, pool); + if (result) + return result; + if (!isCdata && poolLength(pool) && poolLastChar(pool) == XML_T(' ')) + poolChop(pool); + if (!poolAppendChar(pool, XML_T('\0'))) + return XML_ERROR_NO_MEMORY; + return XML_ERROR_NONE; +} + +static enum XML_Error +appendAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata, + const char *ptr, const char *end, + STRING_POOL *pool) +{ + const ENCODING *internalEnc = XmlGetInternalEncoding(); + for (;;) { + const char *next; + int tok = XmlAttributeValueTok(enc, ptr, end, &next); + switch (tok) { + case XML_TOK_NONE: + return XML_ERROR_NONE; + case XML_TOK_INVALID: + if (enc == encoding) + eventPtr = next; + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_PARTIAL: + if (enc == encoding) + eventPtr = ptr; + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_CHAR_REF: + { + XML_Char buf[XML_ENCODE_MAX]; + int i; + int n = XmlCharRefNumber(enc, ptr); + if (n < 0) { + if (enc == encoding) + eventPtr = ptr; + return XML_ERROR_BAD_CHAR_REF; + } + if (!isCdata + && n == 0x20 /* space */ + && (poolLength(pool) == 0 || poolLastChar(pool) == XML_T(' '))) + break; + n = XmlEncode(n, (ICHAR *)buf); + if (!n) { + if (enc == encoding) + eventPtr = ptr; + return XML_ERROR_BAD_CHAR_REF; + } + for (i = 0; i < n; i++) { + if (!poolAppendChar(pool, buf[i])) + return XML_ERROR_NO_MEMORY; + } + } + break; + case XML_TOK_DATA_CHARS: + if (!poolAppend(pool, enc, ptr, next)) + return XML_ERROR_NO_MEMORY; + break; + break; + case XML_TOK_TRAILING_CR: + next = ptr + enc->minBytesPerChar; + /* fall through */ + case XML_TOK_ATTRIBUTE_VALUE_S: + case XML_TOK_DATA_NEWLINE: + if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == XML_T(' '))) + break; + if (!poolAppendChar(pool, XML_T(' '))) + return XML_ERROR_NO_MEMORY; + break; + case XML_TOK_ENTITY_REF: + { + const XML_Char *name; + ENTITY *entity; + XML_Char ch = XmlPredefinedEntityName(enc, + ptr + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (ch) { + if (!poolAppendChar(pool, ch)) + return XML_ERROR_NO_MEMORY; + break; + } + name = poolStoreString(&temp2Pool, enc, + ptr + enc->minBytesPerChar, + next - enc->minBytesPerChar); + if (!name) + return XML_ERROR_NO_MEMORY; + entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0); + poolDiscard(&temp2Pool); + if (!entity) { + if (dtd.complete) { + if (enc == encoding) + eventPtr = ptr; + return XML_ERROR_UNDEFINED_ENTITY; + } + } + else if (entity->open) { + if (enc == encoding) + eventPtr = ptr; + return XML_ERROR_RECURSIVE_ENTITY_REF; + } + else if (entity->notation) { + if (enc == encoding) + eventPtr = ptr; + return XML_ERROR_BINARY_ENTITY_REF; + } + else if (!entity->textPtr) { + if (enc == encoding) + eventPtr = ptr; + return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF; + } + else { + enum XML_Error result; + const XML_Char *textEnd = entity->textPtr + entity->textLen; + entity->open = 1; + result = appendAttributeValue(parser, internalEnc, isCdata, (char *)entity->textPtr, (char *)textEnd, pool); + entity->open = 0; + if (result) + return result; + } + } + break; + default: + abort(); + } + ptr = next; + } + /* not reached */ +} + +static +enum XML_Error storeEntityValue(XML_Parser parser, + const char *entityTextPtr, + const char *entityTextEnd) +{ + const ENCODING *internalEnc = XmlGetInternalEncoding(); + STRING_POOL *pool = &(dtd.pool); + entityTextPtr += encoding->minBytesPerChar; + entityTextEnd -= encoding->minBytesPerChar; + for (;;) { + const char *next; + int tok = XmlEntityValueTok(encoding, entityTextPtr, entityTextEnd, &next); + switch (tok) { + case XML_TOK_PARAM_ENTITY_REF: + eventPtr = entityTextPtr; + return XML_ERROR_SYNTAX; + case XML_TOK_NONE: + if (declEntity) { + declEntity->textPtr = pool->start; + declEntity->textLen = pool->ptr - pool->start; + poolFinish(pool); + } + else + poolDiscard(pool); + return XML_ERROR_NONE; + case XML_TOK_ENTITY_REF: + case XML_TOK_DATA_CHARS: + if (!poolAppend(pool, encoding, entityTextPtr, next)) + return XML_ERROR_NO_MEMORY; + break; + case XML_TOK_TRAILING_CR: + next = entityTextPtr + encoding->minBytesPerChar; + /* fall through */ + case XML_TOK_DATA_NEWLINE: + if (pool->end == pool->ptr && !poolGrow(pool)) + return XML_ERROR_NO_MEMORY; + *(pool->ptr)++ = XML_T('\n'); + break; + case XML_TOK_CHAR_REF: + { + XML_Char buf[XML_ENCODE_MAX]; + int i; + int n = XmlCharRefNumber(encoding, entityTextPtr); + if (n < 0) { + eventPtr = entityTextPtr; + return XML_ERROR_BAD_CHAR_REF; + } + n = XmlEncode(n, (ICHAR *)buf); + if (!n) { + eventPtr = entityTextPtr; + return XML_ERROR_BAD_CHAR_REF; + } + for (i = 0; i < n; i++) { + if (pool->end == pool->ptr && !poolGrow(pool)) + return XML_ERROR_NO_MEMORY; + *(pool->ptr)++ = buf[i]; + } + } + break; + case XML_TOK_PARTIAL: + eventPtr = entityTextPtr; + return XML_ERROR_INVALID_TOKEN; + case XML_TOK_INVALID: + eventPtr = next; + return XML_ERROR_INVALID_TOKEN; + default: + abort(); + } + entityTextPtr = next; + } + /* not reached */ +} + +static void +normalizeLines(XML_Char *s) +{ + XML_Char *p; + for (;; s++) { + if (*s == XML_T('\0')) + return; + if (*s == XML_T('\r')) + break; + } + p = s; + do { + if (*s == XML_T('\r')) { + *p++ = XML_T('\n'); + if (*++s == XML_T('\n')) + s++; + } + else + *p++ = *s++; + } while (*s); + *p = XML_T('\0'); +} + +static int +reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end) +{ + const XML_Char *target; + XML_Char *data; + const char *tem; + if (!processingInstructionHandler) { + if (defaultHandler) + reportDefault(parser, enc, start, end); + return 1; + } + start += enc->minBytesPerChar * 2; + tem = start + XmlNameLength(enc, start); + target = poolStoreString(&tempPool, enc, start, tem); + if (!target) + return 0; + poolFinish(&tempPool); + data = poolStoreString(&tempPool, enc, + XmlSkipS(enc, tem), + end - enc->minBytesPerChar*2); + if (!data) + return 0; + normalizeLines(data); + processingInstructionHandler(handlerArg, target, data); + poolClear(&tempPool); + return 1; +} + +static void +reportDefault(XML_Parser parser, const ENCODING *enc, const char *s, const char *end) +{ + if (MUST_CONVERT(enc, s)) { + for (;;) { + ICHAR *dataPtr = (ICHAR *)dataBuf; + XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd); + if (s == end) { + defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf); + break; + } + if (enc == encoding) { + eventEndPtr = s; + defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf); + eventPtr = s; + } + else + defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf); + } + } + else + defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s); +} + + +static int +defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, int isCdata, const XML_Char *value) +{ + DEFAULT_ATTRIBUTE *att; + if (type->nDefaultAtts == type->allocDefaultAtts) { + if (type->allocDefaultAtts == 0) { + type->allocDefaultAtts = 8; + type->defaultAtts = malloc(type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE)); + } + else { + type->allocDefaultAtts *= 2; + type->defaultAtts = realloc(type->defaultAtts, + type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE)); + } + if (!type->defaultAtts) + return 0; + } + att = type->defaultAtts + type->nDefaultAtts; + att->id = attId; + att->value = value; + att->isCdata = isCdata; + if (!isCdata) + attId->maybeTokenized = 1; + type->nDefaultAtts += 1; + return 1; +} + +static ATTRIBUTE_ID * +getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end) +{ + ATTRIBUTE_ID *id; + const XML_Char *name; + if (!poolAppendChar(&dtd.pool, XML_T('\0'))) + return 0; + name = poolStoreString(&dtd.pool, enc, start, end); + if (!name) + return 0; + ++name; + id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, name, sizeof(ATTRIBUTE_ID)); + if (!id) + return 0; + if (id->name != name) + poolDiscard(&dtd.pool); + else + poolFinish(&dtd.pool); + return id; +} + +static +const XML_Char *getOpenEntityNames(XML_Parser parser) +{ + HASH_TABLE_ITER iter; + + hashTableIterInit(&iter, &(dtd.generalEntities)); + for (;;) { + const XML_Char *s; + ENTITY *e = (ENTITY *)hashTableIterNext(&iter); + if (!e) + break; + if (!e->open) + continue; + if (poolLength(&tempPool) > 0 && !poolAppendChar(&tempPool, XML_T(' '))) + return 0; + for (s = e->name; *s; s++) + if (!poolAppendChar(&tempPool, *s)) + return 0; + } + + if (!poolAppendChar(&tempPool, XML_T('\0'))) + return 0; + return tempPool.start; +} + +static +int setOpenEntityNames(XML_Parser parser, const XML_Char *openEntityNames) +{ + const XML_Char *s = openEntityNames; + while (*openEntityNames != XML_T('\0')) { + if (*s == XML_T(' ') || *s == XML_T('\0')) { + ENTITY *e; + if (!poolAppendChar(&tempPool, XML_T('\0'))) + return 0; + e = (ENTITY *)lookup(&dtd.generalEntities, poolStart(&tempPool), 0); + if (e) + e->open = 1; + if (*s == XML_T(' ')) + s++; + openEntityNames = s; + poolDiscard(&tempPool); + } + else { + if (!poolAppendChar(&tempPool, *s)) + return 0; + s++; + } + } + return 1; +} + + +static +void normalizePublicId(XML_Char *publicId) +{ + XML_Char *p = publicId; + XML_Char *s; + for (s = publicId; *s; s++) { + switch (*s) { + case XML_T(' '): + case XML_T('\r'): + case XML_T('\n'): + if (p != publicId && p[-1] != XML_T(' ')) + *p++ = XML_T(' '); + break; + default: + *p++ = *s; + } + } + if (p != publicId && p[-1] == XML_T(' ')) + --p; + *p = XML_T('\0'); +} + +static int dtdInit(DTD *p) +{ + poolInit(&(p->pool)); + hashTableInit(&(p->generalEntities)); + hashTableInit(&(p->elementTypes)); + hashTableInit(&(p->attributeIds)); + p->complete = 1; + p->standalone = 0; + p->base = 0; + return 1; +} + +static void dtdDestroy(DTD *p) +{ + HASH_TABLE_ITER iter; + hashTableIterInit(&iter, &(p->elementTypes)); + for (;;) { + ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); + if (!e) + break; + if (e->allocDefaultAtts != 0) + free(e->defaultAtts); + } + hashTableDestroy(&(p->generalEntities)); + hashTableDestroy(&(p->elementTypes)); + hashTableDestroy(&(p->attributeIds)); + poolDestroy(&(p->pool)); +} + +/* Do a deep copy of the DTD. Return 0 for out of memory; non-zero otherwise. +The new DTD has already been initialized. */ + +static int dtdCopy(DTD *newDtd, const DTD *oldDtd) +{ + HASH_TABLE_ITER iter; + + if (oldDtd->base) { + const XML_Char *tem = poolCopyString(&(newDtd->pool), oldDtd->base); + if (!tem) + return 0; + newDtd->base = tem; + } + + hashTableIterInit(&iter, &(oldDtd->attributeIds)); + + /* Copy the attribute id table. */ + + for (;;) { + ATTRIBUTE_ID *newA; + const XML_Char *name; + const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter); + + if (!oldA) + break; + /* Remember to allocate the scratch byte before the name. */ + if (!poolAppendChar(&(newDtd->pool), XML_T('\0'))) + return 0; + name = poolCopyString(&(newDtd->pool), oldA->name); + if (!name) + return 0; + ++name; + newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name, sizeof(ATTRIBUTE_ID)); + if (!newA) + return 0; + newA->maybeTokenized = oldA->maybeTokenized; + } + + /* Copy the element type table. */ + + hashTableIterInit(&iter, &(oldDtd->elementTypes)); + + for (;;) { + int i; + ELEMENT_TYPE *newE; + const XML_Char *name; + const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter); + if (!oldE) + break; + name = poolCopyString(&(newDtd->pool), oldE->name); + if (!name) + return 0; + newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name, sizeof(ELEMENT_TYPE)); + if (!newE) + return 0; + newE->defaultAtts = (DEFAULT_ATTRIBUTE *)malloc(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); + if (!newE->defaultAtts) + return 0; + newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts; + for (i = 0; i < newE->nDefaultAtts; i++) { + newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0); + newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata; + if (oldE->defaultAtts[i].value) { + newE->defaultAtts[i].value = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value); + if (!newE->defaultAtts[i].value) + return 0; + } + else + newE->defaultAtts[i].value = 0; + } + } + + /* Copy the entity table. */ + + hashTableIterInit(&iter, &(oldDtd->generalEntities)); + + for (;;) { + ENTITY *newE; + const XML_Char *name; + const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter); + if (!oldE) + break; + name = poolCopyString(&(newDtd->pool), oldE->name); + if (!name) + return 0; + newE = (ENTITY *)lookup(&(newDtd->generalEntities), name, sizeof(ENTITY)); + if (!newE) + return 0; + if (oldE->systemId) { + const XML_Char *tem = poolCopyString(&(newDtd->pool), oldE->systemId); + if (!tem) + return 0; + newE->systemId = tem; + if (oldE->base) { + if (oldE->base == oldDtd->base) + newE->base = newDtd->base; + tem = poolCopyString(&(newDtd->pool), oldE->base); + if (!tem) + return 0; + newE->base = tem; + } + } + else { + const XML_Char *tem = poolCopyStringN(&(newDtd->pool), oldE->textPtr, oldE->textLen); + if (!tem) + return 0; + newE->textPtr = tem; + newE->textLen = oldE->textLen; + } + if (oldE->notation) { + const XML_Char *tem = poolCopyString(&(newDtd->pool), oldE->notation); + if (!tem) + return 0; + newE->notation = tem; + } + } + + newDtd->complete = oldDtd->complete; + newDtd->standalone = oldDtd->standalone; + return 1; +} + +static +void poolInit(STRING_POOL *pool) +{ + pool->blocks = 0; + pool->freeBlocks = 0; + pool->start = 0; + pool->ptr = 0; + pool->end = 0; +} + +static +void poolClear(STRING_POOL *pool) +{ + if (!pool->freeBlocks) + pool->freeBlocks = pool->blocks; + else { + BLOCK *p = pool->blocks; + while (p) { + BLOCK *tem = p->next; + p->next = pool->freeBlocks; + pool->freeBlocks = p; + p = tem; + } + } + pool->blocks = 0; + pool->start = 0; + pool->ptr = 0; + pool->end = 0; +} + +static +void poolDestroy(STRING_POOL *pool) +{ + BLOCK *p = pool->blocks; + while (p) { + BLOCK *tem = p->next; + free(p); + p = tem; + } + pool->blocks = 0; + p = pool->freeBlocks; + while (p) { + BLOCK *tem = p->next; + free(p); + p = tem; + } + pool->freeBlocks = 0; + pool->ptr = 0; + pool->start = 0; + pool->end = 0; +} + +static +XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc, + const char *ptr, const char *end) +{ + if (!pool->ptr && !poolGrow(pool)) + return 0; + for (;;) { + XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end); + if (ptr == end) + break; + if (!poolGrow(pool)) + return 0; + } + return pool->start; +} + +static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s) +{ + do { + if (!poolAppendChar(pool, *s)) + return 0; + } while (*s++); + s = pool->start; + poolFinish(pool); + return s; +} + +static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) +{ + if (!pool->ptr && !poolGrow(pool)) + return 0; + for (; n > 0; --n, s++) { + if (!poolAppendChar(pool, *s)) + return 0; + + } + s = pool->start; + poolFinish(pool); + return s; +} + +static +XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc, + const char *ptr, const char *end) +{ + if (!poolAppend(pool, enc, ptr, end)) + return 0; + if (pool->ptr == pool->end && !poolGrow(pool)) + return 0; + *(pool->ptr)++ = 0; + return pool->start; +} + +static +int poolGrow(STRING_POOL *pool) +{ + if (pool->freeBlocks) { + if (pool->start == 0) { + pool->blocks = pool->freeBlocks; + pool->freeBlocks = pool->freeBlocks->next; + pool->blocks->next = 0; + pool->start = pool->blocks->s; + pool->end = pool->start + pool->blocks->size; + pool->ptr = pool->start; + return 1; + } + if (pool->end - pool->start < pool->freeBlocks->size) { + BLOCK *tem = pool->freeBlocks->next; + pool->freeBlocks->next = pool->blocks; + pool->blocks = pool->freeBlocks; + pool->freeBlocks = tem; + memcpy(pool->blocks->s, pool->start, (pool->end - pool->start) * sizeof(XML_Char)); + pool->ptr = pool->blocks->s + (pool->ptr - pool->start); + pool->start = pool->blocks->s; + pool->end = pool->start + pool->blocks->size; + return 1; + } + } + if (pool->blocks && pool->start == pool->blocks->s) { + int blockSize = (pool->end - pool->start)*2; + pool->blocks = realloc(pool->blocks, offsetof(BLOCK, s) + blockSize * sizeof(XML_Char)); + if (!pool->blocks) + return 0; + pool->blocks->size = blockSize; + pool->ptr = pool->blocks->s + (pool->ptr - pool->start); + pool->start = pool->blocks->s; + pool->end = pool->start + blockSize; + } + else { + BLOCK *tem; + int blockSize = pool->end - pool->start; + if (blockSize < INIT_BLOCK_SIZE) + blockSize = INIT_BLOCK_SIZE; + else + blockSize *= 2; + tem = malloc(offsetof(BLOCK, s) + blockSize * sizeof(XML_Char)); + if (!tem) + return 0; + tem->size = blockSize; + tem->next = pool->blocks; + pool->blocks = tem; + memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char)); + pool->ptr = tem->s + (pool->ptr - pool->start); + pool->start = tem->s; + pool->end = tem->s + blockSize; + } + return 1; +} diff --git a/mozilla/extensions/transformiix/source/xml/parser/xmlparse/xmlparse.h b/mozilla/extensions/transformiix/source/xml/parser/xmlparse/xmlparse.h new file mode 100644 index 00000000000..13d5885ca2a --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/xmlparse/xmlparse.h @@ -0,0 +1,382 @@ +/* +The contents of this file are subject to the Mozilla Public License +Version 1.0 (the "License"); you may not use this file except in +compliance with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" +basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific language governing rights and limitations +under the License. + +The Original Code is expat. + +The Initial Developer of the Original Code is James Clark. +Portions created by James Clark are Copyright (C) 1998 +James Clark. All Rights Reserved. + +Contributor(s): +*/ + +#ifndef XmlParse_INCLUDED +#define XmlParse_INCLUDED 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef XMLPARSEAPI +#define XMLPARSEAPI /* as nothing */ +#endif + +typedef void *XML_Parser; + +#ifdef XML_UNICODE_WCHAR_T + +/* XML_UNICODE_WCHAR_T will work only if sizeof(wchar_t) == 2 and wchar_t +uses Unicode. */ +/* Information is UTF-16 encoded as wchar_ts */ + +#ifndef XML_UNICODE +#define XML_UNICODE +#endif + +#include +typedef wchar_t XML_Char; +typedef wchar_t XML_LChar; + +#else /* not XML_UNICODE_WCHAR_T */ + +#ifdef XML_UNICODE + +/* Information is UTF-16 encoded as unsigned shorts */ +typedef unsigned short XML_Char; +typedef char XML_LChar; + +#else /* not XML_UNICODE */ + +/* Information is UTF-8 encoded. */ +typedef char XML_Char; +typedef char XML_LChar; + +#endif /* not XML_UNICODE */ + +#endif /* not XML_UNICODE_WCHAR_T */ + + +/* Constructs a new parser; encoding is the encoding specified by the external +protocol or null if there is none specified. */ + +XML_Parser XMLPARSEAPI +XML_ParserCreate(const XML_Char *encoding); + + +/* atts is array of name/value pairs, terminated by 0; + names and values are 0 terminated. */ + +typedef void (*XML_StartElementHandler)(void *userData, + const XML_Char *name, + const XML_Char **atts); + +typedef void (*XML_EndElementHandler)(void *userData, + const XML_Char *name); + +/* s is not 0 terminated. */ +typedef void (*XML_CharacterDataHandler)(void *userData, + const XML_Char *s, + int len); + +/* target and data are 0 terminated */ +typedef void (*XML_ProcessingInstructionHandler)(void *userData, + const XML_Char *target, + const XML_Char *data); + +/* This is called for any characters in the XML document for +which there is no applicable handler. This includes both +characters that are part of markup which is of a kind that is +not reported (comments, markup declarations), or characters +that are part of a construct which could be reported but +for which no handler has been supplied. The characters are passed +exactly as they were in the XML document except that +they will be encoded in UTF-8. Line boundaries are not normalized. +Note that a byte order mark character is not passed to the default handler. +If a default handler is set, internal entity references +are not expanded. There are no guarantees about +how characters are divided between calls to the default handler: +for example, a comment might be split between multiple calls. */ + +typedef void (*XML_DefaultHandler)(void *userData, + const XML_Char *s, + int len); + +/* This is called for a declaration of an unparsed (NDATA) +entity. The base argument is whatever was set by XML_SetBase. +The entityName, systemId and notationName arguments will never be null. +The other arguments may be. */ + +typedef void (*XML_UnparsedEntityDeclHandler)(void *userData, + const XML_Char *entityName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +/* This is called for a declaration of notation. +The base argument is whatever was set by XML_SetBase. +The notationName will never be null. The other arguments can be. */ + +typedef void (*XML_NotationDeclHandler)(void *userData, + const XML_Char *notationName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* This is called for a reference to an external parsed general entity. +The referenced entity is not automatically parsed. +The application can parse it immediately or later using +XML_ExternalEntityParserCreate. +The parser argument is the parser parsing the entity containing the reference; +it can be passed as the parser argument to XML_ExternalEntityParserCreate. +The systemId argument is the system identifier as specified in the entity declaration; +it will not be null. +The base argument is the system identifier that should be used as the base for +resolving systemId if systemId was relative; this is set by XML_SetBase; +it may be null. +The publicId argument is the public identifier as specified in the entity declaration, +or null if none was specified; the whitespace in the public identifier +will have been normalized as required by the XML spec. +The openEntityNames argument is a space-separated list of the names of the entities +that are open for the parse of this entity (including the name of the referenced +entity); this can be passed as the openEntityNames argument to +XML_ExternalEntityParserCreate; openEntityNames is valid only until the handler +returns, so if the referenced entity is to be parsed later, it must be copied. +The handler should return 0 if processing should not continue because of +a fatal error in the handling of the external entity. +In this case the calling parser will return an XML_ERROR_EXTERNAL_ENTITY_HANDLING +error. +Note that unlike other handlers the first argument is the parser, not userData. */ + +typedef int (*XML_ExternalEntityRefHandler)(XML_Parser parser, + const XML_Char *openEntityNames, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* This structure is filled in by the XML_UnknownEncodingHandler +to provide information to the parser about encodings that are unknown +to the parser. +The map[b] member gives information about byte sequences +whose first byte is b. +If map[b] is c where c is >= 0, then b by itself encodes the Unicode scalar value c. +If map[b] is -1, then the byte sequence is malformed. +If map[b] is -n, where n >= 2, then b is the first byte of an n-byte +sequence that encodes a single Unicode scalar value. +The data member will be passed as the first argument to the convert function. +The convert function is used to convert multibyte sequences; +s will point to a n-byte sequence where map[(unsigned char)*s] == -n. +The convert function must return the Unicode scalar value +represented by this byte sequence or -1 if the byte sequence is malformed. +The convert function may be null if the encoding is a single-byte encoding, +that is if map[b] >= -1 for all bytes b. +When the parser is finished with the encoding, then if release is not null, +it will call release passing it the data member; +once release has been called, the convert function will not be called again. + +Expat places certain restrictions on the encodings that are supported +using this mechanism. + +1. Every ASCII character that can appear in a well-formed XML document, +other than the characters + + $@\^`{}~ + +must be represented by a single byte, and that byte must be the +same byte that represents that character in ASCII. + +2. No character may require more than 4 bytes to encode. + +3. All characters encoded must have Unicode scalar values <= 0xFFFF, +(ie characters that would be encoded by surrogates in UTF-16 +are not allowed). Note that this restriction doesn't apply to +the built-in support for UTF-8 and UTF-16. + +4. No Unicode character may be encoded by more than one distinct sequence +of bytes. */ + +typedef struct { + int map[256]; + void *data; + int (*convert)(void *data, const char *s); + void (*release)(void *data); +} XML_Encoding; + +/* This is called for an encoding that is unknown to the parser. +The encodingHandlerData argument is that which was passed as the +second argument to XML_SetUnknownEncodingHandler. +The name argument gives the name of the encoding as specified in +the encoding declaration. +If the callback can provide information about the encoding, +it must fill in the XML_Encoding structure, and return 1. +Otherwise it must return 0. +If info does not describe a suitable encoding, +then the parser will return an XML_UNKNOWN_ENCODING error. */ + +typedef int (*XML_UnknownEncodingHandler)(void *encodingHandlerData, + const XML_Char *name, + XML_Encoding *info); + +void XMLPARSEAPI +XML_SetElementHandler(XML_Parser parser, + XML_StartElementHandler start, + XML_EndElementHandler end); + +void XMLPARSEAPI +XML_SetCharacterDataHandler(XML_Parser parser, + XML_CharacterDataHandler handler); + +void XMLPARSEAPI +XML_SetProcessingInstructionHandler(XML_Parser parser, + XML_ProcessingInstructionHandler handler); + +void XMLPARSEAPI +XML_SetDefaultHandler(XML_Parser parser, + XML_DefaultHandler handler); + +void XMLPARSEAPI +XML_SetUnparsedEntityDeclHandler(XML_Parser parser, + XML_UnparsedEntityDeclHandler handler); + +void XMLPARSEAPI +XML_SetNotationDeclHandler(XML_Parser parser, + XML_NotationDeclHandler handler); + +void XMLPARSEAPI +XML_SetExternalEntityRefHandler(XML_Parser parser, + XML_ExternalEntityRefHandler handler); + +void XMLPARSEAPI +XML_SetUnknownEncodingHandler(XML_Parser parser, + XML_UnknownEncodingHandler handler, + void *encodingHandlerData); + +/* This can be called within a handler for a start element, end element, +processing instruction or character data. It causes the corresponding +markup to be passed to the default handler. +Within the expansion of an internal entity, nothing will be passed +to the default handler, although this usually will not happen since +setting a default handler inhibits expansion of internal entities. */ +void XMLPARSEAPI XML_DefaultCurrent(XML_Parser parser); + +/* This value is passed as the userData argument to callbacks. */ +void XMLPARSEAPI +XML_SetUserData(XML_Parser parser, void *userData); + +/* Returns the last value set by XML_SetUserData or null. */ +#define XML_GetUserData(parser) (*(void **)(parser)) + +/* If this function is called, then the parser will be passed +as the first argument to callbacks instead of userData. +The userData will still be accessible using XML_GetUserData. */ + +void XMLPARSEAPI +XML_UseParserAsHandlerArg(XML_Parser parser); + +/* Sets the base to be used for resolving relative URIs in system identifiers in +declarations. Resolving relative identifiers is left to the application: +this value will be passed through as the base argument to the +XML_ExternalEntityRefHandler, XML_NotationDeclHandler +and XML_UnparsedEntityDeclHandler. The base argument will be copied. +Returns zero if out of memory, non-zero otherwise. */ + +int XMLPARSEAPI +XML_SetBase(XML_Parser parser, const XML_Char *base); + +const XML_Char XMLPARSEAPI * +XML_GetBase(XML_Parser parser); + +/* Parses some input. Returns 0 if a fatal error is detected. +The last call to XML_Parse must have isFinal true; +len may be zero for this call (or any other). */ +int XMLPARSEAPI +XML_Parse(XML_Parser parser, const char *s, int len, int isFinal); + +void XMLPARSEAPI * +XML_GetBuffer(XML_Parser parser, int len); + +int XMLPARSEAPI +XML_ParseBuffer(XML_Parser parser, int len, int isFinal); + +/* Creates an XML_Parser object that can parse an external general entity; +openEntityNames is a space-separated list of the names of the entities that are open +for the parse of this entity (including the name of this one); +encoding is the externally specified encoding, +or null if there is no externally specified encoding. +This can be called at any point after the first call to an ExternalEntityRefHandler +so longer as the parser has not yet been freed. +The new parser is completely independent and may safely be used in a separate thread. +The handlers and userData are initialized from the parser argument. +Returns 0 if out of memory. Otherwise returns a new XML_Parser object. */ +XML_Parser XMLPARSEAPI +XML_ExternalEntityParserCreate(XML_Parser parser, + const XML_Char *openEntityNames, + const XML_Char *encoding); + +enum XML_Error { + XML_ERROR_NONE, + XML_ERROR_NO_MEMORY, + XML_ERROR_SYNTAX, + XML_ERROR_NO_ELEMENTS, + XML_ERROR_INVALID_TOKEN, + XML_ERROR_UNCLOSED_TOKEN, + XML_ERROR_PARTIAL_CHAR, + XML_ERROR_TAG_MISMATCH, + XML_ERROR_DUPLICATE_ATTRIBUTE, + XML_ERROR_JUNK_AFTER_DOC_ELEMENT, + XML_ERROR_PARAM_ENTITY_REF, + XML_ERROR_UNDEFINED_ENTITY, + XML_ERROR_RECURSIVE_ENTITY_REF, + XML_ERROR_ASYNC_ENTITY, + XML_ERROR_BAD_CHAR_REF, + XML_ERROR_BINARY_ENTITY_REF, + XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, + XML_ERROR_MISPLACED_XML_PI, + XML_ERROR_UNKNOWN_ENCODING, + XML_ERROR_INCORRECT_ENCODING, + XML_ERROR_UNCLOSED_CDATA_SECTION, + XML_ERROR_EXTERNAL_ENTITY_HANDLING +}; + +/* If XML_Parse or XML_ParseBuffer have returned 0, then XML_GetErrorCode +returns information about the error. */ + +enum XML_Error XMLPARSEAPI XML_GetErrorCode(XML_Parser parser); + +/* These functions return information about the current parse location. +They may be called when XML_Parse or XML_ParseBuffer return 0; +in this case the location is the location of the character at which +the error was detected. +They may also be called from any other callback called to report +some parse event; in this the location is the location of the first +of the sequence of characters that generated the event. */ + +int XMLPARSEAPI XML_GetCurrentLineNumber(XML_Parser parser); +int XMLPARSEAPI XML_GetCurrentColumnNumber(XML_Parser parser); +long XMLPARSEAPI XML_GetCurrentByteIndex(XML_Parser parser); + +/* For backwards compatibility with previous versions. */ +#define XML_GetErrorLineNumber XML_GetCurrentLineNumber +#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber +#define XML_GetErrorByteIndex XML_GetCurrentByteIndex + +/* Frees memory used by the parser. */ +void XMLPARSEAPI +XML_ParserFree(XML_Parser parser); + +/* Returns a string describing the error. */ +const XML_LChar XMLPARSEAPI *XML_ErrorString(int code); + +#ifdef __cplusplus +} +#endif + +#endif /* not XmlParse_INCLUDED */ diff --git a/mozilla/extensions/transformiix/source/xml/parser/xmltok/asciitab.h b/mozilla/extensions/transformiix/source/xml/parser/xmltok/asciitab.h new file mode 100644 index 00000000000..f7d78da4f82 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/xmltok/asciitab.h @@ -0,0 +1,52 @@ +/* +The contents of this file are subject to the Mozilla Public License +Version 1.0 (the "License"); you may not use this file except in +compliance with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" +basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific language governing rights and limitations +under the License. + +The Original Code is expat. + +The Initial Developer of the Original Code is James Clark. +Portions created by James Clark are Copyright (C) 1998 +James Clark. All Rights Reserved. + +Contributor(s): +*/ + +/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML, +/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML, +/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM, +/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS, +/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS, +/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL, +/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, +/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, +/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_NMSTRT, BT_SEMI, +/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST, +/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, +/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, +/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB, +/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT, +/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, +/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, +/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, +/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER, diff --git a/mozilla/extensions/transformiix/source/xml/parser/xmltok/dllmain.c b/mozilla/extensions/transformiix/source/xml/parser/xmltok/dllmain.c new file mode 100644 index 00000000000..579d6567e08 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/xmltok/dllmain.c @@ -0,0 +1,27 @@ +/* +The contents of this file are subject to the Mozilla Public License +Version 1.0 (the "License"); you may not use this file except in +compliance with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" +basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific language governing rights and limitations +under the License. + +The Original Code is expat. + +The Initial Developer of the Original Code is James Clark. +Portions created by James Clark are Copyright (C) 1998 +James Clark. All Rights Reserved. + +Contributor(s): +*/ + +#include + +BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) +{ + return TRUE; +} + diff --git a/mozilla/extensions/transformiix/source/xml/parser/xmltok/iasciitab.h b/mozilla/extensions/transformiix/source/xml/parser/xmltok/iasciitab.h new file mode 100644 index 00000000000..d894074771a --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/xmltok/iasciitab.h @@ -0,0 +1,53 @@ +/* +The contents of this file are subject to the Mozilla Public License +Version 1.0 (the "License"); you may not use this file except in +compliance with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" +basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific language governing rights and limitations +under the License. + +The Original Code is expat. + +The Initial Developer of the Original Code is James Clark. +Portions created by James Clark are Copyright (C) 1998 +James Clark. All Rights Reserved. + +Contributor(s): +*/ + +/* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */ +/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML, +/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML, +/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM, +/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS, +/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS, +/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL, +/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, +/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, +/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_NMSTRT, BT_SEMI, +/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST, +/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, +/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, +/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB, +/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT, +/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, +/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, +/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, +/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER, diff --git a/mozilla/extensions/transformiix/source/xml/parser/xmltok/latin1tab.h b/mozilla/extensions/transformiix/source/xml/parser/xmltok/latin1tab.h new file mode 100644 index 00000000000..378697512e6 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/xmltok/latin1tab.h @@ -0,0 +1,52 @@ +/* +The contents of this file are subject to the Mozilla Public License +Version 1.0 (the "License"); you may not use this file except in +compliance with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" +basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific language governing rights and limitations +under the License. + +The Original Code is expat. + +The Initial Developer of the Original Code is James Clark. +Portions created by James Clark are Copyright (C) 1998 +James Clark. All Rights Reserved. + +Contributor(s): +*/ + +/* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER, +/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME, +/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER, +/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, +/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, +/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, diff --git a/mozilla/extensions/transformiix/source/xml/parser/xmltok/nametab.h b/mozilla/extensions/transformiix/source/xml/parser/xmltok/nametab.h new file mode 100644 index 00000000000..b05e62c77a6 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/xmltok/nametab.h @@ -0,0 +1,150 @@ +static const unsigned namingBitmap[] = { +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, +0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, +0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE, +0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF, +0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF, +0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF, +0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF, +0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD, +0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF, +0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF, +0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE, +0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF, +0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000, +0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060, +0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003, +0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003, +0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000, +0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001, +0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003, +0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000, +0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003, +0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003, +0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000, +0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000, +0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF, +0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB, +0x40000000, 0xF580C900, 0x00000007, 0x02010800, +0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, +0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF, +0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF, +0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF, +0x00000000, 0x00004C40, 0x00000000, 0x00000000, +0x00000007, 0x00000000, 0x00000000, 0x00000000, +0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF, +0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF, +0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, +0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000, +0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, +0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000, +0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE, +0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF, +0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF, +0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000, +0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003, +0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD, +0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF, +0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF, +0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE, +0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF, +0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF, +0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF, +0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF, +0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF, +0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0, +0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1, +0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3, +0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80, +0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3, +0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3, +0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000, +0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000, +0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF, +0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x1FFF0000, 0x00000002, +0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF, +0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF, +}; +static const unsigned char nmstrtPages[] = { +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, +0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, +0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, +0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; +static const unsigned char namePages[] = { +0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00, +0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, +0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, +0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; diff --git a/mozilla/extensions/transformiix/source/xml/parser/xmltok/utf8tab.h b/mozilla/extensions/transformiix/source/xml/parser/xmltok/utf8tab.h new file mode 100644 index 00000000000..57ff8074c16 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/xmltok/utf8tab.h @@ -0,0 +1,53 @@ +/* +The contents of this file are subject to the Mozilla Public License +Version 1.0 (the "License"); you may not use this file except in +compliance with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" +basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific language governing rights and limitations +under the License. + +The Original Code is expat. + +The Initial Developer of the Original Code is James Clark. +Portions created by James Clark are Copyright (C) 1998 +James Clark. All Rights Reserved. + +Contributor(s): +*/ + + +/* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, +/* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, +/* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, +/* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, +/* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4, +/* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM, diff --git a/mozilla/extensions/transformiix/source/xml/parser/xmltok/xmldef.h b/mozilla/extensions/transformiix/source/xml/parser/xmltok/xmldef.h new file mode 100644 index 00000000000..48ba359ca04 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/xmltok/xmldef.h @@ -0,0 +1,32 @@ +/* +The contents of this file are subject to the Mozilla Public License +Version 1.0 (the "License"); you may not use this file except in +compliance with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" +basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific language governing rights and limitations +under the License. + +The Original Code is expat. + +The Initial Developer of the Original Code is James Clark. +Portions created by James Clark are Copyright (C) 1998 +James Clark. All Rights Reserved. + +Contributor(s): +*/ + +/* This file can be used for any definitions needed in +particular environments. */ + +#ifdef MOZILLA + +#include "nspr.h" +#define malloc(x) PR_Calloc(1,(x)) +#define calloc(x, y) PR_Calloc((x),(y)) +#define free(x) PR_Free(x) +#define int int32 + +#endif /* MOZILLA */ diff --git a/mozilla/extensions/transformiix/source/xml/parser/xmltok/xmlrole.c b/mozilla/extensions/transformiix/source/xml/parser/xmltok/xmlrole.c new file mode 100644 index 00000000000..72be89bff8f --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/xmltok/xmlrole.c @@ -0,0 +1,1095 @@ +/* +The contents of this file are subject to the Mozilla Public License +Version 1.0 (the "License"); you may not use this file except in +compliance with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" +basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific language governing rights and limitations +under the License. + +The Original Code is expat. + +The Initial Developer of the Original Code is James Clark. +Portions created by James Clark are Copyright (C) 1998 +James Clark. All Rights Reserved. + +Contributor(s): +*/ + +#include "xmldef.h" +#include "xmlrole.h" + +/* Doesn't check: + + that ,| are not mixed in a model group + content of literals + +*/ + +#ifndef MIN_BYTES_PER_CHAR +#define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar) +#endif + +typedef int PROLOG_HANDLER(struct prolog_state *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc); + +static PROLOG_HANDLER + prolog0, prolog1, prolog2, + doctype0, doctype1, doctype2, doctype3, doctype4, doctype5, + internalSubset, + entity0, entity1, entity2, entity3, entity4, entity5, entity6, + entity7, entity8, entity9, + notation0, notation1, notation2, notation3, notation4, + attlist0, attlist1, attlist2, attlist3, attlist4, attlist5, attlist6, + attlist7, attlist8, attlist9, + element0, element1, element2, element3, element4, element5, element6, + element7, + declClose, + error; + +static +int syntaxError(PROLOG_STATE *); + +static +int prolog0(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + state->handler = prolog1; + return XML_ROLE_NONE; + case XML_TOK_XML_DECL: + state->handler = prolog1; + return XML_ROLE_XML_DECL; + case XML_TOK_PI: + state->handler = prolog1; + return XML_ROLE_NONE; + case XML_TOK_COMMENT: + state->handler = prolog1; + case XML_TOK_BOM: + return XML_ROLE_NONE; + case XML_TOK_DECL_OPEN: + if (!XmlNameMatchesAscii(enc, + ptr + 2 * MIN_BYTES_PER_CHAR(enc), + "DOCTYPE")) + break; + state->handler = doctype0; + return XML_ROLE_NONE; + case XML_TOK_INSTANCE_START: + state->handler = error; + return XML_ROLE_INSTANCE_START; + } + return syntaxError(state); +} + +static +int prolog1(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_PI: + case XML_TOK_COMMENT: + case XML_TOK_BOM: + return XML_ROLE_NONE; + case XML_TOK_DECL_OPEN: + if (!XmlNameMatchesAscii(enc, + ptr + 2 * MIN_BYTES_PER_CHAR(enc), + "DOCTYPE")) + break; + state->handler = doctype0; + return XML_ROLE_NONE; + case XML_TOK_INSTANCE_START: + state->handler = error; + return XML_ROLE_INSTANCE_START; + } + return syntaxError(state); +} + +static +int prolog2(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_PI: + case XML_TOK_COMMENT: + return XML_ROLE_NONE; + case XML_TOK_INSTANCE_START: + state->handler = error; + return XML_ROLE_INSTANCE_START; + } + return syntaxError(state); +} + +static +int doctype0(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + state->handler = doctype1; + return XML_ROLE_DOCTYPE_NAME; + } + return syntaxError(state); +} + +static +int doctype1(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_OPEN_BRACKET: + state->handler = internalSubset; + return XML_ROLE_NONE; + case XML_TOK_DECL_CLOSE: + state->handler = prolog2; + return XML_ROLE_DOCTYPE_CLOSE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, "SYSTEM")) { + state->handler = doctype3; + return XML_ROLE_NONE; + } + if (XmlNameMatchesAscii(enc, ptr, "PUBLIC")) { + state->handler = doctype2; + return XML_ROLE_NONE; + } + break; + } + return syntaxError(state); +} + +static +int doctype2(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_LITERAL: + state->handler = doctype3; + return XML_ROLE_DOCTYPE_PUBLIC_ID; + } + return syntaxError(state); +} + +static +int doctype3(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_LITERAL: + state->handler = doctype4; + return XML_ROLE_DOCTYPE_SYSTEM_ID; + } + return syntaxError(state); +} + +static +int doctype4(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_OPEN_BRACKET: + state->handler = internalSubset; + return XML_ROLE_NONE; + case XML_TOK_DECL_CLOSE: + state->handler = prolog2; + return XML_ROLE_DOCTYPE_CLOSE; + } + return syntaxError(state); +} + +static +int doctype5(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_DECL_CLOSE: + state->handler = prolog2; + return XML_ROLE_DOCTYPE_CLOSE; + } + return syntaxError(state); +} + +static +int internalSubset(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_DECL_OPEN: + if (XmlNameMatchesAscii(enc, + ptr + 2 * MIN_BYTES_PER_CHAR(enc), + "ENTITY")) { + state->handler = entity0; + return XML_ROLE_NONE; + } + if (XmlNameMatchesAscii(enc, + ptr + 2 * MIN_BYTES_PER_CHAR(enc), + "ATTLIST")) { + state->handler = attlist0; + return XML_ROLE_NONE; + } + if (XmlNameMatchesAscii(enc, + ptr + 2 * MIN_BYTES_PER_CHAR(enc), + "ELEMENT")) { + state->handler = element0; + return XML_ROLE_NONE; + } + if (XmlNameMatchesAscii(enc, + ptr + 2 * MIN_BYTES_PER_CHAR(enc), + "NOTATION")) { + state->handler = notation0; + return XML_ROLE_NONE; + } + break; + case XML_TOK_PI: + case XML_TOK_COMMENT: + return XML_ROLE_NONE; + case XML_TOK_PARAM_ENTITY_REF: + return XML_ROLE_PARAM_ENTITY_REF; + case XML_TOK_CLOSE_BRACKET: + state->handler = doctype5; + return XML_ROLE_NONE; + } + return syntaxError(state); +} + +static +int entity0(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_PERCENT: + state->handler = entity1; + return XML_ROLE_NONE; + case XML_TOK_NAME: + state->handler = entity2; + return XML_ROLE_GENERAL_ENTITY_NAME; + } + return syntaxError(state); +} + +static +int entity1(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + state->handler = entity7; + return XML_ROLE_PARAM_ENTITY_NAME; + } + return syntaxError(state); +} + +static +int entity2(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, "SYSTEM")) { + state->handler = entity4; + return XML_ROLE_NONE; + } + if (XmlNameMatchesAscii(enc, ptr, "PUBLIC")) { + state->handler = entity3; + return XML_ROLE_NONE; + } + break; + case XML_TOK_LITERAL: + state->handler = declClose; + return XML_ROLE_ENTITY_VALUE; + } + return syntaxError(state); +} + +static +int entity3(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_LITERAL: + state->handler = entity4; + return XML_ROLE_ENTITY_PUBLIC_ID; + } + return syntaxError(state); +} + + +static +int entity4(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_LITERAL: + state->handler = entity5; + return XML_ROLE_ENTITY_SYSTEM_ID; + } + return syntaxError(state); +} + +static +int entity5(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_DECL_CLOSE: + state->handler = internalSubset; + return XML_ROLE_NONE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, "NDATA")) { + state->handler = entity6; + return XML_ROLE_NONE; + } + break; + } + return syntaxError(state); +} + +static +int entity6(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + state->handler = declClose; + return XML_ROLE_ENTITY_NOTATION_NAME; + } + return syntaxError(state); +} + +static +int entity7(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, "SYSTEM")) { + state->handler = entity9; + return XML_ROLE_NONE; + } + if (XmlNameMatchesAscii(enc, ptr, "PUBLIC")) { + state->handler = entity8; + return XML_ROLE_NONE; + } + break; + case XML_TOK_LITERAL: + state->handler = declClose; + return XML_ROLE_ENTITY_VALUE; + } + return syntaxError(state); +} + +static +int entity8(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_LITERAL: + state->handler = entity9; + return XML_ROLE_ENTITY_PUBLIC_ID; + } + return syntaxError(state); +} + +static +int entity9(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_LITERAL: + state->handler = declClose; + return XML_ROLE_ENTITY_SYSTEM_ID; + } + return syntaxError(state); +} + +static +int notation0(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + state->handler = notation1; + return XML_ROLE_NOTATION_NAME; + } + return syntaxError(state); +} + +static +int notation1(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, "SYSTEM")) { + state->handler = notation3; + return XML_ROLE_NONE; + } + if (XmlNameMatchesAscii(enc, ptr, "PUBLIC")) { + state->handler = notation2; + return XML_ROLE_NONE; + } + break; + } + return syntaxError(state); +} + +static +int notation2(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_LITERAL: + state->handler = notation4; + return XML_ROLE_NOTATION_PUBLIC_ID; + } + return syntaxError(state); +} + +static +int notation3(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_LITERAL: + state->handler = declClose; + return XML_ROLE_NOTATION_SYSTEM_ID; + } + return syntaxError(state); +} + +static +int notation4(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_LITERAL: + state->handler = declClose; + return XML_ROLE_NOTATION_SYSTEM_ID; + case XML_TOK_DECL_CLOSE: + state->handler = internalSubset; + return XML_ROLE_NOTATION_NO_SYSTEM_ID; + } + return syntaxError(state); +} + +static +int attlist0(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + state->handler = attlist1; + return XML_ROLE_ATTLIST_ELEMENT_NAME; + } + return syntaxError(state); +} + +static +int attlist1(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_DECL_CLOSE: + state->handler = internalSubset; + return XML_ROLE_NONE; + case XML_TOK_NAME: + state->handler = attlist2; + return XML_ROLE_ATTRIBUTE_NAME; + } + return syntaxError(state); +} + +static +int attlist2(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + { + static const char *types[] = { + "CDATA", + "ID", + "IDREF", + "IDREFS", + "ENTITY", + "ENTITIES", + "NMTOKEN", + "NMTOKENS", + }; + int i; + for (i = 0; i < (int)(sizeof(types)/sizeof(types[0])); i++) + if (XmlNameMatchesAscii(enc, ptr, types[i])) { + state->handler = attlist8; + return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i; + } + } + if (XmlNameMatchesAscii(enc, ptr, "NOTATION")) { + state->handler = attlist5; + return XML_ROLE_NONE; + } + break; + case XML_TOK_OPEN_PAREN: + state->handler = attlist3; + return XML_ROLE_NONE; + } + return syntaxError(state); +} + +static +int attlist3(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NMTOKEN: + case XML_TOK_NAME: + state->handler = attlist4; + return XML_ROLE_ATTRIBUTE_ENUM_VALUE; + } + return syntaxError(state); +} + +static +int attlist4(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_CLOSE_PAREN: + state->handler = attlist8; + return XML_ROLE_NONE; + case XML_TOK_OR: + state->handler = attlist3; + return XML_ROLE_NONE; + } + return syntaxError(state); +} + +static +int attlist5(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_OPEN_PAREN: + state->handler = attlist6; + return XML_ROLE_NONE; + } + return syntaxError(state); +} + + +static +int attlist6(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + state->handler = attlist7; + return XML_ROLE_ATTRIBUTE_NOTATION_VALUE; + } + return syntaxError(state); +} + +static +int attlist7(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_CLOSE_PAREN: + state->handler = attlist8; + return XML_ROLE_NONE; + case XML_TOK_OR: + state->handler = attlist6; + return XML_ROLE_NONE; + } + return syntaxError(state); +} + +/* default value */ +static +int attlist8(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_POUND_NAME: + if (XmlNameMatchesAscii(enc, + ptr + MIN_BYTES_PER_CHAR(enc), + "IMPLIED")) { + state->handler = attlist1; + return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE; + } + if (XmlNameMatchesAscii(enc, + ptr + MIN_BYTES_PER_CHAR(enc), + "REQUIRED")) { + state->handler = attlist1; + return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE; + } + if (XmlNameMatchesAscii(enc, + ptr + MIN_BYTES_PER_CHAR(enc), + "FIXED")) { + state->handler = attlist9; + return XML_ROLE_NONE; + } + break; + case XML_TOK_LITERAL: + state->handler = attlist1; + return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE; + } + return syntaxError(state); +} + +static +int attlist9(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_LITERAL: + state->handler = attlist1; + return XML_ROLE_FIXED_ATTRIBUTE_VALUE; + } + return syntaxError(state); +} + +static +int element0(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + state->handler = element1; + return XML_ROLE_ELEMENT_NAME; + } + return syntaxError(state); +} + +static +int element1(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + if (XmlNameMatchesAscii(enc, ptr, "EMPTY")) { + state->handler = declClose; + return XML_ROLE_CONTENT_EMPTY; + } + if (XmlNameMatchesAscii(enc, ptr, "ANY")) { + state->handler = declClose; + return XML_ROLE_CONTENT_ANY; + } + break; + case XML_TOK_OPEN_PAREN: + state->handler = element2; + state->level = 1; + return XML_ROLE_GROUP_OPEN; + } + return syntaxError(state); +} + +static +int element2(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_POUND_NAME: + if (XmlNameMatchesAscii(enc, + ptr + MIN_BYTES_PER_CHAR(enc), + "PCDATA")) { + state->handler = element3; + return XML_ROLE_CONTENT_PCDATA; + } + break; + case XML_TOK_OPEN_PAREN: + state->level = 2; + state->handler = element6; + return XML_ROLE_GROUP_OPEN; + case XML_TOK_NAME: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT; + case XML_TOK_NAME_QUESTION: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_OPT; + case XML_TOK_NAME_ASTERISK: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_REP; + case XML_TOK_NAME_PLUS: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_PLUS; + } + return syntaxError(state); +} + +static +int element3(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_CLOSE_PAREN: + case XML_TOK_CLOSE_PAREN_ASTERISK: + state->handler = declClose; + return XML_ROLE_GROUP_CLOSE_REP; + case XML_TOK_OR: + state->handler = element4; + return XML_ROLE_NONE; + } + return syntaxError(state); +} + +static +int element4(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_NAME: + state->handler = element5; + return XML_ROLE_CONTENT_ELEMENT; + } + return syntaxError(state); +} + +static +int element5(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_CLOSE_PAREN_ASTERISK: + state->handler = declClose; + return XML_ROLE_GROUP_CLOSE_REP; + case XML_TOK_OR: + state->handler = element4; + return XML_ROLE_NONE; + } + return syntaxError(state); +} + +static +int element6(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_OPEN_PAREN: + state->level += 1; + return XML_ROLE_GROUP_OPEN; + case XML_TOK_NAME: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT; + case XML_TOK_NAME_QUESTION: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_OPT; + case XML_TOK_NAME_ASTERISK: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_REP; + case XML_TOK_NAME_PLUS: + state->handler = element7; + return XML_ROLE_CONTENT_ELEMENT_PLUS; + } + return syntaxError(state); +} + +static +int element7(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_CLOSE_PAREN: + state->level -= 1; + if (state->level == 0) + state->handler = declClose; + return XML_ROLE_GROUP_CLOSE; + case XML_TOK_CLOSE_PAREN_ASTERISK: + state->level -= 1; + if (state->level == 0) + state->handler = declClose; + return XML_ROLE_GROUP_CLOSE_REP; + case XML_TOK_CLOSE_PAREN_QUESTION: + state->level -= 1; + if (state->level == 0) + state->handler = declClose; + return XML_ROLE_GROUP_CLOSE_OPT; + case XML_TOK_CLOSE_PAREN_PLUS: + state->level -= 1; + if (state->level == 0) + state->handler = declClose; + return XML_ROLE_GROUP_CLOSE_PLUS; + case XML_TOK_COMMA: + state->handler = element6; + return XML_ROLE_GROUP_SEQUENCE; + case XML_TOK_OR: + state->handler = element6; + return XML_ROLE_GROUP_CHOICE; + } + return syntaxError(state); +} + +static +int declClose(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_PROLOG_S: + return XML_ROLE_NONE; + case XML_TOK_DECL_CLOSE: + state->handler = internalSubset; + return XML_ROLE_NONE; + } + return syntaxError(state); +} + +#if 0 + +static +int ignore(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + switch (tok) { + case XML_TOK_DECL_CLOSE: + state->handler = internalSubset; + return 0; + default: + return XML_ROLE_NONE; + } + return syntaxError(state); +} +#endif + +static +int error(PROLOG_STATE *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc) +{ + return XML_ROLE_NONE; +} + +static +int syntaxError(PROLOG_STATE *state) +{ + state->handler = error; + return XML_ROLE_ERROR; +} + +void XmlPrologStateInit(PROLOG_STATE *state) +{ + state->handler = prolog0; +} diff --git a/mozilla/extensions/transformiix/source/xml/parser/xmltok/xmlrole.h b/mozilla/extensions/transformiix/source/xml/parser/xmltok/xmlrole.h new file mode 100644 index 00000000000..ecbcc26dff0 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/xmltok/xmlrole.h @@ -0,0 +1,101 @@ +/* +The contents of this file are subject to the Mozilla Public License +Version 1.0 (the "License"); you may not use this file except in +compliance with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" +basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific language governing rights and limitations +under the License. + +The Original Code is expat. + +The Initial Developer of the Original Code is James Clark. +Portions created by James Clark are Copyright (C) 1998 +James Clark. All Rights Reserved. + +Contributor(s): +*/ + +#ifndef XmlRole_INCLUDED +#define XmlRole_INCLUDED 1 + +#include "xmltok.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + XML_ROLE_ERROR = -1, + XML_ROLE_NONE = 0, + XML_ROLE_XML_DECL, + XML_ROLE_INSTANCE_START, + XML_ROLE_DOCTYPE_NAME, + XML_ROLE_DOCTYPE_SYSTEM_ID, + XML_ROLE_DOCTYPE_PUBLIC_ID, + XML_ROLE_DOCTYPE_CLOSE, + XML_ROLE_GENERAL_ENTITY_NAME, + XML_ROLE_PARAM_ENTITY_NAME, + XML_ROLE_ENTITY_VALUE, + XML_ROLE_ENTITY_SYSTEM_ID, + XML_ROLE_ENTITY_PUBLIC_ID, + XML_ROLE_ENTITY_NOTATION_NAME, + XML_ROLE_NOTATION_NAME, + XML_ROLE_NOTATION_SYSTEM_ID, + XML_ROLE_NOTATION_NO_SYSTEM_ID, + XML_ROLE_NOTATION_PUBLIC_ID, + XML_ROLE_ATTRIBUTE_NAME, + XML_ROLE_ATTRIBUTE_TYPE_CDATA, + XML_ROLE_ATTRIBUTE_TYPE_ID, + XML_ROLE_ATTRIBUTE_TYPE_IDREF, + XML_ROLE_ATTRIBUTE_TYPE_IDREFS, + XML_ROLE_ATTRIBUTE_TYPE_ENTITY, + XML_ROLE_ATTRIBUTE_TYPE_ENTITIES, + XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN, + XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS, + XML_ROLE_ATTRIBUTE_ENUM_VALUE, + XML_ROLE_ATTRIBUTE_NOTATION_VALUE, + XML_ROLE_ATTLIST_ELEMENT_NAME, + XML_ROLE_IMPLIED_ATTRIBUTE_VALUE, + XML_ROLE_REQUIRED_ATTRIBUTE_VALUE, + XML_ROLE_DEFAULT_ATTRIBUTE_VALUE, + XML_ROLE_FIXED_ATTRIBUTE_VALUE, + XML_ROLE_ELEMENT_NAME, + XML_ROLE_CONTENT_ANY, + XML_ROLE_CONTENT_EMPTY, + XML_ROLE_CONTENT_PCDATA, + XML_ROLE_GROUP_OPEN, + XML_ROLE_GROUP_CLOSE, + XML_ROLE_GROUP_CLOSE_REP, + XML_ROLE_GROUP_CLOSE_OPT, + XML_ROLE_GROUP_CLOSE_PLUS, + XML_ROLE_GROUP_CHOICE, + XML_ROLE_GROUP_SEQUENCE, + XML_ROLE_CONTENT_ELEMENT, + XML_ROLE_CONTENT_ELEMENT_REP, + XML_ROLE_CONTENT_ELEMENT_OPT, + XML_ROLE_CONTENT_ELEMENT_PLUS, + XML_ROLE_PARAM_ENTITY_REF +}; + +typedef struct prolog_state { + int (*handler)(struct prolog_state *state, + int tok, + const char *ptr, + const char *end, + const ENCODING *enc); + unsigned level; +} PROLOG_STATE; + +void XMLTOKAPI XmlPrologStateInit(PROLOG_STATE *); + +#define XmlTokenRole(state, tok, ptr, end, enc) \ + (((state)->handler)(state, tok, ptr, end, enc)) + +#ifdef __cplusplus +} +#endif + +#endif /* not XmlRole_INCLUDED */ diff --git a/mozilla/extensions/transformiix/source/xml/parser/xmltok/xmltok.c b/mozilla/extensions/transformiix/source/xml/parser/xmltok/xmltok.c new file mode 100644 index 00000000000..281b318efbb --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/xmltok/xmltok.c @@ -0,0 +1,1141 @@ +/* +The contents of this file are subject to the Mozilla Public License +Version 1.0 (the "License"); you may not use this file except in +compliance with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" +basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific language governing rights and limitations +under the License. + +The Original Code is expat. + +The Initial Developer of the Original Code is James Clark. +Portions created by James Clark are Copyright (C) 1998 +James Clark. All Rights Reserved. + +Contributor(s): +*/ + +#include "xmldef.h" +#include "xmltok.h" +#include "nametab.h" + +#define VTABLE1 \ + { PREFIX(prologTok), PREFIX(contentTok), PREFIX(cdataSectionTok) }, \ + { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \ + PREFIX(sameName), \ + PREFIX(nameMatchesAscii), \ + PREFIX(nameLength), \ + PREFIX(skipS), \ + PREFIX(getAtts), \ + PREFIX(charRefNumber), \ + PREFIX(predefinedEntityName), \ + PREFIX(updatePosition), \ + PREFIX(isPublicId) + +#define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16) + +#define UCS2_GET_NAMING(pages, hi, lo) \ + (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F))) + +/* A 2 byte UTF-8 representation splits the characters 11 bits +between the bottom 5 and 6 bits of the bytes. +We need 8 bits to index into pages, 3 bits to add to that index and +5 bits to generate the mask. */ +#define UTF8_GET_NAMING2(pages, byte) \ + (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \ + + ((((byte)[0]) & 3) << 1) \ + + ((((byte)[1]) >> 5) & 1)] \ + & (1 << (((byte)[1]) & 0x1F))) + +/* A 3 byte UTF-8 representation splits the characters 16 bits +between the bottom 4, 6 and 6 bits of the bytes. +We need 8 bits to index into pages, 3 bits to add to that index and +5 bits to generate the mask. */ +#define UTF8_GET_NAMING3(pages, byte) \ + (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \ + + ((((byte)[1]) >> 2) & 0xF)] \ + << 3) \ + + ((((byte)[1]) & 3) << 1) \ + + ((((byte)[2]) >> 5) & 1)] \ + & (1 << (((byte)[2]) & 0x1F))) + +#define UTF8_GET_NAMING(pages, p, n) \ + ((n) == 2 \ + ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \ + : ((n) == 3 \ + ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \ + : 0)) + +#define UTF8_INVALID3(p) \ + ((*p) == 0xED \ + ? (((p)[1] & 0x20) != 0) \ + : ((*p) == 0xEF \ + ? ((p)[1] == 0xBF && ((p)[2] == 0xBF || (p)[2] == 0xBE)) \ + : 0)) + +#define UTF8_INVALID4(p) ((*p) == 0xF4 && ((p)[1] & 0x30) != 0) + +static +int isNever(const ENCODING *enc, const char *p) +{ + return 0; +} + +static +int utf8_isName2(const ENCODING *enc, const char *p) +{ + return UTF8_GET_NAMING2(namePages, (const unsigned char *)p); +} + +static +int utf8_isName3(const ENCODING *enc, const char *p) +{ + return UTF8_GET_NAMING3(namePages, (const unsigned char *)p); +} + +#define utf8_isName4 isNever + +static +int utf8_isNmstrt2(const ENCODING *enc, const char *p) +{ + return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p); +} + +static +int utf8_isNmstrt3(const ENCODING *enc, const char *p) +{ + return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p); +} + +#define utf8_isNmstrt4 isNever + +#define utf8_isInvalid2 isNever + +static +int utf8_isInvalid3(const ENCODING *enc, const char *p) +{ + return UTF8_INVALID3((const unsigned char *)p); +} + +static +int utf8_isInvalid4(const ENCODING *enc, const char *p) +{ + return UTF8_INVALID4((const unsigned char *)p); +} + +struct normal_encoding { + ENCODING enc; + unsigned char type[256]; + int (*isName2)(const ENCODING *, const char *); + int (*isName3)(const ENCODING *, const char *); + int (*isName4)(const ENCODING *, const char *); + int (*isNmstrt2)(const ENCODING *, const char *); + int (*isNmstrt3)(const ENCODING *, const char *); + int (*isNmstrt4)(const ENCODING *, const char *); + int (*isInvalid2)(const ENCODING *, const char *); + int (*isInvalid3)(const ENCODING *, const char *); + int (*isInvalid4)(const ENCODING *, const char *); +}; + +#define NORMAL_VTABLE(E) \ + E ## isName2, \ + E ## isName3, \ + E ## isName4, \ + E ## isNmstrt2, \ + E ## isNmstrt3, \ + E ## isNmstrt4, \ + E ## isInvalid2, \ + E ## isInvalid3, \ + E ## isInvalid4 + +static int checkCharRefNumber(int); + +#include "xmltok_impl.h" + +/* minimum bytes per character */ +#define MINBPC 1 +#define BYTE_TYPE(enc, p) \ + (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)]) +#define BYTE_TO_ASCII(enc, p) (*p) + +#define IS_NAME_CHAR(enc, p, n) \ + (((const struct normal_encoding *)(enc))->isName ## n(enc, p)) +#define IS_NMSTRT_CHAR(enc, p, n) \ + (((const struct normal_encoding *)(enc))->isNmstrt ## n(enc, p)) +#define IS_INVALID_CHAR(enc, p, n) \ + (((const struct normal_encoding *)(enc))->isInvalid ## n(enc, p)) + +#define IS_NAME_CHAR_MINBPC(enc, p) (0) +#define IS_NMSTRT_CHAR_MINBPC(enc, p) (0) + +/* c is an ASCII character */ +#define CHAR_MATCHES(enc, p, c) (*(p) == c) + +#define PREFIX(ident) normal_ ## ident +#include "xmltok_impl.c" + +#undef MINBPC +#undef BYTE_TYPE +#undef BYTE_TO_ASCII +#undef CHAR_MATCHES +#undef IS_NAME_CHAR +#undef IS_NAME_CHAR_MINBPC +#undef IS_NMSTRT_CHAR +#undef IS_NMSTRT_CHAR_MINBPC +#undef IS_INVALID_CHAR + +enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */ + UTF8_cval1 = 0x00, + UTF8_cval2 = 0xc0, + UTF8_cval3 = 0xe0, + UTF8_cval4 = 0xf0 +}; + +static +void utf8_toUtf8(const ENCODING *enc, + const char **fromP, const char *fromLim, + char **toP, const char *toLim) +{ + char *to; + const char *from; + if (fromLim - *fromP > toLim - *toP) { + /* Avoid copying partial characters. */ + for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--) + if (((unsigned char)fromLim[-1] & 0xc0) != 0x80) + break; + } + for (to = *toP, from = *fromP; from != fromLim; from++, to++) + *to = *from; + *fromP = from; + *toP = to; +} + +static +void utf8_toUtf16(const ENCODING *enc, + const char **fromP, const char *fromLim, + unsigned short **toP, const unsigned short *toLim) +{ + unsigned short *to = *toP; + const char *from = *fromP; + while (from != fromLim && to != toLim) { + switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) { + case BT_LEAD2: + *to++ = ((from[0] & 0x1f) << 6) | (from[1] & 0x3f); + from += 2; + break; + case BT_LEAD3: + *to++ = ((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f); + from += 3; + break; + case BT_LEAD4: + { + unsigned long n; + if (to + 1 == toLim) + break; + n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12) | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f); + n -= 0x10000; + to[0] = (unsigned short)((n >> 10) | 0xD800); + to[1] = (unsigned short)((n & 0x3FF) | 0xDC00); + to += 2; + from += 4; + } + break; + default: + *to++ = *from++; + break; + } + } + *fromP = from; + *toP = to; +} + +static const struct normal_encoding utf8_encoding = { + { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, + { +#include "asciitab.h" +#include "utf8tab.h" + }, + NORMAL_VTABLE(utf8_) +}; + +static const struct normal_encoding internal_utf8_encoding = { + { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, + { +#include "iasciitab.h" +#include "utf8tab.h" + }, + NORMAL_VTABLE(utf8_) +}; + +static +void latin1_toUtf8(const ENCODING *enc, + const char **fromP, const char *fromLim, + char **toP, const char *toLim) +{ + for (;;) { + unsigned char c; + if (*fromP == fromLim) + break; + c = (unsigned char)**fromP; + if (c & 0x80) { + if (toLim - *toP < 2) + break; + *(*toP)++ = ((c >> 6) | UTF8_cval2); + *(*toP)++ = ((c & 0x3f) | 0x80); + (*fromP)++; + } + else { + if (*toP == toLim) + break; + *(*toP)++ = *(*fromP)++; + } + } +} + +static +void latin1_toUtf16(const ENCODING *enc, + const char **fromP, const char *fromLim, + unsigned short **toP, const unsigned short *toLim) +{ + while (*fromP != fromLim && *toP != toLim) + *(*toP)++ = (unsigned char)*(*fromP)++; +} + +static const struct normal_encoding latin1_encoding = { + { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 }, + { +#include "asciitab.h" +#include "latin1tab.h" + } +}; + +static +void ascii_toUtf8(const ENCODING *enc, + const char **fromP, const char *fromLim, + char **toP, const char *toLim) +{ + while (*fromP != fromLim && *toP != toLim) + *(*toP)++ = *(*fromP)++; +} + +static const struct normal_encoding ascii_encoding = { + { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 }, + { +#include "asciitab.h" +/* BT_NONXML == 0 */ + } +}; + +#undef PREFIX + +static int unicode_byte_type(char hi, char lo) +{ + switch ((unsigned char)hi) { + case 0xD8: case 0xD9: case 0xDA: case 0xDB: + return BT_LEAD4; + case 0xDC: case 0xDD: case 0xDE: case 0xDF: + return BT_TRAIL; + case 0xFF: + switch ((unsigned char)lo) { + case 0xFF: + case 0xFE: + return BT_NONXML; + } + break; + } + return BT_NONASCII; +} + +#define DEFINE_UTF16_TO_UTF8 \ +static \ +void PREFIX(toUtf8)(const ENCODING *enc, \ + const char **fromP, const char *fromLim, \ + char **toP, const char *toLim) \ +{ \ + const char *from; \ + for (from = *fromP; from != fromLim; from += 2) { \ + int plane; \ + unsigned char lo2; \ + unsigned char lo = GET_LO(from); \ + unsigned char hi = GET_HI(from); \ + switch (hi) { \ + case 0: \ + if (lo < 0x80) { \ + if (*toP == toLim) { \ + *fromP = from; \ + return; \ + } \ + *(*toP)++ = lo; \ + break; \ + } \ + /* fall through */ \ + case 0x1: case 0x2: case 0x3: \ + case 0x4: case 0x5: case 0x6: case 0x7: \ + if (toLim - *toP < 2) { \ + *fromP = from; \ + return; \ + } \ + *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \ + *(*toP)++ = ((lo & 0x3f) | 0x80); \ + break; \ + default: \ + if (toLim - *toP < 3) { \ + *fromP = from; \ + return; \ + } \ + /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \ + *(*toP)++ = ((hi >> 4) | UTF8_cval3); \ + *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \ + *(*toP)++ = ((lo & 0x3f) | 0x80); \ + break; \ + case 0xD8: case 0xD9: case 0xDA: case 0xDB: \ + if (toLim - *toP < 4) { \ + *fromP = from; \ + return; \ + } \ + plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \ + *(*toP)++ = ((plane >> 2) | UTF8_cval4); \ + *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \ + from += 2; \ + lo2 = GET_LO(from); \ + *(*toP)++ = (((lo & 0x3) << 4) \ + | ((GET_HI(from) & 0x3) << 2) \ + | (lo2 >> 6) \ + | 0x80); \ + *(*toP)++ = ((lo2 & 0x3f) | 0x80); \ + break; \ + } \ + } \ + *fromP = from; \ +} + +#define DEFINE_UTF16_TO_UTF16 \ +static \ +void PREFIX(toUtf16)(const ENCODING *enc, \ + const char **fromP, const char *fromLim, \ + unsigned short **toP, const unsigned short *toLim) \ +{ \ + /* Avoid copying first half only of surrogate */ \ + if (fromLim - *fromP > ((toLim - *toP) << 1) \ + && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) \ + fromLim -= 2; \ + for (; *fromP != fromLim && *toP != toLim; *fromP += 2) \ + *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \ +} + +#define PREFIX(ident) little2_ ## ident +#define MINBPC 2 +#define BYTE_TYPE(enc, p) \ + ((p)[1] == 0 \ + ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \ + : unicode_byte_type((p)[1], (p)[0])) +#define BYTE_TO_ASCII(enc, p) ((p)[1] == 0 ? (p)[0] : -1) +#define CHAR_MATCHES(enc, p, c) ((p)[1] == 0 && (p)[0] == c) +#define IS_NAME_CHAR(enc, p, n) (0) +#define IS_NAME_CHAR_MINBPC(enc, p) \ + UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0]) +#define IS_NMSTRT_CHAR(enc, p, n) (0) +#define IS_NMSTRT_CHAR_MINBPC(enc, p) \ + UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0]) + +#include "xmltok_impl.c" + +#define SET2(ptr, ch) \ + (((ptr)[0] = ((ch) & 0xff)), ((ptr)[1] = ((ch) >> 8))) +#define GET_LO(ptr) ((unsigned char)(ptr)[0]) +#define GET_HI(ptr) ((unsigned char)(ptr)[1]) + +DEFINE_UTF16_TO_UTF8 +DEFINE_UTF16_TO_UTF16 + +#undef SET2 +#undef GET_LO +#undef GET_HI +#undef MINBPC +#undef BYTE_TYPE +#undef BYTE_TO_ASCII +#undef CHAR_MATCHES +#undef IS_NAME_CHAR +#undef IS_NAME_CHAR_MINBPC +#undef IS_NMSTRT_CHAR +#undef IS_NMSTRT_CHAR_MINBPC +#undef IS_INVALID_CHAR + +static const struct normal_encoding little2_encoding = { + { VTABLE, 2, 0, +#if BYTE_ORDER == 12 + 1 +#else + 0 +#endif + }, +#include "asciitab.h" +#include "latin1tab.h" +}; + +#if BYTE_ORDER != 21 + +static const struct normal_encoding internal_little2_encoding = { + { VTABLE, 2, 0, 1 }, +#include "iasciitab.h" +#include "latin1tab.h" +}; + +#endif + +#undef PREFIX + +#define PREFIX(ident) big2_ ## ident +#define MINBPC 2 +/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ +#define BYTE_TYPE(enc, p) \ + ((p)[0] == 0 \ + ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \ + : unicode_byte_type((p)[0], (p)[1])) +#define BYTE_TO_ASCII(enc, p) ((p)[0] == 0 ? (p)[1] : -1) +#define CHAR_MATCHES(enc, p, c) ((p)[0] == 0 && (p)[1] == c) +#define IS_NAME_CHAR(enc, p, n) 0 +#define IS_NAME_CHAR_MINBPC(enc, p) \ + UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1]) +#define IS_NMSTRT_CHAR(enc, p, n) (0) +#define IS_NMSTRT_CHAR_MINBPC(enc, p) \ + UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1]) + +#include "xmltok_impl.c" + +#define SET2(ptr, ch) \ + (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch) & 0xFF))) +#define GET_LO(ptr) ((unsigned char)(ptr)[1]) +#define GET_HI(ptr) ((unsigned char)(ptr)[0]) + +DEFINE_UTF16_TO_UTF8 +DEFINE_UTF16_TO_UTF16 + +#undef SET2 +#undef GET_LO +#undef GET_HI +#undef MINBPC +#undef BYTE_TYPE +#undef BYTE_TO_ASCII +#undef CHAR_MATCHES +#undef IS_NAME_CHAR +#undef IS_NAME_CHAR_MINBPC +#undef IS_NMSTRT_CHAR +#undef IS_NMSTRT_CHAR_MINBPC +#undef IS_INVALID_CHAR + +static const struct normal_encoding big2_encoding = { + { VTABLE, 2, 0, +#if BYTE_ORDER == 21 + 1 +#else + 0 +#endif + }, +#include "asciitab.h" +#include "latin1tab.h" +}; + +#if BYTE_ORDER != 12 + +static const struct normal_encoding internal_big2_encoding = { + { VTABLE, 2, 0, 1 }, +#include "iasciitab.h" +#include "latin1tab.h" +}; + +#endif + +#undef PREFIX + +static +int streqci(const char *s1, const char *s2) +{ + for (;;) { + char c1 = *s1++; + char c2 = *s2++; + if ('a' <= c1 && c1 <= 'z') + c1 += 'A' - 'a'; + if ('a' <= c2 && c2 <= 'z') + c2 += 'A' - 'a'; + if (c1 != c2) + return 0; + if (!c1) + break; + } + return 1; +} + +static +int initScan(const ENCODING *enc, int state, const char *ptr, const char *end, + const char **nextTokPtr) +{ + const ENCODING **encPtr; + + if (ptr == end) + return XML_TOK_NONE; + encPtr = ((const INIT_ENCODING *)enc)->encPtr; + if (ptr + 1 == end) { + switch ((unsigned char)*ptr) { + case 0xFE: + case 0xFF: + case 0x00: + case 0x3C: + return XML_TOK_PARTIAL; + } + } + else { + switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) { + case 0x003C: + *encPtr = &big2_encoding.enc; + return XmlTok(*encPtr, state, ptr, end, nextTokPtr); + case 0xFEFF: + *nextTokPtr = ptr + 2; + *encPtr = &big2_encoding.enc; + return XML_TOK_BOM; + case 0x3C00: + *encPtr = &little2_encoding.enc; + return XmlTok(*encPtr, state, ptr, end, nextTokPtr); + case 0xFFFE: + *nextTokPtr = ptr + 2; + *encPtr = &little2_encoding.enc; + return XML_TOK_BOM; + } + } + *encPtr = &utf8_encoding.enc; + return XmlTok(*encPtr, state, ptr, end, nextTokPtr); +} + +static +int initScanProlog(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) +{ + return initScan(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr); +} + +static +int initScanContent(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) +{ + return initScan(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr); +} + +static +void initUpdatePosition(const ENCODING *enc, const char *ptr, + const char *end, POSITION *pos) +{ + normal_updatePosition(&utf8_encoding.enc, ptr, end, pos); +} + +const ENCODING *XmlGetUtf8InternalEncoding() +{ + return &internal_utf8_encoding.enc; +} + +const ENCODING *XmlGetUtf16InternalEncoding() +{ +#if BYTE_ORDER == 12 + return &internal_little2_encoding.enc; +#elif BYTE_ORDER == 21 + return &internal_big2_encoding.enc; +#else + const short n = 1; + return *(const char *)&n ? &internal_little2_encoding.enc : &internal_big2_encoding.enc; +#endif +} + +int XmlInitEncoding(INIT_ENCODING *p, const ENCODING **encPtr, const char *name) +{ + if (name) { + if (streqci(name, "ISO-8859-1")) { + *encPtr = &latin1_encoding.enc; + return 1; + } + if (streqci(name, "UTF-8")) { + *encPtr = &utf8_encoding.enc; + return 1; + } + if (streqci(name, "US-ASCII")) { + *encPtr = &ascii_encoding.enc; + return 1; + } + if (!streqci(name, "UTF-16")) + return 0; + } + p->initEnc.scanners[XML_PROLOG_STATE] = initScanProlog; + p->initEnc.scanners[XML_CONTENT_STATE] = initScanContent; + p->initEnc.updatePosition = initUpdatePosition; + p->initEnc.minBytesPerChar = 1; + p->encPtr = encPtr; + *encPtr = &(p->initEnc); + return 1; +} + +static +int toAscii(const ENCODING *enc, const char *ptr, const char *end) +{ + char buf[1]; + char *p = buf; + XmlUtf8Convert(enc, &ptr, end, &p, p + 1); + if (p == buf) + return -1; + else + return buf[0]; +} + +static +int isSpace(int c) +{ + switch (c) { + case ' ': + case '\r': + case '\n': + case '\t': + return 1; + } + return 0; +} + +/* Return 1 if there's just optional white space +or there's an S followed by name=val. */ +static +int parsePseudoAttribute(const ENCODING *enc, + const char *ptr, + const char *end, + const char **namePtr, + const char **valPtr, + const char **nextTokPtr) +{ + int c; + char open; + if (ptr == end) { + *namePtr = 0; + return 1; + } + if (!isSpace(toAscii(enc, ptr, end))) { + *nextTokPtr = ptr; + return 0; + } + do { + ptr += enc->minBytesPerChar; + } while (isSpace(toAscii(enc, ptr, end))); + if (ptr == end) { + *namePtr = 0; + return 1; + } + *namePtr = ptr; + for (;;) { + c = toAscii(enc, ptr, end); + if (c == -1) { + *nextTokPtr = ptr; + return 0; + } + if (c == '=') + break; + if (isSpace(c)) { + do { + ptr += enc->minBytesPerChar; + } while (isSpace(c = toAscii(enc, ptr, end))); + if (c != '=') { + *nextTokPtr = ptr; + return 0; + } + break; + } + ptr += enc->minBytesPerChar; + } + if (ptr == *namePtr) { + *nextTokPtr = ptr; + return 0; + } + ptr += enc->minBytesPerChar; + c = toAscii(enc, ptr, end); + while (isSpace(c)) { + ptr += enc->minBytesPerChar; + c = toAscii(enc, ptr, end); + } + if (c != '"' && c != '\'') { + *nextTokPtr = ptr; + return 0; + } + open = c; + ptr += enc->minBytesPerChar; + *valPtr = ptr; + for (;; ptr += enc->minBytesPerChar) { + c = toAscii(enc, ptr, end); + if (c == open) + break; + if (!('a' <= c && c <= 'z') + && !('A' <= c && c <= 'Z') + && !('0' <= c && c <= '9') + && c != '.' + && c != '-' + && c != '_') { + *nextTokPtr = ptr; + return 0; + } + } + *nextTokPtr = ptr + enc->minBytesPerChar; + return 1; +} + +static +const ENCODING *findEncoding(const ENCODING *enc, const char *ptr, const char *end) +{ +#define ENCODING_MAX 128 + char buf[ENCODING_MAX]; + char *p = buf; + int i; + XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1); + if (ptr != end) + return 0; + *p = 0; + for (i = 0; buf[i]; i++) { + if ('a' <= buf[i] && buf[i] <= 'z') + buf[i] += 'A' - 'a'; + } + if (streqci(buf, "UTF-8")) + return &utf8_encoding.enc; + if (streqci(buf, "ISO-8859-1")) + return &latin1_encoding.enc; + if (streqci(buf, "US-ASCII")) + return &ascii_encoding.enc; + if (streqci(buf, "UTF-16")) { + static const unsigned short n = 1; + if (enc->minBytesPerChar == 2) + return enc; + return &big2_encoding.enc; + } + return 0; +} + +int XmlParseXmlDecl(int isGeneralTextEntity, + const ENCODING *enc, + const char *ptr, + const char *end, + const char **badPtr, + const char **versionPtr, + const char **encodingName, + const ENCODING **encoding, + int *standalone) +{ + const char *val = 0; + const char *name = 0; + ptr += 5 * enc->minBytesPerChar; + end -= 2 * enc->minBytesPerChar; + if (!parsePseudoAttribute(enc, ptr, end, &name, &val, &ptr) || !name) { + *badPtr = ptr; + return 0; + } + if (!XmlNameMatchesAscii(enc, name, "version")) { + if (!isGeneralTextEntity) { + *badPtr = name; + return 0; + } + } + else { + if (versionPtr) + *versionPtr = val; + if (!parsePseudoAttribute(enc, ptr, end, &name, &val, &ptr)) { + *badPtr = ptr; + return 0; + } + if (!name) { + if (isGeneralTextEntity) { + /* a TextDecl must have an EncodingDecl */ + *badPtr = ptr; + return 0; + } + return 1; + } + } + if (XmlNameMatchesAscii(enc, name, "encoding")) { + int c = toAscii(enc, val, end); + if (!('a' <= c && c <= 'z') && !('A' <= c && c <= 'Z')) { + *badPtr = val; + return 0; + } + if (encodingName) + *encodingName = val; + if (encoding) + *encoding = findEncoding(enc, val, ptr - enc->minBytesPerChar); + if (!parsePseudoAttribute(enc, ptr, end, &name, &val, &ptr)) { + *badPtr = ptr; + return 0; + } + if (!name) + return 1; + } + if (!XmlNameMatchesAscii(enc, name, "standalone") || isGeneralTextEntity) { + *badPtr = name; + return 0; + } + if (XmlNameMatchesAscii(enc, val, "yes")) { + if (standalone) + *standalone = 1; + } + else if (XmlNameMatchesAscii(enc, val, "no")) { + if (standalone) + *standalone = 0; + } + else { + *badPtr = val; + return 0; + } + while (isSpace(toAscii(enc, ptr, end))) + ptr += enc->minBytesPerChar; + if (ptr != end) { + *badPtr = ptr; + return 0; + } + return 1; +} + +static +int checkCharRefNumber(int result) +{ + switch (result >> 8) { + case 0xD8: case 0xD9: case 0xDA: case 0xDB: + case 0xDC: case 0xDD: case 0xDE: case 0xDF: + return -1; + case 0: + if (latin1_encoding.type[result] == BT_NONXML) + return -1; + break; + case 0xFF: + if (result == 0xFFFE || result == 0xFFFF) + return -1; + break; + } + return result; +} + +int XmlUtf8Encode(int c, char *buf) +{ + enum { + /* minN is minimum legal resulting value for N byte sequence */ + min2 = 0x80, + min3 = 0x800, + min4 = 0x10000 + }; + + if (c < 0) + return 0; + if (c < min2) { + buf[0] = (c | UTF8_cval1); + return 1; + } + if (c < min3) { + buf[0] = ((c >> 6) | UTF8_cval2); + buf[1] = ((c & 0x3f) | 0x80); + return 2; + } + if (c < min4) { + buf[0] = ((c >> 12) | UTF8_cval3); + buf[1] = (((c >> 6) & 0x3f) | 0x80); + buf[2] = ((c & 0x3f) | 0x80); + return 3; + } + if (c < 0x110000) { + buf[0] = ((c >> 18) | UTF8_cval4); + buf[1] = (((c >> 12) & 0x3f) | 0x80); + buf[2] = (((c >> 6) & 0x3f) | 0x80); + buf[3] = ((c & 0x3f) | 0x80); + return 4; + } + return 0; +} + +int XmlUtf16Encode(int charNum, unsigned short *buf) +{ + if (charNum < 0) + return 0; + if (charNum < 0x10000) { + buf[0] = charNum; + return 1; + } + if (charNum < 0x110000) { + charNum -= 0x10000; + buf[0] = (charNum >> 10) + 0xD800; + buf[1] = (charNum & 0x3FF) + 0xDC00; + return 2; + } + return 0; +} + +struct unknown_encoding { + struct normal_encoding normal; + int (*convert)(void *userData, const char *p); + void *userData; + unsigned short utf16[256]; + char utf8[256][4]; +}; + +int XmlSizeOfUnknownEncoding() +{ + return sizeof(struct unknown_encoding); +} + +static +int unknown_isName(const ENCODING *enc, const char *p) +{ + int c = ((const struct unknown_encoding *)enc) + ->convert(((const struct unknown_encoding *)enc)->userData, p); + if (c & ~0xFFFF) + return 0; + return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF); +} + +static +int unknown_isNmstrt(const ENCODING *enc, const char *p) +{ + int c = ((const struct unknown_encoding *)enc) + ->convert(((const struct unknown_encoding *)enc)->userData, p); + if (c & ~0xFFFF) + return 0; + return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF); +} + +static +int unknown_isInvalid(const ENCODING *enc, const char *p) +{ + int c = ((const struct unknown_encoding *)enc) + ->convert(((const struct unknown_encoding *)enc)->userData, p); + return (c & ~0xFFFF) || checkCharRefNumber(c) < 0; +} + +static +void unknown_toUtf8(const ENCODING *enc, + const char **fromP, const char *fromLim, + char **toP, const char *toLim) +{ + char buf[XML_UTF8_ENCODE_MAX]; + for (;;) { + const char *utf8; + int n; + if (*fromP == fromLim) + break; + utf8 = ((const struct unknown_encoding *)enc)->utf8[(unsigned char)**fromP]; + n = *utf8++; + if (n == 0) { + int c = ((const struct unknown_encoding *)enc) + ->convert(((const struct unknown_encoding *)enc)->userData, *fromP); + n = XmlUtf8Encode(c, buf); + if (n > toLim - *toP) + break; + utf8 = buf; + *fromP += ((const struct normal_encoding *)enc)->type[(unsigned char)**fromP] + - (BT_LEAD2 - 2); + } + else { + if (n > toLim - *toP) + break; + (*fromP)++; + } + do { + *(*toP)++ = *utf8++; + } while (--n != 0); + } +} + +static +void unknown_toUtf16(const ENCODING *enc, + const char **fromP, const char *fromLim, + unsigned short **toP, const unsigned short *toLim) +{ + while (*fromP != fromLim && *toP != toLim) { + unsigned short c + = ((const struct unknown_encoding *)enc)->utf16[(unsigned char)**fromP]; + if (c == 0) { + c = (unsigned short)((const struct unknown_encoding *)enc) + ->convert(((const struct unknown_encoding *)enc)->userData, *fromP); + *fromP += ((const struct normal_encoding *)enc)->type[(unsigned char)**fromP] + - (BT_LEAD2 - 2); + } + else + (*fromP)++; + *(*toP)++ = c; + } +} + +ENCODING * +XmlInitUnknownEncoding(void *mem, + int *table, + int (*convert)(void *userData, const char *p), + void *userData) +{ + int i; + struct unknown_encoding *e = mem; + for (i = 0; i < sizeof(struct normal_encoding); i++) + ((char *)mem)[i] = ((char *)&latin1_encoding)[i]; + for (i = 0; i < 128; i++) + if (latin1_encoding.type[i] != BT_OTHER + && latin1_encoding.type[i] != BT_NONXML + && table[i] != i) + return 0; + for (i = 0; i < 256; i++) { + int c = table[i]; + if (c == -1) { + e->normal.type[i] = BT_MALFORM; + /* This shouldn't really get used. */ + e->utf16[i] = 0xFFFF; + e->utf8[i][0] = 1; + e->utf8[i][1] = 0; + } + else if (c < 0) { + if (c < -4) + return 0; + e->normal.type[i] = BT_LEAD2 - (c + 2); + e->utf8[i][0] = 0; + e->utf16[i] = 0; + } + else if (c < 0x80) { + if (latin1_encoding.type[c] != BT_OTHER + && latin1_encoding.type[c] != BT_NONXML + && c != i) + return 0; + e->normal.type[i] = latin1_encoding.type[c]; + e->utf8[i][0] = 1; + e->utf8[i][1] = (char)c; + e->utf16[i] = c == 0 ? 0xFFFF : c; + } + else if (checkCharRefNumber(c) < 0) { + e->normal.type[i] = BT_NONXML; + /* This shouldn't really get used. */ + e->utf16[i] = 0xFFFF; + e->utf8[i][0] = 1; + e->utf8[i][1] = 0; + } + else { + if (c > 0xFFFF) + return 0; + if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff)) + e->normal.type[i] = BT_NMSTRT; + else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff)) + e->normal.type[i] = BT_NAME; + else + e->normal.type[i] = BT_OTHER; + e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1); + e->utf16[i] = c; + } + } + e->userData = userData; + e->convert = convert; + if (convert) { + e->normal.isName2 = unknown_isName; + e->normal.isName3 = unknown_isName; + e->normal.isName4 = unknown_isName; + e->normal.isNmstrt2 = unknown_isNmstrt; + e->normal.isNmstrt3 = unknown_isNmstrt; + e->normal.isNmstrt4 = unknown_isNmstrt; + e->normal.isInvalid2 = unknown_isInvalid; + e->normal.isInvalid3 = unknown_isInvalid; + e->normal.isInvalid4 = unknown_isInvalid; + } + e->normal.enc.utf8Convert = unknown_toUtf8; + e->normal.enc.utf16Convert = unknown_toUtf16; + return &(e->normal.enc); +} diff --git a/mozilla/extensions/transformiix/source/xml/parser/xmltok/xmltok.h b/mozilla/extensions/transformiix/source/xml/parser/xmltok/xmltok.h new file mode 100644 index 00000000000..6d0b91dff2c --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/xmltok/xmltok.h @@ -0,0 +1,276 @@ +/* +The contents of this file are subject to the Mozilla Public License +Version 1.0 (the "License"); you may not use this file except in +compliance with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" +basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific language governing rights and limitations +under the License. + +The Original Code is expat. + +The Initial Developer of the Original Code is James Clark. +Portions created by James Clark are Copyright (C) 1998 +James Clark. All Rights Reserved. + +Contributor(s): +*/ + +#ifndef XmlTok_INCLUDED +#define XmlTok_INCLUDED 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef XMLTOKAPI +#define XMLTOKAPI /* as nothing */ +#endif + +/* The following token may be returned by XmlContentTok */ +#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be start of + illegal ]]> sequence */ +/* The following tokens may be returned by both XmlPrologTok and XmlContentTok */ +#define XML_TOK_NONE -4 /* The string to be scanned is empty */ +#define XML_TOK_TRAILING_CR -3 /* A CR at the end of the scan; + might be part of CRLF sequence */ +#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */ +#define XML_TOK_PARTIAL -1 /* only part of a token */ +#define XML_TOK_INVALID 0 + +/* The following tokens are returned by XmlContentTok; some are also + returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok */ + +#define XML_TOK_START_TAG_WITH_ATTS 1 +#define XML_TOK_START_TAG_NO_ATTS 2 +#define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag */ +#define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4 +#define XML_TOK_END_TAG 5 +#define XML_TOK_DATA_CHARS 6 +#define XML_TOK_DATA_NEWLINE 7 +#define XML_TOK_CDATA_SECT_OPEN 8 +#define XML_TOK_ENTITY_REF 9 +#define XML_TOK_CHAR_REF 10 /* numeric character reference */ + +/* The following tokens may be returned by both XmlPrologTok and XmlContentTok */ +#define XML_TOK_PI 11 /* processing instruction */ +#define XML_TOK_XML_DECL 12 /* XML decl or text decl */ +#define XML_TOK_COMMENT 13 +#define XML_TOK_BOM 14 /* Byte order mark */ + +/* The following tokens are returned only by XmlPrologTok */ +#define XML_TOK_PROLOG_S 15 +#define XML_TOK_DECL_OPEN 16 /* */ +#define XML_TOK_NAME 18 +#define XML_TOK_NMTOKEN 19 +#define XML_TOK_POUND_NAME 20 /* #name */ +#define XML_TOK_OR 21 /* | */ +#define XML_TOK_PERCENT 22 +#define XML_TOK_OPEN_PAREN 23 +#define XML_TOK_CLOSE_PAREN 24 +#define XML_TOK_OPEN_BRACKET 25 +#define XML_TOK_CLOSE_BRACKET 26 +#define XML_TOK_LITERAL 27 +#define XML_TOK_PARAM_ENTITY_REF 28 +#define XML_TOK_INSTANCE_START 29 + +/* The following occur only in element type declarations */ +#define XML_TOK_NAME_QUESTION 30 /* name? */ +#define XML_TOK_NAME_ASTERISK 31 /* name* */ +#define XML_TOK_NAME_PLUS 32 /* name+ */ +#define XML_TOK_COND_SECT_OPEN 33 /* */ +#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */ +#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */ +#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */ +#define XML_TOK_COMMA 38 + +/* The following token is returned only by XmlAttributeValueTok */ +#define XML_TOK_ATTRIBUTE_VALUE_S 39 + +/* The following token is returned only by XmlCdataSectionTok */ +#define XML_TOK_CDATA_SECT_CLOSE 40 + +#define XML_N_STATES 3 +#define XML_PROLOG_STATE 0 +#define XML_CONTENT_STATE 1 +#define XML_CDATA_SECTION_STATE 2 + +#define XML_N_LITERAL_TYPES 2 +#define XML_ATTRIBUTE_VALUE_LITERAL 0 +#define XML_ENTITY_VALUE_LITERAL 1 + +/* The size of the buffer passed to XmlUtf8Encode must be at least this. */ +#define XML_UTF8_ENCODE_MAX 4 +/* The size of the buffer passed to XmlUtf16Encode must be at least this. */ +#define XML_UTF16_ENCODE_MAX 2 + +typedef struct position { + /* first line and first column are 0 not 1 */ + unsigned long lineNumber; + unsigned long columnNumber; +} POSITION; + +typedef struct { + const char *name; + const char *valuePtr; + const char *valueEnd; + char normalized; +} ATTRIBUTE; + +struct encoding; +typedef struct encoding ENCODING; + +struct encoding { + int (*scanners[XML_N_STATES])(const ENCODING *, + const char *, + const char *, + const char **); + int (*literalScanners[XML_N_LITERAL_TYPES])(const ENCODING *, + const char *, + const char *, + const char **); + int (*sameName)(const ENCODING *, + const char *, const char *); + int (*nameMatchesAscii)(const ENCODING *, + const char *, const char *); + int (*nameLength)(const ENCODING *, const char *); + const char *(*skipS)(const ENCODING *, const char *); + int (*getAtts)(const ENCODING *enc, const char *ptr, + int attsMax, ATTRIBUTE *atts); + int (*charRefNumber)(const ENCODING *enc, const char *ptr); + int (*predefinedEntityName)(const ENCODING *, const char *, const char *); + void (*updatePosition)(const ENCODING *, + const char *ptr, + const char *end, + POSITION *); + int (*isPublicId)(const ENCODING *enc, const char *ptr, const char *end, + const char **badPtr); + void (*utf8Convert)(const ENCODING *enc, + const char **fromP, + const char *fromLim, + char **toP, + const char *toLim); + void (*utf16Convert)(const ENCODING *enc, + const char **fromP, + const char *fromLim, + unsigned short **toP, + const unsigned short *toLim); + int minBytesPerChar; + char isUtf8; + char isUtf16; +}; + +/* +Scan the string starting at ptr until the end of the next complete token, +but do not scan past eptr. Return an integer giving the type of token. + +Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set. + +Return XML_TOK_PARTIAL when the string does not contain a complete token; +nextTokPtr will not be set. + +Return XML_TOK_INVALID when the string does not start a valid token; nextTokPtr +will be set to point to the character which made the token invalid. + +Otherwise the string starts with a valid token; nextTokPtr will be set to point +to the character following the end of that token. + +Each data character counts as a single token, but adjacent data characters +may be returned together. Similarly for characters in the prolog outside +literals, comments and processing instructions. +*/ + + +#define XmlTok(enc, state, ptr, end, nextTokPtr) \ + (((enc)->scanners[state])(enc, ptr, end, nextTokPtr)) + +#define XmlPrologTok(enc, ptr, end, nextTokPtr) \ + XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr) + +#define XmlContentTok(enc, ptr, end, nextTokPtr) \ + XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr) + +#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \ + XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr) + +/* This is used for performing a 2nd-level tokenization on +the content of a literal that has already been returned by XmlTok. */ + +#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \ + (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr)) + +#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \ + XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr) + +#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \ + XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr) + +#define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2)) + +#define XmlNameMatchesAscii(enc, ptr1, ptr2) \ + (((enc)->nameMatchesAscii)(enc, ptr1, ptr2)) + +#define XmlNameLength(enc, ptr) \ + (((enc)->nameLength)(enc, ptr)) + +#define XmlSkipS(enc, ptr) \ + (((enc)->skipS)(enc, ptr)) + +#define XmlGetAttributes(enc, ptr, attsMax, atts) \ + (((enc)->getAtts)(enc, ptr, attsMax, atts)) + +#define XmlCharRefNumber(enc, ptr) \ + (((enc)->charRefNumber)(enc, ptr)) + +#define XmlPredefinedEntityName(enc, ptr, end) \ + (((enc)->predefinedEntityName)(enc, ptr, end)) + +#define XmlUpdatePosition(enc, ptr, end, pos) \ + (((enc)->updatePosition)(enc, ptr, end, pos)) + +#define XmlIsPublicId(enc, ptr, end, badPtr) \ + (((enc)->isPublicId)(enc, ptr, end, badPtr)) + +#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \ + (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim)) + +#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \ + (((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim)) + +typedef struct { + ENCODING initEnc; + const ENCODING **encPtr; +} INIT_ENCODING; + +int XMLTOKAPI XmlParseXmlDecl(int isGeneralTextEntity, + const ENCODING *enc, + const char *ptr, + const char *end, + const char **badPtr, + const char **versionPtr, + const char **encodingNamePtr, + const ENCODING **namedEncodingPtr, + int *standalonePtr); + +int XMLTOKAPI XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name); +const ENCODING XMLTOKAPI *XmlGetUtf8InternalEncoding(); +const ENCODING XMLTOKAPI *XmlGetUtf16InternalEncoding(); +int XMLTOKAPI XmlUtf8Encode(int charNumber, char *buf); +int XMLTOKAPI XmlUtf16Encode(int charNumber, unsigned short *buf); + +int XMLTOKAPI XmlSizeOfUnknownEncoding(); +ENCODING XMLTOKAPI * +XmlInitUnknownEncoding(void *mem, + int *table, + int (*convert)(void *userData, const char *p), + void *userData); + +#ifdef __cplusplus +} +#endif + +#endif /* not XmlTok_INCLUDED */ diff --git a/mozilla/extensions/transformiix/source/xml/parser/xmltok/xmltok_impl.c b/mozilla/extensions/transformiix/source/xml/parser/xmltok/xmltok_impl.c new file mode 100644 index 00000000000..fa4916252ff --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/xmltok/xmltok_impl.c @@ -0,0 +1,1651 @@ +/* +The contents of this file are subject to the Mozilla Public License +Version 1.0 (the "License"); you may not use this file except in +compliance with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" +basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific language governing rights and limitations +under the License. + +The Original Code is expat. + +The Initial Developer of the Original Code is James Clark. +Portions created by James Clark are Copyright (C) 1998 +James Clark. All Rights Reserved. + +Contributor(s): +*/ + +#ifndef IS_INVALID_CHAR +#define IS_INVALID_CHAR(enc, ptr, n) (0) +#endif + +#define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \ + case BT_LEAD ## n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ + if (IS_INVALID_CHAR(enc, ptr, n)) { \ + *(nextTokPtr) = (ptr); \ + return XML_TOK_INVALID; \ + } \ + ptr += n; \ + break; + +#define INVALID_CASES(ptr, nextTokPtr) \ + INVALID_LEAD_CASE(2, ptr, nextTokPtr) \ + INVALID_LEAD_CASE(3, ptr, nextTokPtr) \ + INVALID_LEAD_CASE(4, ptr, nextTokPtr) \ + case BT_NONXML: \ + case BT_MALFORM: \ + case BT_TRAIL: \ + *(nextTokPtr) = (ptr); \ + return XML_TOK_INVALID; + +#define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \ + case BT_LEAD ## n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ + if (!IS_NAME_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ + ptr += n; \ + break; + +#define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \ + case BT_NONASCII: \ + if (!IS_NAME_CHAR_MINBPC(enc, ptr)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ + case BT_NMSTRT: \ + case BT_HEX: \ + case BT_DIGIT: \ + case BT_NAME: \ + case BT_MINUS: \ + ptr += MINBPC; \ + break; \ + CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \ + CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \ + CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr) + +#define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \ + case BT_LEAD ## n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ + if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ + ptr += n; \ + break; + +#define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \ + case BT_NONASCII: \ + if (!IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ + case BT_NMSTRT: \ + case BT_HEX: \ + ptr += MINBPC; \ + break; \ + CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \ + CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \ + CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr) + +#ifndef PREFIX +#define PREFIX(ident) ident +#endif + +/* ptr points to character following "')) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC; + return XML_TOK_COMMENT; + } + break; + default: + ptr += MINBPC; + break; + } + } + } + return XML_TOK_PARTIAL; +} + +/* ptr points to character following " */ + switch (BYTE_TYPE(enc, ptr + MINBPC)) { + case BT_S: case BT_CR: case BT_LF: case BT_PERCNT: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + /* fall through */ + case BT_S: case BT_CR: case BT_LF: + *nextTokPtr = ptr; + return XML_TOK_DECL_OPEN; + case BT_NMSTRT: + case BT_HEX: + ptr += MINBPC; + break; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + return XML_TOK_PARTIAL; +} + +static +int PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr, const char *end, int *tokPtr) +{ + int upper = 0; + *tokPtr = XML_TOK_PI; + if (end - ptr != MINBPC*3) + return 1; + switch (BYTE_TO_ASCII(enc, ptr)) { + case 'x': + break; + case 'X': + upper = 1; + break; + default: + return 1; + } + ptr += MINBPC; + switch (BYTE_TO_ASCII(enc, ptr)) { + case 'm': + break; + case 'M': + upper = 1; + break; + default: + return 1; + } + ptr += MINBPC; + switch (BYTE_TO_ASCII(enc, ptr)) { + case 'l': + break; + case 'L': + upper = 1; + break; + default: + return 1; + } + if (upper) + return 0; + *tokPtr = XML_TOK_XML_DECL; + return 1; +} + +/* ptr points to character following "')) { + *nextTokPtr = ptr + MINBPC; + return tok; + } + break; + default: + ptr += MINBPC; + break; + } + } + return XML_TOK_PARTIAL; + case BT_QUEST: + if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + ptr += MINBPC; + if (ptr == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, '>')) { + *nextTokPtr = ptr + MINBPC; + return tok; + } + /* fall through */ + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + return XML_TOK_PARTIAL; +} + + +static +int PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) +{ + int i; + /* CDATA[ */ + if (end - ptr < 6 * MINBPC) + return XML_TOK_PARTIAL; + for (i = 0; i < 6; i++, ptr += MINBPC) { + if (!CHAR_MATCHES(enc, ptr, "CDATA["[i])) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + *nextTokPtr = ptr; + return XML_TOK_CDATA_SECT_OPEN; +} + +static +int PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) +{ + if (ptr == end) + return XML_TOK_NONE; +#if MINBPC > 1 + { + size_t n = end - ptr; + if (n & (MINBPC - 1)) { + n &= ~(MINBPC - 1); + if (n == 0) + return XML_TOK_PARTIAL; + end = ptr + n; + } + } +#endif + switch (BYTE_TYPE(enc, ptr)) { + case BT_RSQB: + ptr += MINBPC; + if (ptr == end) + return XML_TOK_PARTIAL; + if (!CHAR_MATCHES(enc, ptr, ']')) + break; + ptr += MINBPC; + if (ptr == end) + return XML_TOK_PARTIAL; + if (!CHAR_MATCHES(enc, ptr, '>')) { + ptr -= MINBPC; + break; + } + *nextTokPtr = ptr + MINBPC; + return XML_TOK_CDATA_SECT_CLOSE; + case BT_CR: + ptr += MINBPC; + if (ptr == end) + return XML_TOK_PARTIAL; + if (BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC; + *nextTokPtr = ptr; + return XML_TOK_DATA_NEWLINE; + case BT_LF: + *nextTokPtr = ptr + MINBPC; + return XML_TOK_DATA_NEWLINE; + INVALID_CASES(ptr, nextTokPtr) + default: + ptr += MINBPC; + break; + } + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { +#define LEAD_CASE(n) \ + case BT_LEAD ## n: \ + if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_DATA_CHARS; \ + } \ + ptr += n; \ + break; + LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE + case BT_NONXML: + case BT_MALFORM: + case BT_TRAIL: + case BT_CR: + case BT_LF: + case BT_RSQB: + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + default: + ptr += MINBPC; + break; + } + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; +} + +/* ptr points to character following "')) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC; + return XML_TOK_EMPTY_ELEMENT_WITH_ATTS; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + break; + } + break; + } + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + return XML_TOK_PARTIAL; +} + +/* ptr points to character following "<" */ + +static +int PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) +{ + if (ptr == end) + return XML_TOK_PARTIAL; + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + case BT_EXCL: + if ((ptr += MINBPC) == end) + return XML_TOK_PARTIAL; + switch (BYTE_TYPE(enc, ptr)) { + case BT_MINUS: + return PREFIX(scanComment)(enc, ptr + MINBPC, end, nextTokPtr); + case BT_LSQB: + return PREFIX(scanCdataSection)(enc, ptr + MINBPC, end, nextTokPtr); + } + *nextTokPtr = ptr; + return XML_TOK_INVALID; + case BT_QUEST: + return PREFIX(scanPi)(enc, ptr + MINBPC, end, nextTokPtr); + case BT_SOL: + return PREFIX(scanEndTag)(enc, ptr + MINBPC, end, nextTokPtr); + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + /* we have a start-tag */ + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + case BT_S: case BT_CR: case BT_LF: + { + ptr += MINBPC; + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + case BT_GT: + goto gt; + case BT_SOL: + goto sol; + case BT_S: case BT_CR: case BT_LF: + ptr += MINBPC; + continue; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr); + } + return XML_TOK_PARTIAL; + } + case BT_GT: + gt: + *nextTokPtr = ptr + MINBPC; + return XML_TOK_START_TAG_NO_ATTS; + case BT_SOL: + sol: + ptr += MINBPC; + if (ptr == end) + return XML_TOK_PARTIAL; + if (!CHAR_MATCHES(enc, ptr, '>')) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC; + return XML_TOK_EMPTY_ELEMENT_NO_ATTS; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + return XML_TOK_PARTIAL; +} + +static +int PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) +{ + if (ptr == end) + return XML_TOK_NONE; +#if MINBPC > 1 + { + size_t n = end - ptr; + if (n & (MINBPC - 1)) { + n &= ~(MINBPC - 1); + if (n == 0) + return XML_TOK_PARTIAL; + end = ptr + n; + } + } +#endif + switch (BYTE_TYPE(enc, ptr)) { + case BT_LT: + return PREFIX(scanLt)(enc, ptr + MINBPC, end, nextTokPtr); + case BT_AMP: + return PREFIX(scanRef)(enc, ptr + MINBPC, end, nextTokPtr); + case BT_CR: + ptr += MINBPC; + if (ptr == end) + return XML_TOK_TRAILING_CR; + if (BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC; + *nextTokPtr = ptr; + return XML_TOK_DATA_NEWLINE; + case BT_LF: + *nextTokPtr = ptr + MINBPC; + return XML_TOK_DATA_NEWLINE; + case BT_RSQB: + ptr += MINBPC; + if (ptr == end) + return XML_TOK_TRAILING_RSQB; + if (!CHAR_MATCHES(enc, ptr, ']')) + break; + ptr += MINBPC; + if (ptr == end) + return XML_TOK_TRAILING_RSQB; + if (!CHAR_MATCHES(enc, ptr, '>')) { + ptr -= MINBPC; + break; + } + *nextTokPtr = ptr; + return XML_TOK_INVALID; + INVALID_CASES(ptr, nextTokPtr) + default: + ptr += MINBPC; + break; + } + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { +#define LEAD_CASE(n) \ + case BT_LEAD ## n: \ + if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_DATA_CHARS; \ + } \ + ptr += n; \ + break; + LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE + case BT_RSQB: + if (ptr + MINBPC != end) { + if (!CHAR_MATCHES(enc, ptr + MINBPC, ']')) { + ptr += MINBPC; + break; + } + if (ptr + 2*MINBPC != end) { + if (!CHAR_MATCHES(enc, ptr + 2*MINBPC, '>')) { + ptr += MINBPC; + break; + } + *nextTokPtr = ptr + 2*MINBPC; + return XML_TOK_INVALID; + } + } + /* fall through */ + case BT_AMP: + case BT_LT: + case BT_NONXML: + case BT_MALFORM: + case BT_TRAIL: + case BT_CR: + case BT_LF: + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + default: + ptr += MINBPC; + break; + } + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; +} + +/* ptr points to character following "%" */ + +static +int PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) +{ + if (ptr == end) + return XML_TOK_PARTIAL; + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + case BT_S: case BT_LF: case BT_CR: case BT_PERCNT: + *nextTokPtr = ptr; + return XML_TOK_PERCENT; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + case BT_SEMI: + *nextTokPtr = ptr + MINBPC; + return XML_TOK_PARAM_ENTITY_REF; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + return XML_TOK_PARTIAL; +} + +static +int PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) +{ + if (ptr == end) + return XML_TOK_PARTIAL; + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + case BT_CR: case BT_LF: case BT_S: + case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR: + *nextTokPtr = ptr; + return XML_TOK_POUND_NAME; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + return XML_TOK_PARTIAL; +} + +static +int PREFIX(scanLit)(int open, const ENCODING *enc, + const char *ptr, const char *end, + const char **nextTokPtr) +{ + while (ptr != end) { + int t = BYTE_TYPE(enc, ptr); + switch (t) { + INVALID_CASES(ptr, nextTokPtr) + case BT_QUOT: + case BT_APOS: + ptr += MINBPC; + if (t != open) + break; + if (ptr == end) + return XML_TOK_PARTIAL; + *nextTokPtr = ptr; + switch (BYTE_TYPE(enc, ptr)) { + case BT_S: case BT_CR: case BT_LF: + case BT_GT: case BT_PERCNT: case BT_LSQB: + return XML_TOK_LITERAL; + default: + return XML_TOK_INVALID; + } + default: + ptr += MINBPC; + break; + } + } + return XML_TOK_PARTIAL; +} + +static +int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) +{ + int tok; + if (ptr == end) + return XML_TOK_NONE; +#if MINBPC > 1 + { + size_t n = end - ptr; + if (n & (MINBPC - 1)) { + n &= ~(MINBPC - 1); + if (n == 0) + return XML_TOK_PARTIAL; + end = ptr + n; + } + } +#endif + switch (BYTE_TYPE(enc, ptr)) { + case BT_QUOT: + return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC, end, nextTokPtr); + case BT_APOS: + return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC, end, nextTokPtr); + case BT_LT: + { + ptr += MINBPC; + if (ptr == end) + return XML_TOK_PARTIAL; + switch (BYTE_TYPE(enc, ptr)) { + case BT_EXCL: + return PREFIX(scanDecl)(enc, ptr + MINBPC, end, nextTokPtr); + case BT_QUEST: + return PREFIX(scanPi)(enc, ptr + MINBPC, end, nextTokPtr); + case BT_NMSTRT: + case BT_HEX: + case BT_NONASCII: + case BT_LEAD2: + case BT_LEAD3: + case BT_LEAD4: + *nextTokPtr = ptr - MINBPC; + return XML_TOK_INSTANCE_START; + } + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + case BT_CR: + if (ptr + MINBPC == end) + return XML_TOK_TRAILING_CR; + /* fall through */ + case BT_S: case BT_LF: + for (;;) { + ptr += MINBPC; + if (ptr == end) + break; + switch (BYTE_TYPE(enc, ptr)) { + case BT_S: case BT_LF: + break; + case BT_CR: + /* don't split CR/LF pair */ + if (ptr + MINBPC != end) + break; + /* fall through */ + default: + *nextTokPtr = ptr; + return XML_TOK_PROLOG_S; + } + } + *nextTokPtr = ptr; + return XML_TOK_PROLOG_S; + case BT_PERCNT: + return PREFIX(scanPercent)(enc, ptr + MINBPC, end, nextTokPtr); + case BT_COMMA: + *nextTokPtr = ptr + MINBPC; + return XML_TOK_COMMA; + case BT_LSQB: + *nextTokPtr = ptr + MINBPC; + return XML_TOK_OPEN_BRACKET; + case BT_RSQB: + ptr += MINBPC; + if (ptr == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr, ']')) { + if (ptr + MINBPC == end) + return XML_TOK_PARTIAL; + if (CHAR_MATCHES(enc, ptr + MINBPC, '>')) { + *nextTokPtr = ptr + 2*MINBPC; + return XML_TOK_COND_SECT_CLOSE; + } + } + *nextTokPtr = ptr; + return XML_TOK_CLOSE_BRACKET; + case BT_LPAR: + *nextTokPtr = ptr + MINBPC; + return XML_TOK_OPEN_PAREN; + case BT_RPAR: + ptr += MINBPC; + if (ptr == end) + return XML_TOK_PARTIAL; + switch (BYTE_TYPE(enc, ptr)) { + case BT_AST: + *nextTokPtr = ptr + MINBPC; + return XML_TOK_CLOSE_PAREN_ASTERISK; + case BT_QUEST: + *nextTokPtr = ptr + MINBPC; + return XML_TOK_CLOSE_PAREN_QUESTION; + case BT_PLUS: + *nextTokPtr = ptr + MINBPC; + return XML_TOK_CLOSE_PAREN_PLUS; + case BT_CR: case BT_LF: case BT_S: + case BT_GT: case BT_COMMA: case BT_VERBAR: + case BT_RPAR: + *nextTokPtr = ptr; + return XML_TOK_CLOSE_PAREN; + } + *nextTokPtr = ptr; + return XML_TOK_INVALID; + case BT_VERBAR: + *nextTokPtr = ptr + MINBPC; + return XML_TOK_OR; + case BT_GT: + *nextTokPtr = ptr + MINBPC; + return XML_TOK_DECL_CLOSE; + case BT_NUM: + return PREFIX(scanPoundName)(enc, ptr + MINBPC, end, nextTokPtr); +#define LEAD_CASE(n) \ + case BT_LEAD ## n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ + if (IS_NMSTRT_CHAR(enc, ptr, n)) { \ + ptr += n; \ + tok = XML_TOK_NAME; \ + break; \ + } \ + if (IS_NAME_CHAR(enc, ptr, n)) { \ + ptr += n; \ + tok = XML_TOK_NMTOKEN; \ + break; \ + } \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; + LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE + case BT_NMSTRT: + case BT_HEX: + tok = XML_TOK_NAME; + ptr += MINBPC; + break; + case BT_DIGIT: + case BT_NAME: + case BT_MINUS: + tok = XML_TOK_NMTOKEN; + ptr += MINBPC; + break; + case BT_NONASCII: + if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { + ptr += MINBPC; + tok = XML_TOK_NAME; + break; + } + if (IS_NAME_CHAR_MINBPC(enc, ptr)) { + ptr += MINBPC; + tok = XML_TOK_NMTOKEN; + break; + } + /* fall through */ + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { + CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) + case BT_GT: case BT_RPAR: case BT_COMMA: + case BT_VERBAR: case BT_LSQB: case BT_PERCNT: + case BT_S: case BT_CR: case BT_LF: + *nextTokPtr = ptr; + return tok; + case BT_PLUS: + if (tok != XML_TOK_NAME) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC; + return XML_TOK_NAME_PLUS; + case BT_AST: + if (tok != XML_TOK_NAME) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC; + return XML_TOK_NAME_ASTERISK; + case BT_QUEST: + if (tok != XML_TOK_NAME) { + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + *nextTokPtr = ptr + MINBPC; + return XML_TOK_NAME_QUESTION; + default: + *nextTokPtr = ptr; + return XML_TOK_INVALID; + } + } + return XML_TOK_PARTIAL; +} + +static +int PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) +{ + const char *start; + if (ptr == end) + return XML_TOK_NONE; + start = ptr; + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { +#define LEAD_CASE(n) \ + case BT_LEAD ## n: ptr += n; break; + LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE + case BT_AMP: + if (ptr == start) + return PREFIX(scanRef)(enc, ptr + MINBPC, end, nextTokPtr); + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_LT: + /* this is for inside entity references */ + *nextTokPtr = ptr; + return XML_TOK_INVALID; + case BT_LF: + if (ptr == start) { + *nextTokPtr = ptr + MINBPC; + return XML_TOK_DATA_NEWLINE; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_CR: + if (ptr == start) { + ptr += MINBPC; + if (ptr == end) + return XML_TOK_TRAILING_CR; + if (BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC; + *nextTokPtr = ptr; + return XML_TOK_DATA_NEWLINE; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_S: + if (ptr == start) { + *nextTokPtr = ptr + MINBPC; + return XML_TOK_ATTRIBUTE_VALUE_S; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + default: + ptr += MINBPC; + break; + } + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; +} + +static +int PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end, + const char **nextTokPtr) +{ + const char *start; + if (ptr == end) + return XML_TOK_NONE; + start = ptr; + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { +#define LEAD_CASE(n) \ + case BT_LEAD ## n: ptr += n; break; + LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE + case BT_AMP: + if (ptr == start) + return PREFIX(scanRef)(enc, ptr + MINBPC, end, nextTokPtr); + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_PERCNT: + if (ptr == start) + return PREFIX(scanPercent)(enc, ptr + MINBPC, end, nextTokPtr); + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_LF: + if (ptr == start) { + *nextTokPtr = ptr + MINBPC; + return XML_TOK_DATA_NEWLINE; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + case BT_CR: + if (ptr == start) { + ptr += MINBPC; + if (ptr == end) + return XML_TOK_TRAILING_CR; + if (BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC; + *nextTokPtr = ptr; + return XML_TOK_DATA_NEWLINE; + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; + default: + ptr += MINBPC; + break; + } + } + *nextTokPtr = ptr; + return XML_TOK_DATA_CHARS; +} + +static +int PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, + const char **badPtr) +{ + ptr += MINBPC; + end -= MINBPC; + for (; ptr != end; ptr += MINBPC) { + switch (BYTE_TYPE(enc, ptr)) { + case BT_DIGIT: + case BT_HEX: + case BT_MINUS: + case BT_APOS: + case BT_LPAR: + case BT_RPAR: + case BT_PLUS: + case BT_COMMA: + case BT_SOL: + case BT_EQUALS: + case BT_QUEST: + case BT_CR: + case BT_LF: + case BT_SEMI: + case BT_EXCL: + case BT_AST: + case BT_PERCNT: + case BT_NUM: + break; + case BT_S: + if (CHAR_MATCHES(enc, ptr, '\t')) { + *badPtr = ptr; + return 0; + } + break; + case BT_NAME: + case BT_NMSTRT: + if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f)) + break; + default: + switch (BYTE_TO_ASCII(enc, ptr)) { + case 0x24: /* $ */ + case 0x40: /* @ */ + break; + default: + *badPtr = ptr; + return 0; + } + break; + } + } + return 1; +} + +/* This must only be called for a well-formed start-tag or empty element tag. +Returns the number of attributes. Pointers to the first attsMax attributes +are stored in atts. */ + +static +int PREFIX(getAtts)(const ENCODING *enc, const char *ptr, + int attsMax, ATTRIBUTE *atts) +{ + enum { other, inName, inValue } state = inName; + int nAtts = 0; + int open; + + for (ptr += MINBPC;; ptr += MINBPC) { + switch (BYTE_TYPE(enc, ptr)) { +#define START_NAME \ + if (state == other) { \ + if (nAtts < attsMax) { \ + atts[nAtts].name = ptr; \ + atts[nAtts].normalized = 1; \ + } \ + state = inName; \ + } +#define LEAD_CASE(n) \ + case BT_LEAD ## n: START_NAME ptr += (n - MINBPC); break; + LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE + case BT_NONASCII: + case BT_NMSTRT: + case BT_HEX: + START_NAME + break; +#undef START_NAME + case BT_QUOT: + if (state != inValue) { + if (nAtts < attsMax) + atts[nAtts].valuePtr = ptr + MINBPC; + state = inValue; + open = BT_QUOT; + } + else if (open == BT_QUOT) { + state = other; + if (nAtts < attsMax) + atts[nAtts].valueEnd = ptr; + nAtts++; + } + break; + case BT_APOS: + if (state != inValue) { + if (nAtts < attsMax) + atts[nAtts].valuePtr = ptr + MINBPC; + state = inValue; + open = BT_APOS; + } + else if (open == BT_APOS) { + state = other; + if (nAtts < attsMax) + atts[nAtts].valueEnd = ptr; + nAtts++; + } + break; + case BT_AMP: + if (nAtts < attsMax) + atts[nAtts].normalized = 0; + break; + case BT_S: + if (state == inName) + state = other; + else if (state == inValue + && nAtts < attsMax + && atts[nAtts].normalized + && (ptr == atts[nAtts].valuePtr + || BYTE_TO_ASCII(enc, ptr) != ' ' + || BYTE_TO_ASCII(enc, ptr + MINBPC) == ' ' + || BYTE_TYPE(enc, ptr + MINBPC) == open)) + atts[nAtts].normalized = 0; + break; + case BT_CR: case BT_LF: + /* This case ensures that the first attribute name is counted + Apart from that we could just change state on the quote. */ + if (state == inName) + state = other; + else if (state == inValue && nAtts < attsMax) + atts[nAtts].normalized = 0; + break; + case BT_GT: + case BT_SOL: + if (state != inValue) + return nAtts; + break; + default: + break; + } + } + /* not reached */ +} + +static +int PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr) +{ + int result = 0; + /* skip &# */ + ptr += 2*MINBPC; + if (CHAR_MATCHES(enc, ptr, 'x')) { + for (ptr += MINBPC; !CHAR_MATCHES(enc, ptr, ';'); ptr += MINBPC) { + int c = BYTE_TO_ASCII(enc, ptr); + switch (c) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + result <<= 4; + result |= (c - '0'); + break; + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + result <<= 4; + result += 10 + (c - 'A'); + break; + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + result <<= 4; + result += 10 + (c - 'a'); + break; + } + if (result >= 0x110000) + return -1; + } + } + else { + for (; !CHAR_MATCHES(enc, ptr, ';'); ptr += MINBPC) { + int c = BYTE_TO_ASCII(enc, ptr); + result *= 10; + result += (c - '0'); + if (result >= 0x110000) + return -1; + } + } + return checkCharRefNumber(result); +} + +static +int PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr, const char *end) +{ + switch (end - ptr) { + case 2 * MINBPC: + if (CHAR_MATCHES(enc, ptr + MINBPC, 't')) { + switch (BYTE_TO_ASCII(enc, ptr)) { + case 'l': + return '<'; + case 'g': + return '>'; + } + } + break; + case 3 * MINBPC: + if (CHAR_MATCHES(enc, ptr, 'a')) { + ptr += MINBPC; + if (CHAR_MATCHES(enc, ptr, 'm')) { + ptr += MINBPC; + if (CHAR_MATCHES(enc, ptr, 'p')) + return '&'; + } + } + break; + case 4 * MINBPC: + switch (BYTE_TO_ASCII(enc, ptr)) { + case 'q': + ptr += MINBPC; + if (CHAR_MATCHES(enc, ptr, 'u')) { + ptr += MINBPC; + if (CHAR_MATCHES(enc, ptr, 'o')) { + ptr += MINBPC; + if (CHAR_MATCHES(enc, ptr, 't')) + return '"'; + } + } + break; + case 'a': + ptr += MINBPC; + if (CHAR_MATCHES(enc, ptr, 'p')) { + ptr += MINBPC; + if (CHAR_MATCHES(enc, ptr, 'o')) { + ptr += MINBPC; + if (CHAR_MATCHES(enc, ptr, 's')) + return '\''; + } + } + break; + } + } + return 0; +} + +static +int PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2) +{ + for (;;) { + switch (BYTE_TYPE(enc, ptr1)) { +#define LEAD_CASE(n) \ + case BT_LEAD ## n: \ + if (*ptr1++ != *ptr2++) \ + return 0; + LEAD_CASE(4) LEAD_CASE(3) LEAD_CASE(2) +#undef LEAD_CASE + /* fall through */ + if (*ptr1++ != *ptr2++) + return 0; + break; + case BT_NONASCII: + case BT_NMSTRT: + case BT_HEX: + case BT_DIGIT: + case BT_NAME: + case BT_MINUS: + if (*ptr2++ != *ptr1++) + return 0; +#if MINBPC > 1 + if (*ptr2++ != *ptr1++) + return 0; +#if MINBPC > 2 + if (*ptr2++ != *ptr1++) + return 0; +#if MINBPC > 3 + if (*ptr2++ != *ptr1++) + return 0; +#endif +#endif +#endif + break; + default: +#if MINBPC == 1 + if (*ptr1 == *ptr2) + return 1; +#endif + switch (BYTE_TYPE(enc, ptr2)) { + case BT_LEAD2: + case BT_LEAD3: + case BT_LEAD4: + case BT_NONASCII: + case BT_NMSTRT: + case BT_HEX: + case BT_DIGIT: + case BT_NAME: + case BT_MINUS: + return 0; + default: + return 1; + } + } + } + /* not reached */ +} + +static +int PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1, const char *ptr2) +{ + for (; *ptr2; ptr1 += MINBPC, ptr2++) { + if (!CHAR_MATCHES(end, ptr1, *ptr2)) + return 0; + } + switch (BYTE_TYPE(enc, ptr1)) { + case BT_LEAD2: + case BT_LEAD3: + case BT_LEAD4: + case BT_NONASCII: + case BT_NMSTRT: + case BT_HEX: + case BT_DIGIT: + case BT_NAME: + case BT_MINUS: + return 0; + default: + return 1; + } +} + +static +int PREFIX(nameLength)(const ENCODING *enc, const char *ptr) +{ + const char *start = ptr; + for (;;) { + switch (BYTE_TYPE(enc, ptr)) { +#define LEAD_CASE(n) \ + case BT_LEAD ## n: ptr += n; break; + LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE + case BT_NONASCII: + case BT_NMSTRT: + case BT_HEX: + case BT_DIGIT: + case BT_NAME: + case BT_MINUS: + ptr += MINBPC; + break; + default: + return ptr - start; + } + } +} + +static +const char *PREFIX(skipS)(const ENCODING *enc, const char *ptr) +{ + for (;;) { + switch (BYTE_TYPE(enc, ptr)) { + case BT_LF: + case BT_CR: + case BT_S: + ptr += MINBPC; + break; + default: + return ptr; + } + } +} + +static +void PREFIX(updatePosition)(const ENCODING *enc, + const char *ptr, + const char *end, + POSITION *pos) +{ + while (ptr != end) { + switch (BYTE_TYPE(enc, ptr)) { +#define LEAD_CASE(n) \ + case BT_LEAD ## n: \ + ptr += n; \ + break; + LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE + case BT_LF: + pos->columnNumber = (unsigned)-1; + pos->lineNumber++; + ptr += MINBPC; + break; + case BT_CR: + pos->lineNumber++; + ptr += MINBPC; + if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF) + ptr += MINBPC; + pos->columnNumber = (unsigned)-1; + break; + default: + ptr += MINBPC; + break; + } + pos->columnNumber++; + } +} + +#undef DO_LEAD_CASE +#undef MULTIBYTE_CASES +#undef INVALID_CASES +#undef CHECK_NAME_CASE +#undef CHECK_NAME_CASES +#undef CHECK_NMSTRT_CASE +#undef CHECK_NMSTRT_CASES diff --git a/mozilla/extensions/transformiix/source/xml/parser/xmltok/xmltok_impl.h b/mozilla/extensions/transformiix/source/xml/parser/xmltok/xmltok_impl.h new file mode 100644 index 00000000000..3b0444ad2a6 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/xmltok/xmltok_impl.h @@ -0,0 +1,60 @@ +/* +The contents of this file are subject to the Mozilla Public License +Version 1.0 (the "License"); you may not use this file except in +compliance with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" +basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific language governing rights and limitations +under the License. + +The Original Code is expat. + +The Initial Developer of the Original Code is James Clark. +Portions created by James Clark are Copyright (C) 1998 +James Clark. All Rights Reserved. + +Contributor(s): +*/ + +enum { + BT_NONXML, + BT_MALFORM, + BT_LT, + BT_AMP, + BT_RSQB, + BT_LEAD2, + BT_LEAD3, + BT_LEAD4, + BT_TRAIL, + BT_CR, + BT_LF, + BT_GT, + BT_QUOT, + BT_APOS, + BT_EQUALS, + BT_QUEST, + BT_EXCL, + BT_SOL, + BT_SEMI, + BT_NUM, + BT_LSQB, + BT_S, + BT_NMSTRT, + BT_HEX, + BT_DIGIT, + BT_NAME, + BT_MINUS, + BT_OTHER, /* known not to be a name or name start character */ + BT_NONASCII, /* might be a name or name start character */ + BT_PERCNT, + BT_LPAR, + BT_RPAR, + BT_AST, + BT_PLUS, + BT_COMMA, + BT_VERBAR +}; + +#include diff --git a/mozilla/extensions/transformiix/source/xml/parser/xmlwf-ignore/CODEPAGE.C b/mozilla/extensions/transformiix/source/xml/parser/xmlwf-ignore/CODEPAGE.C new file mode 100644 index 00000000000..159a12a0695 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/xmlwf-ignore/CODEPAGE.C @@ -0,0 +1,77 @@ +/* +The contents of this file are subject to the Mozilla Public License +Version 1.0 (the "License"); you may not use this file except in +compliance with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" +basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific language governing rights and limitations +under the License. + +The Original Code is expat. + +The Initial Developer of the Original Code is James Clark. +Portions created by James Clark are Copyright (C) 1998 +James Clark. All Rights Reserved. + +Contributor(s): +*/ + +#include "codepage.h" + +#ifdef WIN32 +#include + +int codepageMap(int cp, int *map) +{ + int i; + CPINFO info; + if (!GetCPInfo(cp, &info) || info.MaxCharSize > 2) + return 0; + for (i = 0; i < 256; i++) + map[i] = -1; + if (info.MaxCharSize > 1) { + for (i = 0; i < MAX_LEADBYTES; i++) { + int j, lim; + if (info.LeadByte[i] == 0 && info.LeadByte[i + 1] == 0) + break; + lim = info.LeadByte[i + 1]; + for (j = info.LeadByte[i]; j < lim; j++) + map[j] = -2; + } + } + for (i = 0; i < 256; i++) { + if (map[i] == -1) { + char c = i; + unsigned short n; + if (MultiByteToWideChar(cp, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, + &c, 1, &n, 1) == 1) + map[i] = n; + } + } + return 1; +} + +int codepageConvert(int cp, const char *p) +{ + unsigned short c; + if (MultiByteToWideChar(cp, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, + p, 2, &c, 1) == 1) + return c; + return -1; +} + +#else /* not WIN32 */ + +int codepageMap(int cp, int *map) +{ + return 0; +} + +int codepageConvert(int cp, const char *p) +{ + return -1; +} + +#endif /* not WIN32 */ diff --git a/mozilla/extensions/transformiix/source/xml/parser/xmlwf-ignore/CODEPAGE.H b/mozilla/extensions/transformiix/source/xml/parser/xmlwf-ignore/CODEPAGE.H new file mode 100644 index 00000000000..94c66f563f7 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/xmlwf-ignore/CODEPAGE.H @@ -0,0 +1,22 @@ +/* +The contents of this file are subject to the Mozilla Public License +Version 1.0 (the "License"); you may not use this file except in +compliance with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" +basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific language governing rights and limitations +under the License. + +The Original Code is expat. + +The Initial Developer of the Original Code is James Clark. +Portions created by James Clark are Copyright (C) 1998 +James Clark. All Rights Reserved. + +Contributor(s): +*/ + +int codepageMap(int cp, int *map); +int codepageConvert(int cp, const char *p); diff --git a/mozilla/extensions/transformiix/source/xml/parser/xmlwf-ignore/FILEMAP.H b/mozilla/extensions/transformiix/source/xml/parser/xmlwf-ignore/FILEMAP.H new file mode 100644 index 00000000000..60a1f6775ec --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/xmlwf-ignore/FILEMAP.H @@ -0,0 +1,32 @@ +/* +The contents of this file are subject to the Mozilla Public License +Version 1.0 (the "License"); you may not use this file except in +compliance with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" +basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific language governing rights and limitations +under the License. + +The Original Code is expat. + +The Initial Developer of the Original Code is James Clark. +Portions created by James Clark are Copyright (C) 1998 +James Clark. All Rights Reserved. + +Contributor(s): +*/ + + +#include + +#ifdef XML_UNICODE +int filemap(const wchar_t *name, + void (*processor)(const void *, size_t, const wchar_t *, void *arg), + void *arg); +#else +int filemap(const char *name, + void (*processor)(const void *, size_t, const char *, void *arg), + void *arg); +#endif diff --git a/mozilla/extensions/transformiix/source/xml/parser/xmlwf-ignore/XMLWF.C b/mozilla/extensions/transformiix/source/xml/parser/xmlwf-ignore/XMLWF.C new file mode 100644 index 00000000000..9903e399e94 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/xmlwf-ignore/XMLWF.C @@ -0,0 +1,653 @@ +/* +The contents of this file are subject to the Mozilla Public License +Version 1.0 (the "License"); you may not use this file except in +compliance with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" +basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific language governing rights and limitations +under the License. + +The Original Code is expat. + +The Initial Developer of the Original Code is James Clark. +Portions created by James Clark are Copyright (C) 1998 +James Clark. All Rights Reserved. + +Contributor(s): +*/ + +#include "xmlparse.h" +#include "filemap.h" +#include "codepage.h" + +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +#include +#endif + +#ifdef _POSIX_SOURCE +#include +#endif + +#ifndef O_BINARY +#ifdef _O_BINARY +#define O_BINARY _O_BINARY +#else +#define O_BINARY 0 +#endif +#endif + +#ifdef _MSC_VER +#include +#endif + +#ifdef _DEBUG +#define READ_SIZE 16 +#else +#define READ_SIZE (1024*8) +#endif + +#ifdef XML_UNICODE +#ifndef XML_UNICODE_WCHAR_T +#error xmlwf requires a 16-bit Unicode-compatible wchar_t +#endif +#define T(x) L ## x +#define ftprintf fwprintf +#define tfopen _wfopen +#define fputts fputws +#define puttc putwc +#define tcscmp wcscmp +#define tcscpy wcscpy +#define tcscat wcscat +#define tcschr wcschr +#define tcsrchr wcsrchr +#define tcslen wcslen +#define tperror _wperror +#define topen _wopen +#define tmain wmain +#define tremove _wremove +#else /* not XML_UNICODE */ +#define T(x) x +#define ftprintf fprintf +#define tfopen fopen +#define fputts fputs +#define puttc putc +#define tcscmp strcmp +#define tcscpy strcpy +#define tcscat strcat +#define tcschr strchr +#define tcsrchr strrchr +#define tcslen strlen +#define tperror perror +#define topen open +#define tmain main +#define tremove remove +#endif /* not XML_UNICODE */ + +static void characterData(void *userData, const XML_Char *s, int len) +{ + FILE *fp = userData; + for (; len > 0; --len, ++s) { + switch (*s) { + case T('&'): + fputts(T("&"), fp); + break; + case T('<'): + fputts(T("<"), fp); + break; + case T('>'): + fputts(T(">"), fp); + break; + case T('"'): + fputts(T("""), fp); + break; + case 9: + case 10: + case 13: + ftprintf(fp, T("&#%d;"), *s); + break; + default: + puttc(*s, fp); + break; + } + } +} + +/* Lexicographically comparing UTF-8 encoded attribute values, +is equivalent to lexicographically comparing based on the character number. */ + +static int attcmp(const void *att1, const void *att2) +{ + return tcscmp(*(const XML_Char **)att1, *(const XML_Char **)att2); +} + +static void startElement(void *userData, const XML_Char *name, const XML_Char **atts) +{ + int nAtts; + const XML_Char **p; + FILE *fp = userData; + puttc(T('<'), fp); + fputts(name, fp); + + p = atts; + while (*p) + ++p; + nAtts = (p - atts) >> 1; + if (nAtts > 1) + qsort((void *)atts, nAtts, sizeof(XML_Char *) * 2, attcmp); + while (*atts) { + puttc(T(' '), fp); + fputts(*atts++, fp); + puttc(T('='), fp); + puttc(T('"'), fp); + characterData(userData, *atts, tcslen(*atts)); + puttc(T('"'), fp); + atts++; + } + puttc(T('>'), fp); +} + +static void endElement(void *userData, const XML_Char *name) +{ + FILE *fp = userData; + puttc(T('<'), fp); + puttc(T('/'), fp); + fputts(name, fp); + puttc(T('>'), fp); +} + +static void processingInstruction(void *userData, const XML_Char *target, const XML_Char *data) +{ + FILE *fp = userData; + puttc(T('<'), fp); + puttc(T('?'), fp); + fputts(target, fp); + puttc(T(' '), fp); + fputts(data, fp); + puttc(T('?'), fp); + puttc(T('>'), fp); +} + +static void defaultCharacterData(XML_Parser parser, const XML_Char *s, int len) +{ + XML_DefaultCurrent(parser); +} + +static void defaultStartElement(XML_Parser parser, const XML_Char *name, const XML_Char **atts) +{ + XML_DefaultCurrent(parser); +} + +static void defaultEndElement(XML_Parser parser, const XML_Char *name) +{ + XML_DefaultCurrent(parser); +} + +static void defaultProcessingInstruction(XML_Parser parser, const XML_Char *target, const XML_Char *data) +{ + XML_DefaultCurrent(parser); +} + +static void markup(XML_Parser parser, const XML_Char *s, int len) +{ + FILE *fp = XML_GetUserData(parser); + for (; len > 0; --len, ++s) + puttc(*s, fp); +} + +static +void metaLocation(XML_Parser parser) +{ + const XML_Char *uri = XML_GetBase(parser); + if (uri) + ftprintf(XML_GetUserData(parser), T(" uri=\"%s\""), uri); + ftprintf(XML_GetUserData(parser), + T(" byte=\"%ld\" line=\"%d\" col=\"%d\""), + XML_GetCurrentByteIndex(parser), + XML_GetCurrentLineNumber(parser), + XML_GetCurrentColumnNumber(parser)); +} + +static +void metaStartElement(XML_Parser parser, const XML_Char *name, const XML_Char **atts) +{ + FILE *fp = XML_GetUserData(parser); + ftprintf(fp, T("\n"), fp); + do { + ftprintf(fp, T("\n"), fp); + } while (*(atts += 2)); + fputts(T("\n"), fp); + } + else + fputts(T("/>\n"), fp); +} + +static +void metaEndElement(XML_Parser parser, const XML_Char *name) +{ + FILE *fp = XML_GetUserData(parser); + ftprintf(fp, T("\n"), fp); +} + +static +void metaProcessingInstruction(XML_Parser parser, const XML_Char *target, const XML_Char *data) +{ + FILE *fp = XML_GetUserData(parser); + ftprintf(fp, T("\n"), fp); +} + +static +void metaCharacterData(XML_Parser parser, const XML_Char *s, int len) +{ + FILE *fp = XML_GetUserData(parser); + fputts(T("\n"), fp); +} + +static +void metaUnparsedEntityDecl(XML_Parser parser, + const XML_Char *entityName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName) +{ + FILE *fp = XML_GetUserData(parser); + ftprintf(fp, T("\n"), fp); +} + +static +void metaNotationDecl(XML_Parser parser, + const XML_Char *notationName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId) +{ + FILE *fp = XML_GetUserData(parser); + ftprintf(fp, T("\n"), fp); +} + +typedef struct { + XML_Parser parser; + int *retPtr; +} PROCESS_ARGS; + +static +void reportError(XML_Parser parser, const XML_Char *filename) +{ + int code = XML_GetErrorCode(parser); + const XML_Char *message = XML_ErrorString(code); + if (message) + ftprintf(stdout, T("%s:%d:%ld: %s\n"), + filename, + XML_GetErrorLineNumber(parser), + XML_GetErrorColumnNumber(parser), + message); + else + ftprintf(stderr, T("%s: (unknown message %d)\n"), filename, code); +} + +static +void processFile(const void *data, size_t size, const XML_Char *filename, void *args) +{ + XML_Parser parser = ((PROCESS_ARGS *)args)->parser; + int *retPtr = ((PROCESS_ARGS *)args)->retPtr; + if (!XML_Parse(parser, data, size, 1)) { + reportError(parser, filename); + *retPtr = 0; + } + else + *retPtr = 1; +} + +static +int isAsciiLetter(XML_Char c) +{ + return (T('a') <= c && c <= T('z')) || (T('A') <= c && c <= T('Z')); +} + +static +const XML_Char *resolveSystemId(const XML_Char *base, const XML_Char *systemId, XML_Char **toFree) +{ + XML_Char *s; + *toFree = 0; + if (!base + || *systemId == T('/') +#ifdef WIN32 + || *systemId == T('\\') + || (isAsciiLetter(systemId[0]) && systemId[1] == T(':')) +#endif + ) + return systemId; + *toFree = (XML_Char *)malloc((tcslen(base) + tcslen(systemId) + 2)*sizeof(XML_Char)); + if (!*toFree) + return systemId; + tcscpy(*toFree, base); + s = *toFree; + if (tcsrchr(s, T('/'))) + s = tcsrchr(s, T('/')) + 1; +#ifdef WIN32 + if (tcsrchr(s, T('\\'))) + s = tcsrchr(s, T('\\')) + 1; +#endif + tcscpy(s, systemId); + return *toFree; +} + +static +int externalEntityRefFilemap(XML_Parser parser, + const XML_Char *openEntityNames, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId) +{ + int result; + XML_Char *s; + const XML_Char *filename; + XML_Parser entParser = XML_ExternalEntityParserCreate(parser, openEntityNames, 0); + PROCESS_ARGS args; + args.retPtr = &result; + args.parser = entParser; + filename = resolveSystemId(base, systemId, &s); + XML_SetBase(entParser, filename); + if (!filemap(filename, processFile, &args)) + result = 0; + free(s); + XML_ParserFree(entParser); + return result; +} + +static +int processStream(const XML_Char *filename, XML_Parser parser) +{ + int fd = topen(filename, O_BINARY|O_RDONLY); + if (fd < 0) { + tperror(filename); + return 0; + } + for (;;) { + int nread; + char *buf = XML_GetBuffer(parser, READ_SIZE); + if (!buf) { + close(fd); + ftprintf(stderr, T("%s: out of memory\n"), filename); + return 0; + } + nread = read(fd, buf, READ_SIZE); + if (nread < 0) { + tperror(filename); + close(fd); + return 0; + } + if (!XML_ParseBuffer(parser, nread, nread == 0)) { + reportError(parser, filename); + close(fd); + return 0; + } + if (nread == 0) { + close(fd); + break;; + } + } + return 1; +} + +static +int externalEntityRefStream(XML_Parser parser, + const XML_Char *openEntityNames, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId) +{ + XML_Char *s; + const XML_Char *filename; + int ret; + XML_Parser entParser = XML_ExternalEntityParserCreate(parser, openEntityNames, 0); + filename = resolveSystemId(base, systemId, &s); + XML_SetBase(entParser, filename); + ret = processStream(filename, entParser); + free(s); + XML_ParserFree(entParser); + return ret; +} + +static +int unknownEncodingConvert(void *data, const char *p) +{ + return codepageConvert(*(int *)data, p); +} + +static +int unknownEncoding(void *userData, + const XML_Char *name, + XML_Encoding *info) +{ + int cp; + static const XML_Char prefixL[] = T("windows-"); + static const XML_Char prefixU[] = T("WINDOWS-"); + int i; + + for (i = 0; prefixU[i]; i++) + if (name[i] != prefixU[i] && name[i] != prefixL[i]) + return 0; + + cp = 0; + for (; name[i]; i++) { + static const XML_Char digits[] = T("0123456789"); + const XML_Char *s = tcschr(digits, name[i]); + if (!s) + return 0; + cp *= 10; + cp += s - digits; + if (cp >= 0x10000) + return 0; + } + if (!codepageMap(cp, info->map)) + return 0; + info->convert = unknownEncodingConvert; + /* We could just cast the code page integer to a void *, + and avoid the use of release. */ + info->release = free; + info->data = malloc(sizeof(int)); + if (!info->data) + return 0; + *(int *)info->data = cp; + return 1; +} + +static +void usage(const XML_Char *prog) +{ + ftprintf(stderr, T("usage: %s [-r] [-w] [-x] [-d output-dir] [-e encoding] file ...\n"), prog); + exit(1); +} + +int tmain(int argc, XML_Char **argv) +{ + int i; + const XML_Char *outputDir = 0; + const XML_Char *encoding = 0; + int useFilemap = 1; + int processExternalEntities = 0; + int windowsCodePages = 0; + int outputType = 0; + +#ifdef _MSC_VER + _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF); +#endif + + i = 1; + while (i < argc && argv[i][0] == T('-')) { + int j; + if (argv[i][1] == T('-') && argv[i][2] == T('\0')) { + i++; + break; + } + j = 1; + if (argv[i][j] == T('r')) { + useFilemap = 0; + j++; + } + if (argv[i][j] == T('x')) { + processExternalEntities = 1; + j++; + } + if (argv[i][j] == T('w')) { + windowsCodePages = 1; + j++; + } + if (argv[i][j] == T('m')) { + outputType = 'm'; + j++; + } + if (argv[i][j] == T('c')) { + outputType = 'c'; + j++; + } + if (argv[i][j] == T('d')) { + if (argv[i][j + 1] == T('\0')) { + if (++i == argc) + usage(argv[0]); + outputDir = argv[i]; + } + else + outputDir = argv[i] + j + 1; + i++; + } + else if (argv[i][j] == T('e')) { + if (argv[i][j + 1] == T('\0')) { + if (++i == argc) + usage(argv[0]); + encoding = argv[i]; + } + else + encoding = argv[i] + j + 1; + i++; + } + else if (argv[i][j] == T('\0') && j > 1) + i++; + else + usage(argv[0]); + } + if (i == argc) + usage(argv[0]); + for (; i < argc; i++) { + FILE *fp = 0; + XML_Char *outName = 0; + int result; + XML_Parser parser = XML_ParserCreate(encoding); + if (outputDir) { + const XML_Char *file = argv[i]; + if (tcsrchr(file, T('/'))) + file = tcsrchr(file, T('/')) + 1; +#ifdef WIN32 + if (tcsrchr(file, T('\\'))) + file = tcsrchr(file, T('\\')) + 1; +#endif + outName = malloc((tcslen(outputDir) + tcslen(file) + 2) * sizeof(XML_Char)); + tcscpy(outName, outputDir); + tcscat(outName, T("/")); + tcscat(outName, file); + fp = tfopen(outName, T("wb")); + if (!fp) { + tperror(outName); + exit(1); + } +#ifdef XML_UNICODE + puttc(0xFEFF, fp); +#endif + XML_SetUserData(parser, fp); + switch (outputType) { + case 'm': + XML_UseParserAsHandlerArg(parser); + fputts(T("\n"), fp); + XML_SetElementHandler(parser, metaStartElement, metaEndElement); + XML_SetProcessingInstructionHandler(parser, metaProcessingInstruction); + XML_SetCharacterDataHandler(parser, metaCharacterData); + XML_SetUnparsedEntityDeclHandler(parser, metaUnparsedEntityDecl); + XML_SetNotationDeclHandler(parser, metaNotationDecl); + break; + case 'c': + XML_UseParserAsHandlerArg(parser); + XML_SetDefaultHandler(parser, markup); + XML_SetElementHandler(parser, defaultStartElement, defaultEndElement); + XML_SetCharacterDataHandler(parser, defaultCharacterData); + XML_SetProcessingInstructionHandler(parser, defaultProcessingInstruction); + break; + default: + XML_SetElementHandler(parser, startElement, endElement); + XML_SetCharacterDataHandler(parser, characterData); + XML_SetProcessingInstructionHandler(parser, processingInstruction); + break; + } + } + if (windowsCodePages) + XML_SetUnknownEncodingHandler(parser, unknownEncoding, 0); + if (!XML_SetBase(parser, argv[i])) { + ftprintf(stderr, T("%s: out of memory"), argv[0]); + exit(1); + } + if (processExternalEntities) + XML_SetExternalEntityRefHandler(parser, + useFilemap + ? externalEntityRefFilemap + : externalEntityRefStream); + if (useFilemap) { + PROCESS_ARGS args; + args.retPtr = &result; + args.parser = parser; + if (!filemap(argv[i], processFile, &args)) + result = 0; + } + else + result = processStream(argv[i], parser); + if (outputDir) { + if (outputType == 'm') + fputts(T("\n"), fp); + fclose(fp); + if (!result) + tremove(outName); + free(outName); + } + XML_ParserFree(parser); + } + return 0; +} diff --git a/mozilla/extensions/transformiix/source/xml/parser/xmlwf-ignore/readfilemap.c b/mozilla/extensions/transformiix/source/xml/parser/xmlwf-ignore/readfilemap.c new file mode 100644 index 00000000000..cfdfa2a7974 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/xmlwf-ignore/readfilemap.c @@ -0,0 +1,89 @@ +/* +The contents of this file are subject to the Mozilla Public License +Version 1.0 (the "License"); you may not use this file except in +compliance with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" +basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific language governing rights and limitations +under the License. + +The Original Code is expat. + +The Initial Developer of the Original Code is James Clark. +Portions created by James Clark are Copyright (C) 1998 +James Clark. All Rights Reserved. + +Contributor(s): +*/ + +#include +#include +#include +#include +#include + +#ifndef S_ISREG +#ifndef S_IFREG +#define S_IFREG _S_IFREG +#endif +#ifndef S_IFMT +#define S_IFMT _S_IFMT +#endif +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#endif /* not S_ISREG */ + +#ifndef O_BINARY +#ifdef _O_BINARY +#define O_BINARY _O_BINARY +#else +#define O_BINARY 0 +#endif +#endif + +int filemap(const char *name, + void (*processor)(const void *, size_t, const char *, void *arg), + void *arg) +{ + size_t nbytes; + int fd; + int n; + struct stat sb; + void *p; + + fd = open(name, O_RDONLY|O_BINARY); + if (fd < 0) { + perror(name); + return 0; + } + if (fstat(fd, &sb) < 0) { + perror(name); + return 0; + } + if (!S_ISREG(sb.st_mode)) { + fprintf(stderr, "%s: not a regular file\n", name); + return 0; + } + nbytes = sb.st_size; + p = malloc(nbytes); + if (!p) { + fprintf(stderr, "%s: out of memory\n", name); + return 0; + } + n = read(fd, p, nbytes); + if (n < 0) { + perror(name); + close(fd); + return 0; + } + if (n != nbytes) { + fprintf(stderr, "%s: read unexpected number of bytes\n", name); + close(fd); + return 0; + } + processor(p, nbytes, name, arg); + free(p); + close(fd); + return 1; +} diff --git a/mozilla/extensions/transformiix/source/xml/parser/xmlwf-ignore/unixfilemap.c b/mozilla/extensions/transformiix/source/xml/parser/xmlwf-ignore/unixfilemap.c new file mode 100644 index 00000000000..1207d12b92f --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/xmlwf-ignore/unixfilemap.c @@ -0,0 +1,72 @@ +/* +The contents of this file are subject to the Mozilla Public License +Version 1.0 (the "License"); you may not use this file except in +compliance with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" +basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific language governing rights and limitations +under the License. + +The Original Code is expat. + +The Initial Developer of the Original Code is James Clark. +Portions created by James Clark are Copyright (C) 1998 +James Clark. All Rights Reserved. + +Contributor(s): +*/ + +#include +#include +#include +#include +#include +#include +#include + +#ifndef MAP_FILE +#define MAP_FILE 0 +#endif + +#include "filemap.h" + +int filemap(const char *name, + void (*processor)(const void *, size_t, const char *, void *arg), + void *arg) +{ + int fd; + size_t nbytes; + struct stat sb; + void *p; + + fd = open(name, O_RDONLY); + if (fd < 0) { + perror(name); + return 0; + } + if (fstat(fd, &sb) < 0) { + perror(name); + close(fd); + return 0; + } + if (!S_ISREG(sb.st_mode)) { + close(fd); + fprintf(stderr, "%s: not a regular file\n", name); + return 0; + } + + nbytes = sb.st_size; + p = (void *)mmap((caddr_t)0, (size_t)nbytes, PROT_READ, + MAP_FILE|MAP_PRIVATE, fd, (off_t)0); + if (p == (void *)-1) { + perror(name); + close(fd); + return 0; + } + processor(p, nbytes, name, arg); + munmap((caddr_t)p, nbytes); + close(fd); + return 1; +} diff --git a/mozilla/extensions/transformiix/source/xml/parser/xmlwf-ignore/win32filemap.c b/mozilla/extensions/transformiix/source/xml/parser/xmlwf-ignore/win32filemap.c new file mode 100644 index 00000000000..488aa685f29 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/parser/xmlwf-ignore/win32filemap.c @@ -0,0 +1,102 @@ +/* +The contents of this file are subject to the Mozilla Public License +Version 1.0 (the "License"); you may not use this file except in +compliance with the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" +basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific language governing rights and limitations +under the License. + +The Original Code is expat. + +The Initial Developer of the Original Code is James Clark. +Portions created by James Clark are Copyright (C) 1998 +James Clark. All Rights Reserved. + +Contributor(s): +*/ + +#define STRICT 1 +#ifdef XML_UNICODE +#define UNICODE +#define _UNICODE +#endif /* XML_UNICODE */ +#include +#include +#include +#include "filemap.h" + +static void win32perror(const TCHAR *); + +int filemap(const TCHAR *name, + void (*processor)(const void *, size_t, const TCHAR *, void *arg), + void *arg) +{ + HANDLE f; + HANDLE m; + DWORD size; + DWORD sizeHi; + void *p; + + f = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, + FILE_FLAG_SEQUENTIAL_SCAN, NULL); + if (f == INVALID_HANDLE_VALUE) { + win32perror(name); + return 0; + } + size = GetFileSize(f, &sizeHi); + if (size == (DWORD)-1) { + win32perror(name); + return 0; + } + if (sizeHi) { + _ftprintf(stderr, _T("%s: bigger than 2Gb\n"), name); + return 0; + } + /* CreateFileMapping barfs on zero length files */ + if (size == 0) { + static const char c = '\0'; + processor(&c, 0, name, arg); + CloseHandle(f); + return 1; + } + m = CreateFileMapping(f, NULL, PAGE_READONLY, 0, 0, NULL); + if (m == NULL) { + win32perror(name); + CloseHandle(f); + return 0; + } + p = MapViewOfFile(m, FILE_MAP_READ, 0, 0, 0); + if (p == NULL) { + win32perror(name); + CloseHandle(m); + CloseHandle(f); + return 0; + } + processor(p, size, name, arg); + UnmapViewOfFile(p); + CloseHandle(m); + CloseHandle(f); + return 1; +} + +static +void win32perror(const TCHAR *s) +{ + LPVOID buf; + if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &buf, + 0, + NULL)) { + _ftprintf(stderr, _T("%s: %s"), s, buf); + fflush(stderr); + LocalFree(buf); + } + else + _ftprintf(stderr, _T("%s: unknown Windows error\n"), s); +} diff --git a/mozilla/extensions/transformiix/source/xml/printer/HTMLPrinter.cpp b/mozilla/extensions/transformiix/source/xml/printer/HTMLPrinter.cpp new file mode 100644 index 00000000000..68ec03367cb --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/printer/HTMLPrinter.cpp @@ -0,0 +1,175 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "Printers.h" + + //--------------------------------/ + //- Implementation of HTMLPrinter -/ +//--------------------------------/ + +/** + * A class for printing XML nodes. + * This class was ported from XSL:P Java source + * @author Keith Visco +**/ + //---------------/ + //- Contructors -/ +//---------------/ +/** + * Default Constructor. Creates a new HTMLPrinter using cout as the ostream. +**/ +HTMLPrinter::HTMLPrinter() : XMLPrinter() { + initialize(cout, DEFAULT_INDENT); +} //-- HTMLPrinter + +/** + * Creates a new HTML Printer using the given ostream for output + * @param os the out stream to use for output +**/ +HTMLPrinter::HTMLPrinter(ostream& os) : XMLPrinter(os) { + initialize(os, DEFAULT_INDENT); +} //-- HTMLPrinter + +/** + * Creates a new HTML Printer using the given ostream + * for output, and nodes are indenting using the specified + * indent size + * @param os the out stream to use for output + * @param indent the number of spaces to indent +**/ +HTMLPrinter::HTMLPrinter (ostream& os, int indent) : XMLPrinter(os, indent) { + initialize(os, indent); +} //-- HTMLPrinter + +void HTMLPrinter::initialize(ostream& os, int indentSize) { + ostreamPtr = &os; + XMLPrinter::setUseEmptyElementShorthand(MB_FALSE); + setUseFormat(MB_TRUE); + + MITREObject* nonNull = &htmlEmptyTags; + htmlEmptyTags.put("BR", nonNull); + htmlEmptyTags.put("HR", nonNull); + htmlEmptyTags.put("IMAGE", nonNull); + htmlEmptyTags.put("INPUT", nonNull); + htmlEmptyTags.put("LI", nonNull); + htmlEmptyTags.put("META", nonNull); + htmlEmptyTags.put("P", nonNull); + +} //-- initialize + +/** + * Sets whether or not this HTMLPrinter should add whitespace + * to pretty print the XML tree + * @param useFormat a boolean to indicate whether to allow the + * Printer to add whitespace to the XML tree. (true by default) +**/ + +void HTMLPrinter::setUseFormat(MBool useFormat) { + this->useFormat = useFormat; + XMLPrinter::setUseFormat(useFormat); +} //-- setUseFormat + + //---------------------/ + //- Protected Methods -/ +//---------------------/ + +/** + * prints the given node to this HTMLPrinter's Writer. If the + * useFormat flag has been set, the node will be printed with + * indentation equal to currentIndent + indentSize + * @param node the Node to print + * @param currentIndent the current indent String + * @return true, if and only if a new line was printed at + * the end of printing the given node +**/ +MBool HTMLPrinter::print(Node* node, String& currentIndent) { + + ostream& out = *this->ostreamPtr; + + //-- if (node == null) return false; + + NodeList* nl; + + switch(node->getNodeType()) { + + //-- print Document Node + case Node::DOCUMENT_NODE: + { + out << "" <getChildNodes(); + for (int i = 0; i < nl->getLength(); i++) { + print(nl->item(i),currentIndent); + } + break; + } + case Node::ELEMENT_NODE : + { + String nodeName = node->getNodeName(); + nodeName.toUpperCase(); + + //-- handle special elements + if (node->hasChildNodes() || ( !htmlEmptyTags.get(nodeName) )) { + return XMLPrinter::print(node, currentIndent); + } + else { + Element* element = (Element*)node; + out << L_ANGLE_BRACKET; + out << element->getNodeName(); + NamedNodeMap* attList = element->getAttributes(); + int size = 0; + if (attList) size = attList->getLength(); + Attr* att = 0; + for (int i = 0; i < size; i++) { + att = (Attr*) attList->item(i); + out << SPACE; + out << att->getName(); + const DOMString& data = att->getValue(); + if (&data != &NULL_STRING) { + out << EQUALS << DOUBLE_QUOTE; + out << data; + out << DOUBLE_QUOTE; + } + } + out << R_ANGLE_BRACKET; + if (useFormat) { + Node* sibling = node->getNextSibling(); + if ((!sibling) || + (sibling->getNodeType() != Node::TEXT_NODE)) + { + out < + +#ifndef MITRE_PRINTERS_H +#define MITRE_PRINTERS_H + + +/** + * A class for printing XML nodes. + * This class was ported from XSL:P Java source + * @author Keith Visco (kvisco@mitre.org) +**/ +class XMLPrinter { + +public: + + /** + * The default indent size + **/ + static const int DEFAULT_INDENT; + + //---------------/ + //- Contructors -/ + //---------------/ + + /** + * Default constructor. Uses stdout as the default ostream + **/ + XMLPrinter(); + + /** + * Creates a new XML Printer using the given PrintWriter + * for output + * @param writer the PrintWriter to use for output + **/ + XMLPrinter(ostream& os); + + /** + * Creates a new XML Printer using the given PrintWriter + * for output, and nodes are indenting using the specified + * indent size + * @param os the out stream to use for output + * @param indent the number of spaces to indent + **/ + XMLPrinter (ostream& os, int indent); + + /** + * Prints the given Node + * @param node the Node to print + **/ + virtual void print(Node* node); + + /** + * Sets the indent size + * @param indent the number of spaces to indent + **/ + virtual void setIndentSize(int indent); + + /** + * Sets whether or not to "unwrap" CDATA Sections + * when printing. By Default CDATA Sections are left as is. + * @param unescape the boolean indicating whether or not + * to unescape CDATA Sections + **/ + virtual void setUnescapeCDATA(MBool unescape); + + + virtual void setUseEmptyElementShorthand(MBool useShorthand); + + /** + * Sets whether or not this XMLPrinter should add whitespace + * to pretty print the XML tree + * @param useFormat a boolean to indicate whether to allow the + * XMLPrinter to add whitespace to the XML tree. (false by default) + **/ + virtual void setUseFormat(MBool useFormat); + +protected: + + static const String CDATA_END; + static const String CDATA_START; + static const String COMMENT_START; + static const String COMMENT_END; + static const String DOCTYPE_START; + static const String DOCTYPE_END; + static const String DOUBLE_QUOTE; + static const String EQUALS; + static const String FORWARD_SLASH; + static const String L_ANGLE_BRACKET; + static const String PI_START; + static const String PI_END; + static const String PUBLIC; + static const String R_ANGLE_BRACKET; + static const String SEMICOLON; + static const String SPACE; + static const String SYSTEM; + static const String XML_DECL; + + // chars + static const char AMPERSAND; + static const char GT; + static const char LT; + static const char DASH; + + //---------------------/ + //- Protected Methods -/ + //---------------------/ + + /** + * prints the given node to this XMLPrinter's Writer. If the + * useFormat flag has been set, the node will be printed with + * indentation equal to currentIndent + indentSize + * @param node the Node to print + * @param currentIndent the current indent String + * @return true, if and only if a new line was printed at + * the end of printing the given node + **/ + virtual MBool print(Node* node, String& currentIndent); + + /** + * Prints the proper UTF8 character + **/ + void printUTF8Char(DOM_CHAR ch) const; + + /** + * Print the proper UTF8 characters + * based on code submitted by Majkel Kretschmar + **/ + void printUTF8Chars(const DOMString& data); + + +private: + + static const char CR; + static const char LF; + static const String AMP_ENTITY; + static const String GT_ENTITY; + static const String LT_ENTITY; + static const String HEX_ENTITY; + + String version; + String entityTokens; + + /** + * The a string comprised of indentSize number of indentChar's + **/ + String indent; + + /** + * The character used for indentation + **/ + char indentChar; + + /** + * The size of the indentation + **/ + int indentSize; + + + /** + * The out stream to print results to + **/ + ostream* ostreamPtr; + + /** + * A flag indicating whether or not to unescape CDATA sections + **/ + MBool unescapeCDATA; + + MBool useEmptyElementShorthand; + + /** + * A flag indicating whether or not to add whitespace + * such as line breaks while printing + **/ + MBool useFormat; + + + + //-------------------/ + //- Private Methods -/ + //-------------------/ + + /** + * Called by Constructor to initialize Object instance + **/ + void initialize(ostream& os, int indentSize); + + /** + * Replaces any occurances of the special characters with their + * appropriate entity reference and prints the String + **/ + void printWithXMLEntities(const DOMString& data); + + /** + * Replaces any occurances of -- inside comment data with - - + * and prints the String + * @param data the comment data (does not include start and end tags) + **/ + void printComment(const DOMString& data); + +}; //-- XMLPrinter + +/** + * A class for printing an XML node as non-well-formed HTML + * This class was ported from XSL:P Java source + * @author Keith Visco (kvisco@mitre.org) +**/ +class HTMLPrinter : public XMLPrinter { + +public: + + //---------------/ + //- Contructors -/ + //---------------/ + + /** + * Default constructor uses cout as the default ostream + **/ + HTMLPrinter(); + + /** + * Creates a new XML Printer using the given PrintWriter + * for output + * @param writer the PrintWriter to use for output + **/ + HTMLPrinter(ostream& os); + + /** + * Creates a new XML Printer using the given PrintWriter + * for output, and nodes are indenting using the specified + * indent size + * @param os the out stream to use for output + * @param indent the number of spaces to indent + **/ + HTMLPrinter (ostream& os, int indent); + + /** + * Sets whether or not this XMLPrinter should add whitespace + * to pretty print the XML tree + * @param useFormat a boolean to indicate whether to allow the + * XMLPrinter to add whitespace to the XML tree. (false by default) + **/ + virtual void setUseFormat(MBool useFormat); + +protected: + + //---------------------/ + //- Protected Methods -/ + //---------------------/ + + /** + * prints the given node to this XMLPrinter's Writer. If the + * useFormat flag has been set, the node will be printed with + * indentation equal to currentIndent + indentSize + * @param node the Node to print + * @param currentIndent the current indent String + * @return true, if and only if a new line was printed at + * the end of printing the given node + **/ + virtual MBool print(Node* node, String& currentIndent); + +private: + + NamedMap htmlEmptyTags; + MBool useFormat; + + /** + * The out stream to print results to + **/ + ostream* ostreamPtr; + + //-------------------/ + //- Private Methods -/ + //-------------------/ + + /** + * Called by Constructor to initialize Object instance + **/ + void initialize(ostream& os, int indentSize); + +}; //-- HTMLPrinter + +#endif diff --git a/mozilla/extensions/transformiix/source/xml/printer/XMLPrinter.cpp b/mozilla/extensions/transformiix/source/xml/printer/XMLPrinter.cpp new file mode 100644 index 00000000000..f9af9bee17a --- /dev/null +++ b/mozilla/extensions/transformiix/source/xml/printer/XMLPrinter.cpp @@ -0,0 +1,433 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "Printers.h" + + //--------------------------------/ + //- Implementation of XMLPrinter -/ +//--------------------------------/ + +/** + * A class for printing XML nodes. + * This class was ported from XSL:P Java source + * @author Keith Visco +**/ + +/** + * The default indent size +**/ +const int XMLPrinter::DEFAULT_INDENT = 2; + + +const String XMLPrinter::AMP_ENTITY = "&"; +const String XMLPrinter::GT_ENTITY = ">"; +const String XMLPrinter::LT_ENTITY = "<"; +const String XMLPrinter::HEX_ENTITY = "&#"; + +const String XMLPrinter::CDATA_END = "]]>"; +const String XMLPrinter::CDATA_START = ""; +const String XMLPrinter::DOCTYPE_START = ""; +const String XMLPrinter::DOUBLE_QUOTE = "\""; +const String XMLPrinter::EQUALS = "="; +const String XMLPrinter::FORWARD_SLASH = "/"; +const String XMLPrinter::L_ANGLE_BRACKET = "<"; +const String XMLPrinter::PI_START = ""; +const String XMLPrinter::PUBLIC = "PUBLIC"; +const String XMLPrinter::R_ANGLE_BRACKET = ">"; +const String XMLPrinter::SEMICOLON = ";"; +const String XMLPrinter::SPACE = " "; +const String XMLPrinter::SYSTEM = "SYSTEM"; +const String XMLPrinter::XML_DECL = "xml version="; + +// chars +const char XMLPrinter::AMPERSAND = '&'; +const char XMLPrinter::GT = '>'; +const char XMLPrinter::LT = '<'; +const char XMLPrinter::DASH = '-'; +const char XMLPrinter::CR = '\r'; +const char XMLPrinter::LF = '\n'; + + + //---------------/ + //- Contructors -/ +//---------------/ + +/** + * Default Constructor. Creates a new XMLPrinter using cout as the ostream. +**/ +XMLPrinter::XMLPrinter() { + initialize(cout, DEFAULT_INDENT); +} //-- HTMLPrinter + +/** + * Creates a new XML Printer using the given ostream for output + * @param os the out stream to use for output +**/ +XMLPrinter::XMLPrinter(ostream& os) { + initialize(os, DEFAULT_INDENT); +} //-- XMLPrinter + +/** + * Creates a new XML Printer using the given ostream + * for output, and nodes are indenting using the specified + * indent size + * @param os the out stream to use for output + * @param indent the number of spaces to indent +**/ +XMLPrinter::XMLPrinter (ostream& os, int indent) { + initialize(os, indent); +} //-- XMLPrinter + +void XMLPrinter::initialize(ostream& os, int indentSize) { + ostreamPtr = &os; + indentChar = ' '; + version = "1.0"; + entityTokens = "&<>"; + setIndentSize(indentSize); + unescapeCDATA = MB_FALSE; + useEmptyElementShorthand = MB_TRUE; + useFormat = MB_FALSE; +} //-- initialize + +/** + * Prints the given Node + * @param node the Node to print +**/ +void XMLPrinter::print(Node* node) { + String currentIndent; + print(node,currentIndent); + *ostreamPtr<indentSize = indentSize; + indent.clear(); + for (int i = 0; i < indentSize; i++) { + indent.append(indentChar); + } +} //-- setIndentSize + +/** + * Sets whether or not to "unwrap" CDATA Sections + * when printing. By Default CDATA Sections are left as is. + * @param unescape the boolean indicating whether or not + * to unescape CDATA Sections +**/ +void XMLPrinter::setUnescapeCDATA(MBool unescape) { + unescapeCDATA = unescape; +} //-- setUnescapeCDATA + + +void XMLPrinter::setUseEmptyElementShorthand(MBool useShorthand) { + useEmptyElementShorthand = useShorthand; +} //-- setUseEmptyElementShorthand + +/** + * Sets whether or not this XMLPrinter should add whitespace + * to pretty print the XML tree + * @param useFormat a boolean to indicate whether to allow the + * XMLPrinter to add whitespace to the XML tree. (false by default) +**/ +void XMLPrinter::setUseFormat(MBool useFormat) { + this->useFormat = useFormat; +} //-- setUseFormat + + //---------------------/ + //- Protected Methods -/ +//---------------------/ + +/** + * prints the given node to this XMLPrinter's Writer. If the + * useFormat flag has been set, the node will be printed with + * indentation equal to currentIndent + indentSize + * @param node the Node to print + * @param currentIndent the current indent String + * @return true, if and only if a new line was printed at + * the end of printing the given node +**/ +MBool XMLPrinter::print(Node* node, String& currentIndent) { + + ostream& out = *this->ostreamPtr; + + //-- if (node == null) return false; + + NodeList* nl; + + switch(node->getNodeType()) { + + //-- print Document Node + case Node::DOCUMENT_NODE: + { + Document* doc = (Document*)node; + out << PI_START << XML_DECL << DOUBLE_QUOTE; + out << version; + out << DOUBLE_QUOTE << PI_END << endl; + //-- printDoctype(doc.getDoctype()); + nl = doc->getChildNodes(); + for (int i = 0; i < nl->getLength(); i++) { + print(nl->item(i),currentIndent); + } + break; + } + //-- print Attribute Node + case Node::ATTRIBUTE_NODE: + { + Attr* attr = (Attr*)node; + //out << attr->getName(); + out << attr->getNodeName(); + const DOMString& data = attr->getNodeValue(); + if (&data != &NULL_STRING) { + out << EQUALS << DOUBLE_QUOTE; + out << data; + out << DOUBLE_QUOTE; + } + break; + } + //-- print Element + case Node::ELEMENT_NODE: + { + Element* element = (Element*)node; + out << L_ANGLE_BRACKET; + out << element->getNodeName(); + + NamedNodeMap* attList = element->getAttributes(); + if (attList) { + //-- print attribute nodes + Attr* att; + for (int i = 0; i < attList->getLength(); i++) { + att = (Attr*)attList->item(i); + //const DOMString& data = att->getValue(); + const DOMString& data = att->getNodeValue(); //-- remove + //out << SPACE << * (att->getName()); + out << SPACE << att->getNodeName(); + if (&data != &NULL_STRING) { + out << EQUALS << DOUBLE_QUOTE; + out << data; + out << DOUBLE_QUOTE; + } + } + } + + NodeList* childList = element->getChildNodes(); + int size = childList->getLength(); + if ((size == 0) && (useEmptyElementShorthand)) + { + out << FORWARD_SLASH << R_ANGLE_BRACKET; + if (useFormat) { + out << endl; + return MB_TRUE; + } + } + else { + // Either children, or no shorthand + MBool newLine = MB_FALSE; + out << R_ANGLE_BRACKET; + if ((useFormat) && (size > 0)) { + // Fix formatting of PCDATA elements by Peter Marks and + // David King Lassman + // -- add if statement to check for text node before + // adding line break + if (childList->item(0)->getNodeType() != Node::TEXT_NODE) { + out << endl; + newLine = MB_TRUE; + } + } + + Node* child = 0; + String newIndent(indent); + newIndent.append(currentIndent); + for (int i = 0; i < size; i++) { + child = childList->item(i); + if ((useFormat) && newLine) + { + out << newIndent; + } + newLine = print(child,newIndent); + } + if (useFormat) { + // Fix formatting of PCDATA elements by Peter Marks and + // David King Lassman + // -- add if statement to check for text node before + // adding line break + if (child) { + if (child->getNodeType() != Node::TEXT_NODE) { + out << currentIndent; + } + } + } + out << L_ANGLE_BRACKET << FORWARD_SLASH; + out << element->getNodeName(); + out << R_ANGLE_BRACKET; + if (useFormat) { + Node* sibling = node->getNextSibling(); + if ((!sibling) || + (sibling->getNodeType() != Node::TEXT_NODE)) + { + out<getData(); + printWithXMLEntities(data); + break; + } + case Node::CDATA_SECTION_NODE: + if (unescapeCDATA) + printWithXMLEntities( ((Text*)node)->getData() ); + else { + const DOMString& data = ((Text*)node)->getData(); + out << CDATA_START; + printUTF8Chars(data); + out << CDATA_END; + } + break; + case Node::COMMENT_NODE: + out << COMMENT_START; + printComment(((CharacterData*)node)->getData()); + out << COMMENT_END; + if (useFormat) { + out <getNodeName() << SEMICOLON; + break; + case Node::PROCESSING_INSTRUCTION_NODE: + { + ProcessingInstruction* pi = (ProcessingInstruction*)node; + out << PI_START; + out << pi->getTarget(); + out << SPACE; + out << pi->getData(); + out << PI_END; + if (useFormat) { + out <ostreamPtr; + if (ch >= 128) { + out << HEX_ENTITY; + out << ch; + out << SEMICOLON; + } + else out << (char)ch; +} //-- printUTF8Char + +/** + * Print the proper UTF8 characters + * based on code submitted by Majkel Kretschmar +**/ +void XMLPrinter::printUTF8Chars(const DOMString& data) { + int i = 0; + while(i < data.length()) printUTF8Char(data.charAt(i++)); +} //-- printUTF8Chars + + //-------------------/ + //- Private Methods -/ +//-------------------/ + + +void XMLPrinter::printWithXMLEntities(const DOMString& data) { + DOM_CHAR currChar; + + if (&data == &NULL_STRING) return; + + for (int i = 0; i < data.length(); i++) { + currChar = data.charAt(i); + switch (currChar) { + case AMPERSAND: + *ostreamPtr << AMP_ENTITY; + break; + case LT: + *ostreamPtr << LT_ENTITY; + break; + case GT: + *ostreamPtr << GT_ENTITY; + break; + default: + printUTF8Char(currChar); + break; + } + } + *ostreamPtr << flush; +} // -- printWithXMLEntities + +/** + * Replaces any occurances of -- inside comment data with - - + * @param data the comment data (does not include start and end tags) +**/ +void XMLPrinter::printComment(const DOMString& data) { + DOM_CHAR prevChar; + DOM_CHAR currChar; + + if (&data == &NULL_STRING) return; + + prevChar = '\0'; + + for (int i = 0; i < data.length(); i++) { + currChar = data.charAt(i); + + if ((currChar == DASH) && (prevChar == DASH)) + *ostreamPtr << SPACE << DASH; + else + printUTF8Char(currChar); + + prevChar = currChar; + } +} //-- formatComment + + diff --git a/mozilla/extensions/transformiix/source/xsl/Makefile b/mozilla/extensions/transformiix/source/xsl/Makefile new file mode 100644 index 00000000000..208c0b0b807 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/Makefile @@ -0,0 +1,48 @@ +target: xslp + +CC = g++ + +#ifndef PROJ_PATH +ROOT_PATH = .. +XML_PATH = $(ROOT_PATH)/xml +XSL_PATH = $(ROOT_PATH)/xsl +BASE_PATH = $(ROOT_PATH)/base +DOM_PATH = $(XML_PATH)/dom +NET_PATH = $(ROOT_PATH)/net +EXPR_PATH = $(XSL_PATH)/expr +XSLUTIL_PATH = $(XSL_PATH)/util +XMLPRINTER_PATH = $(XML_PATH)/printer +XMLPARSER_PATH = $(XML_PATH)/parser +EXPAT_PARSER_PATH = $(XMLPARSER_PATH)/xmlparse +EXPAT_TOKEN_PATH = $(XMLPARSER_PATH)/xmltok +#endif + +INCLUDE_PATHS = -I $(BASE_PATH) \ + -I $(NET_PATH) \ + -I $(DOM_PATH) \ + -I $(EXPR_PATH) \ + -I $(XSL_PATH) \ + -I $(XSLUTIL_PATH) \ + -I $(XML_PATH) \ + -I $(XMLPARSER_PATH) \ + -I $(XMLPRINTER_PATH) \ + -I $(EXPAT_PARSER_PATH) -I- + +XSL_OBJS = Names.o \ + ProcessorState.o \ + XSLProcessor.o + +###################### +# Build Local Classes +###################### + +xslp: $(XSL_OBJS) + +Names.o: Names.cpp Names.h + $(CC) -I . -I $(BASE_PATH) -c Names.cpp + +ProcessorState.o: ProcessorState.cpp ProcessorState.h + $(CC) $(INCLUDE_PATHS) -c ProcessorState.cpp + +XSLProcessor.o: XSLProcessor.cpp XSLProcessor.h + $(CC) -c XSLProcessor.cpp -D __cplusplus $(INCLUDE_PATHS) diff --git a/mozilla/extensions/transformiix/source/xsl/Names.cpp b/mozilla/extensions/transformiix/source/xsl/Names.cpp new file mode 100644 index 00000000000..bdfd7123e49 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/Names.cpp @@ -0,0 +1,138 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * XSL names used throughout the XSLProcessor. + * Probably should be wrapped in a Namespace + * @author Keith Visco +**/ +#include "Names.h" + +//-- Global Strings +const String HTML = "html"; +const String HTML_NS = "http://www.w3.org/TR/REC-html"; +const String STYLESHEET_PI = "xml-stylesheet"; +const String STYLESHEET_PI_OLD = "xml:stylesheet"; +const String XML_SPACE = "xml:space"; +const String XSL_MIME_TYPE = "text/xsl"; +const String XSLT_NS = "http://www.w3.org/XSL/Transform/"; + +//-- Elements +const String APPLY_IMPORTS = "apply-imports"; +const String APPLY_TEMPLATES = "apply-templates"; +const String ATTRIBUTE = "attribute"; +const String ATTRIBUTE_SET = "attribute-set"; +const String CALL_TEMPLATE = "call-template"; +const String CHOOSE = "choose"; +const String COMMENT = "comment"; +const String COPY = "copy"; +const String COPY_OF = "copy-of"; +const String ELEMENT = "element"; +const String FOR_EACH = "for-each"; +const String IF = "if"; +const String MESSAGE = "message"; +const String NUMBER = "number"; +const String OTHERWISE = "otherwise"; +const String PI = "processing-instruction"; +const String PRESERVE_SPACE = "preserve-space"; +const String STRIP_SPACE = "strip-space"; +const String TEMPLATE = "template"; +const String TEXT = "text"; +const String VALUE_OF = "value-of"; +const String VARIABLE = "variable"; +const String WHEN = "when"; + + +//-- Attributes +const String COUNT_ATTR = "count"; +const String DEFAULT_SPACE_ATTR = "default-space"; +const String ELEMENTS_ATTR = "elements"; +const String EXPR_ATTR = "expr"; +const String FORMAT_ATTR = "format"; +const String MATCH_ATTR = "match"; +const String MODE_ATTR = "mode"; +const String NAME_ATTR = "name"; +const String NAMESPACE_ATTR = "namespace"; +const String PRIORITY_ATTR = "priority"; +const String SELECT_ATTR = "select"; +const String TEST_ATTR = "test"; +const String USE_ATTRIBUTE_SETS_ATTR = "use-attribute-sets"; + +//-- Attribute Values +const String STRIP_VALUE = "strip"; +const String PRESERVE_VALUE = "preserve"; +const String YES_VALUE = "yes"; +const String NO_VALUE = "no"; + +//-- Stylesheet attributes +const String INDENT_RESULT_ATTR = "indent-result"; +const String RESULT_NS_ATTR = "result-ns"; + +const String ANCESTOR_AXIS = "ancestor"; +const String ANCESTOR_OR_SELF_AXIS = "ancestor-or-self"; +const String ATTRIBUTE_AXIS = "attribute"; +const String CHILD_AXIS = "child"; +const String DESCENDANT_AXIS = "descendant"; +const String DESCENDANT_OR_SELF_AXIS = "descendant-or-self"; +const String FOLLOWING_AXIS = "following"; +const String FOLLOWING_SIBLING_AXIS = "following-siblings"; +const String NAMESPACE_AXIS = "namespace"; +const String PARENT_AXIS = "parent"; +const String PRECEDING_AXIS = "preceding"; +const String PRECEDING_SIBLING_AXIS = "preceding-siblings"; +const String SELF_AXIS = "self"; + + +//-- NodeTest Operators +const String ATTRIBUTE_FNAME = "@"; +const String COMMENT_FNAME = "comment"; +const String PI_FNAME = "pi"; +const String TEXT_FNAME = "text"; +const String NODE_FNAME = "node"; +const String IDENTITY_OP = "."; +const String PARENT_OP = ".."; + +//-- Function Names +const String BOOLEAN_FN = "boolean"; +const String CONCAT_FN = "concat"; +const String CONTAINS_FN = "contains"; +const String COUNT_FN = "count"; +const String FALSE_FN = "false"; +const String LAST_FN = "last"; +const String LOCAL_PART_FN = "local-part"; +const String NAME_FN = "name"; +const String NAMESPACE_FN = "namespace"; +const String NOT_FN = "not"; +const String POSITION_FN = "position"; +const String STARTS_WITH_FN = "starts-with"; +const String STRING_FN = "string"; +const String STRING_LENGTH_FN = "string-length"; +const String SUBSTRING_FN = "substring"; +const String SUBSTRING_AFTER_FN = "substring-after"; +const String SUBSTRING_BEFORE_FN = "substring-before"; +const String TRANSLATE_FN = "translate"; +const String TRUE_FN = "true"; + +//-- internal XSL processor functions +const String ERROR_FN = "error"; + +const String WILD_CARD = "*"; + diff --git a/mozilla/extensions/transformiix/source/xsl/Names.h b/mozilla/extensions/transformiix/source/xsl/Names.h new file mode 100644 index 00000000000..7362e0e3a5d --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/Names.h @@ -0,0 +1,137 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "String.h" + +#ifndef MITREXSL_NAMES_H +#define MITREXSL_NAMES_H + +//-- Global Strings +extern const String HTML; +extern const String HTML_NS; +extern const String STYLESHEET_PI; +extern const String STYLESHEET_PI_OLD; +extern const String XML_SPACE; +extern const String XSL_MIME_TYPE; +extern const String XSLT_NS; + +//-- Elements +extern const String APPLY_IMPORTS; +extern const String APPLY_TEMPLATES; +extern const String ATTRIBUTE; +extern const String ATTRIBUTE_SET; +extern const String CALL_TEMPLATE; +extern const String CHOOSE; +extern const String COMMENT; +extern const String COPY; +extern const String COPY_OF; +extern const String ELEMENT; +extern const String FOR_EACH; +extern const String IF; +extern const String MESSAGE; +extern const String NUMBER; +extern const String OTHERWISE; +extern const String PI; +extern const String PRESERVE_SPACE; +extern const String STRIP_SPACE; +extern const String TEMPLATE; +extern const String TEXT; +extern const String VALUE_OF; +extern const String VARIABLE; +extern const String WHEN; + + +//-- Attributes +extern const String COUNT_ATTR; +extern const String DEFAULT_SPACE_ATTR; +extern const String ELEMENTS_ATTR; +extern const String EXPR_ATTR; +extern const String FORMAT_ATTR; +extern const String MATCH_ATTR; +extern const String MODE_ATTR; +extern const String NAME_ATTR; +extern const String NAMESPACE_ATTR; +extern const String PRIORITY_ATTR; +extern const String SELECT_ATTR; +extern const String TEST_ATTR; +extern const String USE_ATTRIBUTE_SETS_ATTR; + +//-- Attribute Values +extern const String STRIP_VALUE; +extern const String PRESERVE_VALUE; +extern const String YES_VALUE; +extern const String NO_VALUE; + +//-- Stylesheet attributes +extern const String INDENT_RESULT_ATTR; +extern const String RESULT_NS_ATTR; + +extern const String ANCESTOR_AXIS; +extern const String ANCESTOR_OR_SELF_AXIS; +extern const String ATTRIBUTE_AXIS; +extern const String CHILD_AXIS; +extern const String DESCENDANT_AXIS; +extern const String DESCENDANT_OR_SELF_AXIS; +extern const String FOLLOWING_AXIS; +extern const String FOLLOWING_SIBLING_AXIS; +extern const String NAMESPACE_AXIS; +extern const String PARENT_AXIS; +extern const String PRECEDING_AXIS; +extern const String PRECEDING_SIBLING_AXIS; +extern const String SELF_AXIS; + + +//-- NodeTest Operators +extern const String ATTRIBUTE_FNAME; +extern const String COMMENT_FNAME; +extern const String PI_FNAME; +extern const String TEXT_FNAME; +extern const String NODE_FNAME; +extern const String IDENTITY_OP; +extern const String PARENT_OP; + +//-- Function Names +extern const String BOOLEAN_FN; +extern const String CONCAT_FN; +extern const String CONTAINS_FN; +extern const String COUNT_FN ; +extern const String FALSE_FN; +extern const String LAST_FN; +extern const String LOCAL_PART_FN; +extern const String NAME_FN; +extern const String NAMESPACE_FN; +extern const String NOT_FN; +extern const String POSITION_FN; +extern const String STARTS_WITH_FN; +extern const String STRING_FN; +extern const String STRING_LENGTH_FN; +extern const String SUBSTRING_FN; +extern const String SUBSTRING_AFTER_FN; +extern const String SUBSTRING_BEFORE_FN; +extern const String TRANSLATE_FN; +extern const String TRUE_FN; + +//-- internal XSL processor functions +extern const String ERROR_FN; + +extern const String WILD_CARD; + +#endif diff --git a/mozilla/extensions/transformiix/source/xsl/ProcessorState.cpp b/mozilla/extensions/transformiix/source/xsl/ProcessorState.cpp new file mode 100644 index 00000000000..f9fc67a3add --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/ProcessorState.cpp @@ -0,0 +1,579 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * Implementation of ProcessorState + * This code was ported from XSL:P + * @author Keith Visco +**/ + +#include "ProcessorState.h" + + //-------------/ + //- Constants -/ +//-------------/ +const String ProcessorState::wrapperNSPrefix = "transformiix"; +const String ProcessorState::wrapperName = "transformiix:result"; +const String ProcessorState::wrapperNS = "http://www.mitre.org/TransforMiix"; + +/** + * Creates a new ProcessorState for the given XSL document + * and resultDocument +**/ +ProcessorState::ProcessorState(Document& xslDocument, Document& resultDocument) { + this->xslDocument = &xslDocument; + this->resultDocument = &resultDocument; + initialize(); +} //-- ProcessorState + +/** + * Destroys this ProcessorState +**/ +ProcessorState::~ProcessorState() { + delete dfWildCardTemplate; + delete dfTextTemplate; + delete nodeStack; + while ( ! variableSets.empty() ) { + delete (NamedMap*) variableSets.pop(); + } +} //-- ~ProcessorState + + +/** + * Adds the given attribute set to the list of available named attribute sets + * @param attributeSet the Element to add as a named attribute set +**/ +void ProcessorState::addAttributeSet(Element* attributeSet) { + if ( !attributeSet ) return; + String name = attributeSet->getAttribute(NAME_ATTR); + if ( name.length() == 0 ) { + cout << "missing required name attribute for xsl:" << ATTRIBUTE_SET <getChildNodes(); + for ( int i = 0; i < nl->getLength(); i++) { + Node* node = nl->item(i); + if ( node->getNodeType() == Node::ELEMENT_NODE) { + String nodeName = node->getNodeName(); + String ns; + XMLUtils::getNameSpace(nodeName, ns); + if ( !xsltNameSpace.isEqual(ns)) continue; + String localPart; + XMLUtils::getLocalPart(nodeName, localPart); + if ( ATTRIBUTE.isEqual(localPart) ) attSet->add(node); + } + } + +} //-- addAttributeSet + +/** + * Registers the given ErrorObserver with this ProcessorState +**/ +void ProcessorState::addErrorObserver(ErrorObserver& errorObserver) { + errorObservers.add(&errorObserver); +} //-- addErrorObserver + +/** + * Adds the given template to the list of templates to process + * @param xslTemplate, the Element to add as a template +**/ +void ProcessorState::addTemplate(Element* xslTemplate) { + if ( !xslTemplate ) return; + const String match = xslTemplate->getAttribute(MATCH_ATTR); + String name = xslTemplate->getAttribute(NAME_ATTR); + if ( name.length() > 0 ) { + //-- check for duplicates + MITREObjectWrapper* mObj = (MITREObjectWrapper*)namedTemplates.get(name); + if ( mObj ) { + String warn("error duplicate template name: "); + warn.append(name); + warn.append("\n -- using template closest to end of document"); + recieveError(warn,ErrorObserver::WARNING); + delete mObj; + } + MITREObjectWrapper* oldObj = mObj; + mObj= new MITREObjectWrapper(); + mObj->object = xslTemplate; + namedTemplates.put(name,mObj); + if ( oldObj ) delete oldObj; + } + patternExprHash.put(match, exprParser.createPatternExpr(match)); + templates.add(xslTemplate); +} //-- addTempalte + +/** + * Adds the given node to the result tree + * @param node the Node to add to the result tree +**/ +MBool ProcessorState::addToResultTree(Node* node) { + + Node* current = nodeStack->peek(); + + switch (node->getNodeType()) { + + case Node::ATTRIBUTE_NODE: + { + if (current->getNodeType() != Node::ELEMENT_NODE) return MB_FALSE; + Element* element = (Element*)current; + Attr* attr = (Attr*)node; + element->setAttribute(attr->getName(),attr->getValue()); + delete node; + break; + } + case Node::ELEMENT_NODE: + //-- if current node is the document, make sure + //-- we don't already have a document element. + //-- if we do, create a wrapper element + if ( current == resultDocument ) { + Element* docElement = resultDocument->getDocumentElement(); + if ( docElement ) { + String nodeName(wrapperName); + Element* wrapper = resultDocument->createElement(nodeName); + nodeStack->push(wrapper); + current->appendChild(wrapper); + current = wrapper; + } + } + current->appendChild(node); + break; + case Node::TEXT_NODE : + //-- if current node is the document, create wrapper element + if ( current == resultDocument ) { + String nodeName(wrapperName); + Element* wrapper = resultDocument->createElement(nodeName); + nodeStack->push(wrapper); + current->appendChild(wrapper); + current = wrapper; + } + current->appendChild(node); + break; + case Node::PROCESSING_INSTRUCTION_NODE: + case Node::COMMENT_NODE : + current->appendChild(node); + break; + //-- only add if not adding to document Node + default: + if (current != resultDocument) current->appendChild(node); + else return MB_FALSE; + break; + } + return MB_TRUE; + +} //-- addToResultTree + +/** + * Copies the node using the rules defined in the XSL specification +**/ +Node* copyNode(Node* node) { + return 0; +} //-- copyNode + +/** + * Finds a template for the given Node. Only templates with + * a mode attribute equal to the given mode will be searched. +**/ +Element* ProcessorState::findTemplate(Node* node, Node* context) { + return findTemplate(node, context, 0); +} //-- findTemplate + +/** + * Finds a template for the given Node. Only templates with + * a mode attribute equal to the given mode will be searched. +**/ +Element* ProcessorState::findTemplate(Node* node, Node* context, String* mode) { + + if (!node) return 0; + Element* matchTemplate = 0; + double currentPriority = 0.5; + + for (int i = 0; i < templates.size(); i++) { + + //cout << "looking at template: " << i << endl; + Element* xslTemplate = (Element*) templates.get(i); + + //-- check mode attribute + Attr* modeAttr = xslTemplate->getAttributeNode(MODE_ATTR); + if (( mode ) && (!modeAttr)) continue; + else if (( !mode ) && (modeAttr)) continue; + else if ( mode ) { + if ( ! mode->isEqual( modeAttr->getValue() ) ) continue; + } + //-- get templates match expr + String match = xslTemplate->getAttribute(MATCH_ATTR); + //cout << "match attr: " << match << endl; + + //-- get Expr from expression hash table + PatternExpr* pExpr = getPatternExpr(match); + if ( !pExpr ) continue; + + if (pExpr->matches(node, context, this)) { + String priorityAttr = xslTemplate->getAttribute(PRIORITY_ATTR); + double tmpPriority = 0; + if ( priorityAttr.length() > 0 ) { + Double dbl(priorityAttr); + tmpPriority = dbl.doubleValue(); + } + else tmpPriority = pExpr->getDefaultPriority(node,context,this); + + if (( !matchTemplate ) || ( tmpPriority >= currentPriority )) + matchTemplate = xslTemplate; + currentPriority = tmpPriority; + } + } + //cout << "findTemplate:end"<object; + } + return 0; +} //-- getNamedTemplate + + +NodeStack* ProcessorState::getNodeStack() { + return nodeStack; +} //-- getNodeStack + +PatternExpr* ProcessorState::getPatternExpr(const String& pattern) { + PatternExpr* pExpr = (PatternExpr*)patternExprHash.get(pattern); + if ( !pExpr ) { + pExpr = exprParser.createPatternExpr(pattern); + patternExprHash.put(pattern, pExpr); + } + return pExpr; +} //-- getPatternExpr + +Document* ProcessorState::getResultDocument() { + return resultDocument; +} //-- getResultDocument + +NodeSet* ProcessorState::getTemplates() { + return &templates; +} //-- getTemplates + + +Stack* ProcessorState::getVariableSetStack() { + return &variableSets; +} //-- getVariableSetStack + +String& ProcessorState::getXSLNamespace() { + return xsltNameSpace; +} //-- getXSLNamespace + +/** + * Determines if the given XSL node allows Whitespace stripping +**/ +MBool ProcessorState::isXSLStripSpaceAllowed(Node* node) { + + if ( !node ) return MB_FALSE; + return (MBool)(PRESERVE != getXMLSpaceMode(node)); + +} //--isXSLStripSpaceAllowed + +/** + * Adds the set of names to the Whitespace preserving element set +**/ +void ProcessorState::preserveSpace(String& names) { + + //-- split names on whitespace + Tokenizer tokenizer(names); + String name; + while ( tokenizer.hasMoreTokens() ) { + tokenizer.nextToken(name); + wsPreserve.add(new String(name)); + wsStrip.remove(name); + } + +} //-- preserveSpace + +/** + * Adds the set of names to the Whitespace stripping element set +**/ +void ProcessorState::stripSpace(String& names) { + //-- split names on whitespace + Tokenizer tokenizer(names); + String name; + while ( tokenizer.hasMoreTokens() ) { + tokenizer.nextToken(name); + wsStrip.add(new String(name)); + wsPreserve.remove(name); + } + +} //-- stripSpace + + //--------------------------------------------------/ + //- Virtual Methods from derived from ContextState -/ +//--------------------------------------------------/ + +/** + * Returns the Stack of context NodeSets + * @return the Stack of context NodeSets +**/ +Stack* ProcessorState::getNodeSetStack() { + return &nodeSetStack; +} //-- getNodeSetStack + +/** + * Returns the value of a given variable binding within the current scope + * @param the name to which the desired variable value has been bound + * @return the ExprResult which has been bound to the variable with the given + * name +**/ +ExprResult* ProcessorState::getVariable(String& name) { + + StackIterator* iter = variableSets.iterator(); + ExprResult* exprResult = 0; + while ( iter->hasNext() ) { + NamedMap* map = (NamedMap*) iter->next(); + if ( map->get(name)) { + exprResult = (ExprResult*)map->get(name); + break; + } + } + delete iter; + return exprResult; +} //-- getVariable + +/** + * Determines if the given XML node allows Whitespace stripping +**/ +MBool ProcessorState::isStripSpaceAllowed(Node* node) { + + if ( !node ) return MB_FALSE; + + switch ( node->getNodeType() ) { + + case Node::ELEMENT_NODE : + { + //-- check Whitespace element names against given Node + String name = node->getNodeName(); + if (wsPreserve.contains(name)) return MB_FALSE; + if (wsStrip.contains(name)) return MB_TRUE; + break; + } + case Node::TEXT_NODE: + return isStripSpaceAllowed(node->getParentNode()); + default: + break; + } + XMLSpaceMode mode = getXMLSpaceMode(node); + if (mode == DEFAULT) return (MBool)(defaultSpace == STRIP); + return (MBool)(STRIP == mode); + +} //--isStripSpaceAllowed + +/** + * Notifies this Error observer of a new error, with default + * level of NORMAL +**/ +void ProcessorState::recieveError(String& errorMessage) { + recieveError(errorMessage, ErrorObserver::NORMAL); +} //-- recieveError + +/** + * Notifies this Error observer of a new error using the given error level +**/ +void ProcessorState::recieveError(String& errorMessage, ErrorLevel level) { + ListIterator* iter = errorObservers.iterator(); + while ( iter->hasNext()) { + ErrorObserver* observer = (ErrorObserver*)iter->next(); + observer->recieveError(errorMessage, level); + } + delete iter; +} //-- recieveError + + //-------------------/ + //- Private Methods -/ +//-------------------/ + +/** + * Returns the closest xml:space value for the given Text node +**/ +ProcessorState::XMLSpaceMode ProcessorState::getXMLSpaceMode(Node* node) { + + if (!node) return DEFAULT; //-- we should never see this + + Node* parent = node; + while ( parent ) { + switch ( parent->getNodeType() ) { + case Node::ELEMENT_NODE: + { + String value = ((Element*)parent)->getAttribute(XML_SPACE); + if ( value.isEqual(PRESERVE_VALUE)) { + return PRESERVE; + } + break; + } + case Node::TEXT_NODE: + //-- we will only see this the first time through the loop + //-- if the argument node is a text node + break; + default: + return DEFAULT; + } + parent = parent->getParentNode(); + } + return DEFAULT; + +} //-- getXMLSpaceMode + +/** + * Initializes this ProcessorState +**/ +void ProcessorState::initialize() { + + //-- initialize default-space + defaultSpace = PRESERVE; + + //-- add global variable set + NamedMap* globalVars = new NamedMap(); + globalVars->setObjectDeletion(MB_TRUE); + variableSets.push(globalVars); + + /* turn object deletion on for some of the Maps (NamedMap) */ + exprHash.setObjectDeletion(MB_TRUE); + patternExprHash.setObjectDeletion(MB_TRUE); + nameSpaceMap.setObjectDeletion(MB_TRUE); + namedAttributeSets.setObjectDeletion(MB_TRUE); + + //-- named templates uses deletion, to remove the ObjectWrappers + namedTemplates.setObjectDeletion(MB_TRUE); + //-- do not set ObjectDeletion for templates, since the Document + //-- handles the cleanup + + //-- create NodeStack + nodeStack = new NodeStack(); + nodeStack->push(this->resultDocument); + + //-- determine xsl properties + Element* element = xslDocument->getDocumentElement(); + if ( element ) { + //-- process namespace nodes + NamedNodeMap* atts = element->getAttributes(); + if ( atts ) { + for (int i = 0; i < atts->getLength(); i++) { + Attr* attr = (Attr*)atts->item(i); + String attName = attr->getName(); + String attValue = attr->getValue(); + if ( attName.indexOf(XMLUtils::XMLNS) == 0) { + String ns; + XMLUtils::getLocalPart(attName, ns); + //-- default namespace + if ( attName.isEqual(XMLUtils::XMLNS) ) { + //-- handle default + //-- do nothing for now + } + // namespace declaration + else { + String ns; + XMLUtils::getNameSpace(attName, ns); + nameSpaceMap.put(ns, new String(attValue)); + } + // check for XSL namespace + if ( attValue.indexOf(XSLT_NS) == 0) { + xsltNameSpace = ns; + } + } + else if ( attName.isEqual(DEFAULT_SPACE_ATTR) ) { + if ( attValue.isEqual(STRIP_VALUE) ) { + defaultSpace = STRIP; + } + } + } //-- end for each att + } //-- end if atts are not null + } //-- end if document element exists + + /* Create default (built-in) templates */ + + //-- create default template for elements + + + String templateName = xsltNameSpace; + if (templateName.length() > 0) templateName.append(':'); + templateName.append(TEMPLATE); + + String actionName = xsltNameSpace; + if ( actionName.length()>0) actionName.append(':'); + actionName.append(APPLY_TEMPLATES); + + dfWildCardTemplate = xslDocument->createElement(templateName); + dfWildCardTemplate->setAttribute(MATCH_ATTR, "* | /"); + dfWildCardTemplate->appendChild(xslDocument->createElement(actionName)); + templates.add(dfWildCardTemplate); + + //-- create default "built-in" templates for text nodes + dfTextTemplate = xslDocument->createElement(templateName); + dfTextTemplate->setAttribute(MATCH_ATTR, "text()|@*"); + actionName = xsltNameSpace; + if ( actionName.length()>0) actionName.append(':'); + actionName.append(VALUE_OF); + Element* value_of = xslDocument->createElement(actionName); + value_of->setAttribute(SELECT_ATTR, IDENTITY_OP); + dfTextTemplate->appendChild(value_of); + templates.add(dfTextTemplate); + + //-- add PatternExpr hash for default templates + patternExprHash.put("*", new WildCardExpr()); + patternExprHash.put("/", new RootExpr()); + patternExprHash.put("text()", new TextExpr()); + + //cout << "XSLT namespace: " << xsltNameSpace << endl; +} //-- initialize + + diff --git a/mozilla/extensions/transformiix/source/xsl/ProcessorState.h b/mozilla/extensions/transformiix/source/xsl/ProcessorState.h new file mode 100644 index 00000000000..f88b0463982 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/ProcessorState.h @@ -0,0 +1,259 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + + + +#ifndef MITREXSL_PROCESSORSTATE_H +#define MITREXSL_PROCESSORSTATE_H + +#include "dom.h" +#include "XMLUtils.h" +#include "Names.h" +#include "NodeSet.h" +#include "NodeStack.h" +#include "Stack.h" +#include "ErrorObserver.h" +#include "List.h" +#include "NamedMap.h" +#include "ExprParser.h" +#include "Expr.h" +#include "StringList.h" +#include "Tokenizer.h" + +/** + * Class used for keeping the current state of the XSL Processor + * @author Keith Visco +**/ +class ProcessorState : public ContextState +{ + +public: + + static const String wrapperNSPrefix; + static const String wrapperName; + static const String wrapperNS; + + /** + * Creates a new ProcessorState for the given XSL document + * And result Document + **/ + ProcessorState(Document& xslDocument, Document& resultDocument); + + /** + * Destroys this ProcessorState + **/ + ~ProcessorState(); + + /** + * Adds the given attribute set to the list of available named attribute sets + * @param attributeSet the Element to add as a named attribute set + **/ + void addAttributeSet(Element* attributeSet); + + /** + * Registers the given ErrorObserver with this ProcessorState + **/ + void addErrorObserver(ErrorObserver& errorObserver); + + /** + * Adds the given template to the list of templates to process + * @param xslTemplate, the Element to add as a template + **/ + void addTemplate(Element* xslTemplate); + + /** + * Adds the given Node to the Result Tree + * + **/ + MBool addToResultTree(Node* node); + + /** + * Copies the node using the rules defined in the XSL specification + **/ + Node* copyNode(Node* node); + + /** + * Returns the AttributeSet associated with the given name + * or null if no AttributeSet is found + **/ + NodeSet* getAttributeSet(const String& name); + + + /** + * Returns the template associated with the given name, or + * null if not template is found + **/ + Element* getNamedTemplate(String& name); + + NodeStack* getNodeStack(); + Stack* getVariableSetStack(); + + Expr* getExpr(const String& pattern); + PatternExpr* getPatternExpr(const String& pattern); + + /** + * Returns a pointer to the result document + **/ + Document* getResultDocument(); + + /** + * Returns a pointer to a list of available templates + **/ + NodeSet* getTemplates(); + + String& getXSLNamespace(); + + /** + * Finds a template for the given Node. Only templates without + * a mode attribute will be searched. + **/ + Element* findTemplate(Node* node, Node* context); + + /** + * Finds a template for the given Node. Only templates with + * a mode attribute equal to the given mode will be searched. + **/ + Element* findTemplate(Node* node, Node* context, String* mode); + + /** + * Determines if the given XSL node allows Whitespace stripping + **/ + MBool isXSLStripSpaceAllowed(Node* node); + + /** + * Adds the set of names to the Whitespace preserving element set + **/ + void preserveSpace(String& names); + + /** + * Adds the set of names to the Whitespace stripping element set + **/ + void stripSpace(String& names); + + + //-------------------------------------/ + //- Virtual Methods from ContextState -/ + //-------------------------------------/ + + /** + * Returns the value of a given variable binding within the current scope + * @param the name to which the desired variable value has been bound + * @return the ExprResult which has been bound to the variable with the given + * name + **/ + virtual ExprResult* getVariable(String& name); + + /** + * Returns the Stack of context NodeSets + * @return the Stack of context NodeSets + **/ + virtual Stack* getNodeSetStack(); + + /** + * Determines if the given XML node allows Whitespace stripping + **/ + virtual MBool isStripSpaceAllowed(Node* node); + + /** + * Notifies this Error observer of a new error, with default + * level of NORMAL + **/ + virtual void recieveError(String& errorMessage); + + /** + * Notifies this Error observer of a new error using the given error level + **/ + virtual void recieveError(String& errorMessage, ErrorLevel level); + +private: + + enum XMLSpaceMode {STRIP = 0, DEFAULT, PRESERVE}; + + /** + * The list of ErrorObservers registered with this ProcessorState + **/ + List errorObservers; + + /** + * A map for named attribute sets + **/ + NamedMap namedAttributeSets; + + /** + * A map for named templates + **/ + NamedMap namedTemplates; + + /** + * Current stack of nodes, where we are in the result document tree + **/ + NodeStack* nodeStack; + + /** + * The set of whitespace preserving elements + **/ + StringList wsPreserve; + + /** + * The set of whitespace stripping elements + **/ + StringList wsStrip; + + /** + * The set of whitespace stripping elements + **/ + XMLSpaceMode defaultSpace; + + /** + * A set of all availabe templates + **/ + NodeSet templates; + + + Stack nodeSetStack; + Document* xslDocument; + Document* resultDocument; + NamedMap exprHash; + NamedMap patternExprHash; + Stack variableSets; + ExprParser exprParser; + String xsltNameSpace; + NamedMap nameSpaceMap; + + //-- default templates + Element* dfWildCardTemplate; + Element* dfTextTemplate; + + /** + * Returns the closest xml:space value for the given node + **/ + XMLSpaceMode getXMLSpaceMode(Node* node); + + /** + * Initializes the ProcessorState + **/ + void initialize(); + +}; //-- ProcessorState + + +#endif + diff --git a/mozilla/extensions/transformiix/source/xsl/XSLProcessor.cpp b/mozilla/extensions/transformiix/source/xsl/XSLProcessor.cpp new file mode 100644 index 00000000000..5318fc4a51b --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/XSLProcessor.cpp @@ -0,0 +1,1269 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "XSLProcessor.h" + + + //----------------------------------/ + //- Implementation of XSLProcessor -/ +//----------------------------------/ + +/** + * XSLProcessor is a class for Processing XSL styelsheets + * @author Keith Visco (kvisco@mitre.org) +**/ + +/** + * A warning message used by all templates that do not allow non character + * data to be generated +**/ +const String XSLProcessor::NON_TEXT_TEMPLATE_WARNING = +"templates for the following element are not allowed to generate non character data: "; + +/** + * Creates a new XSLProcessor +**/ +XSLProcessor::XSLProcessor() { + +#ifdef MOZILLA + NS_INIT_ISUPPORTS(); +#endif + + xslVersion.append("1.0"); + appName.append("TransforMiiX"); + appVersion.append("1.0 [beta v19990813]"); + + //-- create XSL element types + xslTypes.setObjectDeletion(MB_TRUE); + xslTypes.put(APPLY_TEMPLATES, new XSLType(XSLType::APPLY_TEMPLATES)); + xslTypes.put(ATTRIBUTE, new XSLType(XSLType::ATTRIBUTE)); + xslTypes.put(ATTRIBUTE_SET, new XSLType(XSLType::ATTRIBUTE_SET)); + xslTypes.put(CALL_TEMPLATE, new XSLType(XSLType::CALL_TEMPLATE)); + xslTypes.put(CHOOSE, new XSLType(XSLType::CHOOSE)); + xslTypes.put(COMMENT, new XSLType(XSLType::COMMENT)); + xslTypes.put(COPY, new XSLType(XSLType::COPY)); + xslTypes.put(COPY_OF, new XSLType(XSLType::COPY_OF)); + xslTypes.put(ELEMENT, new XSLType(XSLType::ELEMENT)); + xslTypes.put(FOR_EACH, new XSLType(XSLType::FOR_EACH)); + xslTypes.put(IF, new XSLType(XSLType::IF)); + xslTypes.put(MESSAGE, new XSLType(XSLType::MESSAGE)); + xslTypes.put(NUMBER, new XSLType(XSLType::NUMBER)); + xslTypes.put(OTHERWISE, new XSLType(XSLType::OTHERWISE)); + xslTypes.put(PI, new XSLType(XSLType::PI)); + xslTypes.put(PRESERVE_SPACE, new XSLType(XSLType::PRESERVE_SPACE)); + xslTypes.put(STRIP_SPACE, new XSLType(XSLType::STRIP_SPACE)); + xslTypes.put(TEMPLATE, new XSLType(XSLType::TEMPLATE)); + xslTypes.put(TEXT, new XSLType(XSLType::TEXT)); + xslTypes.put(VALUE_OF, new XSLType(XSLType::VALUE_OF)); + xslTypes.put(VARIABLE, new XSLType(XSLType::VARIABLE)); + xslTypes.put(WHEN, new XSLType(XSLType::WHEN)); + + //-- proprietary debug elements + xslTypes.put("expr-debug", new XSLType(XSLType::EXPR_DEBUG)); +} //-- XSLProcessor + +/** + * Default destructor +**/ +XSLProcessor::~XSLProcessor() { + //-- currently does nothing, but added for future use +} //-- ~XSLProcessor + +#ifdef MOZILLA +// Provide a Create method that can be called by a factory constructor: +NS_METHOD +XSLProcessor::Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult) +{ + if (aOuter) + return NS_ERROR_NO_AGGREGATION; + + XSLProcessor* xslp = new XSLProcessor(); + if (xslp == NULL) + return NS_ERROR_OUT_OF_MEMORY; + + // Note that Create doesn't initialize the instance -- that has to + // be done by the caller since the initialization args aren't passed + // in here. + + // AddRef before calling QI -- this makes it easier to handle the QI + // failure case because we'll always just Release and return + NS_ADDREF(xslp); + nsresult rv = xslp->QueryInterface(aIID, aResult); + + // This will free it if QI failed: + NS_RELEASE(xslp); + return rv; +} + +NS_IMPL_ISUPPORTS(XSLProcessor, nsIDocumentTransformer::GetIID()); +#endif + +/** + * Registers the given ErrorObserver with this ProcessorState +**/ +void XSLProcessor::addErrorObserver(ErrorObserver& errorObserver) { + errorObservers.add(&errorObserver); +} //-- addErrorObserver + +#ifndef MOZILLA +XMLPrinter* XSLProcessor::createPrinter(Document& xslDocument, ostream& out) { + + //-- check result-ns of stylesheet element + Element* stylesheet = xslDocument.getDocumentElement(); + XMLPrinter* xmlPrinter = 0; + + ostream* target = 0; + if ( !out ) target = &cout; + else target = &out; + + if ( stylesheet ) { + String result_ns = stylesheet->getAttribute(RESULT_NS_ATTR); + Attr* indentResult = stylesheet->getAttributeNode(INDENT_RESULT_ATTR); + + //-- create appropriate printer + if ( result_ns.indexOf(HTML_NS) == 0) { + xmlPrinter = new HTMLPrinter(*target); + } + else xmlPrinter = new XMLPrinter(*target); + + //-- set use formatting + if ( indentResult ) { + MBool useFormat = (MBool) YES_VALUE.isEqual(indentResult->getValue()); + xmlPrinter->setUseFormat(useFormat); + } + + } + else xmlPrinter = new XMLPrinter(*target); + return xmlPrinter; +} //-- createPrinter +#endif + +String& XSLProcessor::getAppName() { + return appName; +} //-- getAppName + +String& XSLProcessor::getAppVersion() { + return appVersion; +} //-- getAppVersion + + +#ifndef MOZILLA +/** + * Parses all XML Stylesheet PIs associated with the + * given XML document. If any stylesheet PIs are found with + * type="text/xsl" the href psuedo attribute value will be + * added to the given href argument. If multiple text/xsl stylesheet PIs + * are found, the one closest to the end of the document is used. +**/ +void XSLProcessor::getHrefFromStylesheetPI(Document& xmlDocument, String& href) { + + NodeList* nl = xmlDocument.getChildNodes(); + String type; + String tmpHref; + for ( int i = 0; i < nl->getLength(); i++ ) { + Node* node = nl->item(i); + if ( node->getNodeType() == Node::PROCESSING_INSTRUCTION_NODE ) { + String target = ((ProcessingInstruction*)node)->getTarget(); + if ( STYLESHEET_PI.isEqual(target) || + STYLESHEET_PI_OLD.isEqual(target) ) { + String data = ((ProcessingInstruction*)node)->getData(); + type.clear(); + tmpHref.clear(); + parseStylesheetPI(data, type, tmpHref); + if ( XSL_MIME_TYPE.isEqual(type) ) { + href.clear(); + href.append(tmpHref); + } + } + } + } + +} //-- getHrefFromStylesheetPI + +/** + * Parses the contents of data, and returns the type and href psuedo attributes +**/ +void XSLProcessor::parseStylesheetPI(String& data, String& type, String& href) { + + Int32 size = data.length(); + NamedMap bufferMap; + bufferMap.put("type", &type); + bufferMap.put("href", &href); + int ccount = 0; + MBool inLiteral = MB_FALSE; + char matchQuote = '"'; + String sink; + String* buffer = &sink; + + for (ccount = 0; ccount < size; ccount++) { + char ch = data.charAt(ccount); + switch ( ch ) { + case ' ' : + if ( inLiteral ) { + buffer->append(ch); + } + break; + case '=': + if ( inLiteral ) buffer->append(ch); + else if ( buffer->length() > 0 ) { + buffer = (String*)bufferMap.get(*buffer); + if ( !buffer ) { + sink.clear(); + buffer = &sink; + } + } + break; + case '"' : + case '\'': + if (inLiteral) { + if ( matchQuote == ch ) { + inLiteral = MB_FALSE; + sink.clear(); + buffer = &sink; + } + else buffer->append(ch); + } + else { + inLiteral = MB_TRUE; + matchQuote = ch; + } + break; + default: + buffer->append(ch); + break; + } + } + +} //-- parseStylesheetPI + +/** + * Processes the given XML Document, the XSL stylesheet + * will be retrieved from the XML Stylesheet Processing instruction, + * otherwise an empty document will be returned. + * @param xmlDocument the XML document to process + * @param documentBase the document base of the XML document, for + * resolving relative URIs + * @return the result tree. +**/ +Document* XSLProcessor::process(Document& xmlDocument, String& documentBase) { + //-- look for Stylesheet PI + Document xslDocument; //-- empty for now + return process(xmlDocument, xslDocument); +} //-- process + +/** + * Reads an XML Document from the given XML input stream, and + * processes the document using the XSL document derived from + * the given XSL input stream. + * @return the result tree. +**/ +Document* XSLProcessor::process(istream& xmlInput, istream& xslInput) { + //-- read in XML Document + XMLParser xmlParser; + Document* xmlDoc = xmlParser.parse(xmlInput); + if (!xmlDoc) { + String err("error reading XML document: "); + err.append(xmlParser.getErrorString()); + notifyError(err, ErrorObserver::FATAL); + return 0; + } + //-- Read in XSL document + Document* xslDoc = xmlParser.parse(xslInput); + if (!xslDoc) { + String err("error reading XSL stylesheet document: "); + err.append(xmlParser.getErrorString()); + notifyError(err, ErrorObserver::FATAL); + delete xmlDoc; + return 0; + } + Document* result = process(*xmlDoc, *xslDoc); + delete xmlDoc; + delete xslDoc; + return result; +} //-- process + +/** + * Reads an XML document from the given XML input stream. The + * XML document is processed using the associated XSL document + * retrieved from the XML document's Stylesheet Processing Instruction, + * otherwise an empty document will be returned. + * @param xmlDocument the XML document to process + * @param documentBase the document base of the XML document, for + * resolving relative URIs + * @return the result tree. +**/ +Document* XSLProcessor::process(istream& xmlInput, String& documentBase) { + //-- read in XML Document + XMLParser xmlParser; + Document* xmlDoc = xmlParser.parse(xmlInput); + if (!xmlDoc) { + String err("error reading XML document: "); + err.append(xmlParser.getErrorString()); + notifyError(err, ErrorObserver::FATAL); + return 0; + } + //-- Read in XSL document + String href; + String errMsg; + getHrefFromStylesheetPI(*xmlDoc, href); + istream* xslInput = URIUtils::getInputStream(href,documentBase,errMsg); + Document* xslDoc = 0; + if ( xslInput ) { + xslDoc = xmlParser.parse(*xslInput); + delete xslInput; + } + if (!xslDoc) { + String err("error reading XSL stylesheet document: "); + err.append(xmlParser.getErrorString()); + notifyError(err, ErrorObserver::FATAL); + delete xmlDoc; + return 0; + } + Document* result = process(*xmlDoc, *xslDoc); + delete xmlDoc; + delete xslDoc; + return result; +} //-- process +#endif + +/** + * Processes the given XML Document using the given XSL document + * and returns the result tree +**/ +Document* XSLProcessor::process(Document& xmlDocument, Document& xslDocument) { + + Document* result = new Document(); + + //-- create a new ProcessorState + ProcessorState ps(xslDocument, *result); + + //-- add error observers + ListIterator* iter = errorObservers.iterator(); + while ( iter->hasNext()) { + ps.addErrorObserver(*((ErrorObserver*)iter->next())); + } + delete iter; + //-------------------------------------------------------/ + //- index templates and process root level xsl elements -/ + //-------------------------------------------------------/ + Element* stylesheet = xslDocument.getDocumentElement(); + NodeList* nl = stylesheet->getChildNodes(); + for (int i = 0; i < nl->getLength(); i++) { + Node* node = nl->item(i); + if (node->getNodeType() == Node::ELEMENT_NODE) { + Element* element = (Element*)node; + DOMString name = element->getNodeName(); + switch (getElementType(name, &ps)) { + case XSLType::ATTRIBUTE_SET: + ps.addAttributeSet(element); + break; + case XSLType::TEMPLATE : + ps.addTemplate(element); + break; + case XSLType::VARIABLE : + { + String name = element->getAttribute(NAME_ATTR); + if ( name.length() == 0 ) { + notifyError("missing required name attribute for xsl:variable"); + break; + } + ExprResult* exprResult = processVariable(node, element, &ps); + bindVariable(name, exprResult, &ps); + break; + } + case XSLType::PRESERVE_SPACE : + { + String elements = element->getAttribute(ELEMENTS_ATTR); + if ( elements.length() == 0 ) { + //-- add error to ErrorObserver + String err("missing required 'elements' attribute for "); + err.append("xsl:preserve-space"); + notifyError(err); + } + else ps.preserveSpace(elements); + break; + } + case XSLType::STRIP_SPACE : + { + String elements = element->getAttribute(ELEMENTS_ATTR); + if ( elements.length() == 0 ) { + //-- add error to ErrorObserver + String err("missing required 'elements' attribute for "); + err.append("xsl:strip-space"); + notifyError(err); + } + else ps.stripSpace(elements); + break; + } + default: + //-- unknown + break; + } + } + } + //----------------------------------------/ + //- Process root of XML source document -/ + //--------------------------------------/ + process(&xmlDocument, &xmlDocument, &ps); + + //-- return result Document + return result; +} //-- process + +#ifndef MOZILLA +/** + * Processes the given XML Document using the given XSL document + * and prints the results to the given ostream argument +**/ +void XSLProcessor::process(Document& xmlDocument, Document& xslDocument, ostream& out) { + Document* resultDoc = process(xmlDocument, xslDocument); + XMLPrinter* xmlPrinter = createPrinter(xslDocument, out); + xmlPrinter->print(resultDoc); + delete xmlPrinter; + delete resultDoc; +} //-- process + + +/** + * Reads an XML Document from the given XML input stream. + * The XSL Stylesheet is obtained from the XML Documents stylesheet PI. + * If no Stylesheet is found, an empty document will be the result; + * otherwise the XML Document is processed using the stylesheet. + * The result tree is printed to the given ostream argument, + * will not close the ostream argument +**/ +void XSLProcessor::process(istream& xmlInput, String& documentBase, ostream& out) { + + XMLParser xmlParser; + Document* xmlDoc = xmlParser.parse(xmlInput); + if (!xmlDoc) { + String err("error reading XML document: "); + err.append(xmlParser.getErrorString()); + notifyError(err, ErrorObserver::FATAL); + return; + } + //-- Read in XSL document + String href; + String errMsg; + getHrefFromStylesheetPI(*xmlDoc, href); + istream* xslInput = URIUtils::getInputStream(href,documentBase,errMsg); + Document* xslDoc = 0; + if ( xslInput ) { + xslDoc = xmlParser.parse(*xslInput); + delete xslInput; + } + if (!xslDoc) { + String err("error reading XSL stylesheet document: "); + err.append(xmlParser.getErrorString()); + notifyError(err, ErrorObserver::FATAL); + delete xmlDoc; + return; + } + Document* result = process(*xmlDoc, *xslDoc); + XMLPrinter* xmlPrinter = createPrinter(*xslDoc, out); + xmlPrinter->print(result); + delete xmlPrinter; + delete xmlDoc; + delete xslDoc; + delete result; +} //-- process + +/** + * Reads an XML Document from the given XML input stream, and + * processes the document using the XSL document derived from + * the given XSL input stream. + * The result tree is printed to the given ostream argument, + * will not close the ostream argument +**/ +void XSLProcessor::process(istream& xmlInput, istream& xslInput, ostream& out) { + //-- read in XML Document + XMLParser xmlParser; + Document* xmlDoc = xmlParser.parse(xmlInput); + if (!xmlDoc) { + String err("error reading XML document: "); + err.append(xmlParser.getErrorString()); + notifyError(err, ErrorObserver::FATAL); + return; + } + //-- read in XSL Document + Document* xslDoc = xmlParser.parse(xslInput); + if (!xslDoc) { + String err("error reading XSL stylesheet document: "); + err.append(xmlParser.getErrorString()); + notifyError(err, ErrorObserver::FATAL); + delete xmlDoc; + return; + } + Document* result = process(*xmlDoc, *xslDoc); + XMLPrinter* xmlPrinter = createPrinter(*xslDoc, out); + xmlPrinter->print(result); + delete xmlPrinter; + delete xmlDoc; + delete xslDoc; + delete result; +} //-- process +#endif + //-------------------/ + //- Private Methods -/ +//-------------------/ + +/** + * Returns the type of Element represented by the given name + * @return the XSLType represented by the given element name +**/ +short XSLProcessor::getElementType(String& name, ProcessorState* ps) { + + + String namePart; + XMLUtils::getNameSpace(name, namePart); + XSLType* xslType = 0; + + if ( ps->getXSLNamespace().isEqual(namePart) ) { + namePart.clear(); + XMLUtils::getLocalPart(name, namePart); + xslType = (XSLType*) xslTypes.get(namePart); + } + + if ( !xslType ) { + return XSLType::LITERAL; + } + else return xslType->type; + +} //-- getElementType + +void XSLProcessor::bindVariable + (String& name, ExprResult* exprResult, ProcessorState* ps) +{ + NamedMap* varSet = (NamedMap*)ps->getVariableSetStack()->peek(); + //-- check for duplicate variable names + ExprResult* current = (ExprResult*) varSet->get(name); + if ( current ) { + //-- error cannot rebind variables + String err("error cannot rebind variables: "); + err.append(name); + err.append(" already exists in this scope."); + notifyError(err); + } + else { + varSet->put((const String&)name, exprResult); + } + +} //-- bindVariable + +/** + * Gets the Text value of the given DocumentFragment. The value is placed + * into the given destination String. If a non text node element is + * encountered and warningForNonTextNodes is turned on, the MB_FALSE + * will be returned, otherwise true is always returned. + * @param dfrag the document fragment to get the text from + * @param dest the destination string to place the text into. + * @param deep indicates to process non text nodes and recusively append + * their value. If this value is true, the allowOnlyTextNodes flag is ignored. + * @param allowOnlyTextNodes +**/ +MBool XSLProcessor::getText + (DocumentFragment* dfrag, String& dest, MBool deep, MBool allowOnlyTextNodes) +{ + if ( !dfrag ) return MB_TRUE; + + MBool flag = MB_TRUE; + if ( deep ) XMLDOMUtils::getNodeValue(dfrag, &dest); + else { + NodeList* nl = dfrag->getChildNodes(); + for ( int i = 0; i < nl->getLength(); i++ ) { + Node* node = nl->item(i); + switch(node->getNodeType()) { + case Node::CDATA_SECTION_NODE: + case Node::TEXT_NODE : + dest.append( ((CharacterData*)node)->getData() ); + break; + default: + if (allowOnlyTextNodes) flag = MB_FALSE; + break; + } + } + } + return flag; +} //-- getText + +/** + * Notifies all registered ErrorObservers of the given error +**/ +void XSLProcessor::notifyError(const char* errorMessage) { + String err(errorMessage); + notifyError(err, ErrorObserver::NORMAL); +} //-- notifyError + +/** + * Notifies all registered ErrorObservers of the given error +**/ +void XSLProcessor::notifyError(String& errorMessage) { + notifyError(errorMessage, ErrorObserver::NORMAL); +} //-- notifyError + +/** + * Notifies all registered ErrorObservers of the given error +**/ +void XSLProcessor::notifyError(String& errorMessage, ErrorObserver::ErrorLevel level) { + ListIterator* iter = errorObservers.iterator(); + + //-- send fatal errors to default observer if no error obersvers + //-- have been registered + if ((!iter->hasNext()) && (level == ErrorObserver::FATAL)) { + fatalObserver.recieveError(errorMessage, level); + } + while ( iter->hasNext() ) { + ErrorObserver* observer = (ErrorObserver*)iter->next(); + observer->recieveError(errorMessage, level); + } + delete iter; +} //-- notifyError + +void XSLProcessor::process(Node* node, Node* context, ProcessorState* ps) { + process(node, context, 0, ps); +} //-- process + +void XSLProcessor::process(Node* node, Node* context, String* mode, ProcessorState* ps) { + if ( !node ) return; + Element* xslTemplate = ps->findTemplate(node, context, mode); + if (!xslTemplate) return; + processTemplate(node, xslTemplate, ps); +} //-- process + +void XSLProcessor::processAction + (Node* node, Node* xslAction, ProcessorState* ps) +{ + if (!xslAction) return; + Document* resultDoc = ps->getResultDocument(); + + short nodeType = xslAction->getNodeType(); + + //-- handle text nodes + if (nodeType == Node::TEXT_NODE) { + String textValue; + if ( ps->isXSLStripSpaceAllowed(xslAction) ) { + //-- strip whitespace + //-- Note: we might want to save results of whitespace stripping. + //-- I was thinking about removing whitespace while reading in the + //-- XSL document, but this won't handle the case of Dynamic XSL + //-- documents + const String curValue = ((Text*)xslAction)->getData(); + + //-- set leading + trailing whitespace stripping flags + MBool stripLWS = (MBool) (xslAction->getPreviousSibling()); + MBool stripTWS = (MBool) (xslAction->getNextSibling()); + XMLUtils::stripSpace(curValue,textValue, stripLWS, stripTWS); + //-- create new text node and add it to the result tree + //-- if necessary + } + else { + textValue = ((Text*)xslAction)->getData(); + } + if ( textValue.length() > 0) + ps->addToResultTree(resultDoc->createTextNode(textValue)); + return; + } + //-- handle element nodes + else if (nodeType == Node::ELEMENT_NODE) { + + String nodeName = xslAction->getNodeName(); + PatternExpr* pExpr = 0; + Expr* expr = 0; + + Element* actionElement = (Element*)xslAction; + switch ( getElementType(nodeName, ps) ) { + + //-- xsl:apply-templates + case XSLType::APPLY_TEMPLATES : + { + + String* mode = 0; + Attr* modeAttr = actionElement->getAttributeNode(MODE_ATTR); + if ( modeAttr ) mode = new String(modeAttr->getValue()); + String selectAtt = actionElement->getAttribute(SELECT_ATTR); + if ( selectAtt.length() == 0 ) selectAtt = "*"; + pExpr = ps->getPatternExpr(selectAtt); + ExprResult* exprResult = pExpr->evaluate(node, ps); + NodeSet* nodeSet = 0; + if ( exprResult->getResultType() == ExprResult::NODESET ) { + nodeSet = (NodeSet*)exprResult; + //-- push nodeSet onto context stack + ps->getNodeSetStack()->push(nodeSet); + for (int i = 0; i < nodeSet->size(); i++) { + process(nodeSet->get(i), node, mode, ps); + } + //-- remove nodeSet from context stack + ps->getNodeSetStack()->pop(); + } + else { + notifyError("error processing apply-templates"); + } + //-- clean up + delete mode; + delete exprResult; + break; + } + //-- attribute + case XSLType::ATTRIBUTE: + { + Attr* attr = actionElement->getAttributeNode(NAME_ATTR); + if ( !attr) { + notifyError("missing required name attribute for xsl:attribute"); + } + else { + String ns = actionElement->getAttribute(NAMESPACE_ATTR); + //-- process name as an AttributeValueTemplate + String name; + processAttrValueTemplate(attr->getValue(),name,node,ps); + Attr* newAttr = 0; + //-- check name validity + if ( XMLUtils::isValidQName(name)) { + newAttr = resultDoc->createAttribute(name); + } + else { + String err("error processing xsl:attribute, "); + err.append(name); + err.append(" is not a valid QName."); + notifyError(err); + } + if ( newAttr ) { + DocumentFragment* dfrag = resultDoc->createDocumentFragment(); + ps->getNodeStack()->push(dfrag); + processTemplate(node, actionElement, ps); + ps->getNodeStack()->pop(); + String value; + XMLDOMUtils::getNodeValue(dfrag, &value); + XMLUtils::normalizeAttributeValue(value); + newAttr->setValue(value); + if ( ! ps->addToResultTree(newAttr) ) + delete newAttr; + } + } + break; + } + // call-template + case XSLType::CALL_TEMPLATE : + { + String templateName = actionElement->getAttribute(NAME_ATTR); + if ( templateName.length() > 0 ) { + Element* xslTemplate = ps->getNamedTemplate(templateName); + if ( xslTemplate ) { + processTemplate(node, xslTemplate, ps); + } + } + else { + notifyError("missing required name attribute for xsl:call-template"); + } + } + // xsl:if + case XSLType::CHOOSE : + { + NodeList* nl = actionElement->getChildNodes(); + Element* xslTemplate = 0; + for (int i = 0; i < nl->getLength(); i++ ) { + Node* tmp = nl->item(i); + if ( tmp->getNodeType() != Node::ELEMENT_NODE ) continue; + xslTemplate = (Element*)tmp; + DOMString nodeName = xslTemplate->getNodeName(); + switch ( getElementType(nodeName, ps) ) { + case XSLType::WHEN : + { + expr = ps->getExpr(xslTemplate->getAttribute(TEST_ATTR)); + ExprResult* result = expr->evaluate(node, ps); + if ( result->booleanValue() ) { + processTemplate(node, xslTemplate, ps); + return; + } + break; + } + case XSLType::OTHERWISE: + processTemplate(node, xslTemplate, ps); + return; //-- important to break out of everything + default: //-- invalid xsl:choose child + break; + } + } //-- end for-each child of xsl:choose + break; + } + case XSLType::COMMENT: + { + DocumentFragment* dfrag = resultDoc->createDocumentFragment(); + ps->getNodeStack()->push(dfrag); + processTemplate(node, actionElement, ps); + ps->getNodeStack()->pop(); + String value; + if (!getText(dfrag, value, MB_FALSE,MB_TRUE)) { + String warning(NON_TEXT_TEMPLATE_WARNING); + warning.append(COMMENT); + notifyError(warning, ErrorObserver::WARNING); + } + //XMLUtils::normalizePIValue(value); + Comment* comment = resultDoc->createComment(value); + if ( ! ps->addToResultTree(comment) ) delete comment; + break; + } + case XSLType::COPY: + xslCopy(node, actionElement, ps); + break; + case XSLType::ELEMENT: + { + Attr* attr = actionElement->getAttributeNode(NAME_ATTR); + if ( !attr) { + notifyError("missing required name attribute for xsl:element"); + } + else { + String ns = actionElement->getAttribute(NAMESPACE_ATTR); + //-- process name as an AttributeValueTemplate + String name; + processAttrValueTemplate(attr->getValue(),name,node,ps); + Element* element = 0; + //-- check name validity + if ( XMLUtils::isValidQName(name)) { + element = resultDoc->createElement(name); + } + else { + String err("error processing xsl:element, '"); + err.append(name); + err.append("' is not a valid QName."); + notifyError(err); + } + if ( element ) { + ps->addToResultTree(element); + ps->getNodeStack()->push(element); + //-- processAttributeSets + processAttributeSets(actionElement->getAttribute(USE_ATTRIBUTE_SETS_ATTR), + node, ps); + } + //-- process template + processTemplate(node, actionElement, ps); + if( element ) ps->getNodeStack()->pop(); + } + break; + } + //-- xsl:for-each + case XSLType::FOR_EACH : + { + String selectAtt = actionElement->getAttribute(SELECT_ATTR); + + if ( selectAtt.length() == 0 ) selectAtt = "*"; //-- default + + pExpr = ps->getPatternExpr(selectAtt); + + ExprResult* exprResult = pExpr->evaluate(node, ps); + NodeSet* nodeSet = 0; + if ( exprResult->getResultType() == ExprResult::NODESET ) { + nodeSet = (NodeSet*)exprResult; + + //-- push nodeSet onto context stack + ps->getNodeSetStack()->push(nodeSet); + for (int i = 0; i < nodeSet->size(); i++) { + processTemplate(nodeSet->get(i), xslAction, ps); + } + //-- remove nodeSet from context stack + ps->getNodeSetStack()->pop(); + } + else { + notifyError("error processing for-each"); + } + //-- clean up exprResult + delete exprResult; + break; + } + // xsl:if + case XSLType::IF : + { + DOMString selectAtt = actionElement->getAttribute(TEST_ATTR); + expr = ps->getExpr(selectAtt); + //-- check for Error + /* add later when we create ErrResult */ + + ExprResult* exprResult = expr->evaluate(node, ps); + if ( exprResult->booleanValue() ) { + processTemplate(node, actionElement, ps); + } + delete exprResult; + + break; + } + case XSLType::MESSAGE : + { + String message; + XMLDOMUtils::getNodeValue(actionElement, &message); + //-- we should add a MessageObserver class + cout << "xsl:message - "<< message << endl; + break; + } + //xsl:number + case XSLType::NUMBER : + { + break; + } + //-- xsl:processing-instruction + case XSLType::PI: + { + Attr* attr = actionElement->getAttributeNode(NAME_ATTR); + if ( !attr) { + String err("missing required name attribute for xsl:"); + err.append(PI); + notifyError(err); + } + else { + String ns = actionElement->getAttribute(NAMESPACE_ATTR); + //-- process name as an AttributeValueTemplate + String name; + processAttrValueTemplate(attr->getValue(),name,node,ps); + //-- check name validity + if ( !XMLUtils::isValidQName(name)) { + String err("error processing xsl:"); + err.append(PI); + err.append(", '"); + err.append(name); + err.append("' is not a valid QName."); + notifyError(err); + } + DocumentFragment* dfrag = resultDoc->createDocumentFragment(); + ps->getNodeStack()->push(dfrag); + processTemplate(node, actionElement, ps); + ps->getNodeStack()->pop(); + String value; + if (!getText(dfrag, value, MB_FALSE,MB_TRUE)) { + String warning(NON_TEXT_TEMPLATE_WARNING); + warning.append(PI); + notifyError(warning, ErrorObserver::WARNING); + } + XMLUtils::normalizePIValue(value); + ProcessingInstruction* pi + = resultDoc->createProcessingInstruction(name, value); + if ( ! ps->addToResultTree(pi) ) delete pi; + } + break; + } + //-- xsl:text + case XSLType::TEXT : + { + String data; + //-- get Node value, and do not perform whitespace stripping + XMLDOMUtils::getNodeValue(actionElement, &data); + Text* text = resultDoc->createTextNode(data); + ps->addToResultTree(text); + break; + } + case XSLType::EXPR_DEBUG: //-- proprietary debug element + { + DOMString exprAtt = actionElement->getAttribute(EXPR_ATTR); + Expr* expr = ps->getExpr(exprAtt); + ExprResult* exprResult = expr->evaluate(node, ps); + String data("expr debug: "); + expr->toString(data); + cout << data << endl; + data.clear(); + cout << "result: "; + if ( exprResult ) { + switch ( exprResult->getResultType() ) { + case ExprResult::NODESET: + cout << "#NodeSet - "; + default: + exprResult->stringValue(data); + cout << data; + break; + } + } + cout << endl; + + delete exprResult; + break; + } + //-- xsl:value-of + case XSLType::VALUE_OF : + { + DOMString selectAtt = actionElement->getAttribute(SELECT_ATTR); + + Expr* expr = ps->getExpr(selectAtt); + ExprResult* exprResult = expr->evaluate(node, ps); + String value; + if ( !exprResult ) { + notifyError("null ExprResult"); + break; + } + exprResult->stringValue(value); + //-- handle whitespace stripping + if ( exprResult->getResultType() == ExprResult::NODESET) { + NodeSet* nodes = (NodeSet*)exprResult; + if ( nodes->size() > 0) { + Node* node = nodes->get(0); + if ( ps->isStripSpaceAllowed(node) ) { + const String temp = value; + value.clear(); + XMLUtils::stripSpace(temp, value); + } + } + } + ps->addToResultTree(resultDoc->createTextNode(value)); + delete exprResult; + break; + } + case XSLType::VARIABLE : + { + String name = actionElement->getAttribute(NAME_ATTR); + if ( name.length() == 0 ) { + notifyError("missing required name attribute for xsl:variable"); + break; + } + ExprResult* exprResult = processVariable(node, actionElement, ps); + bindVariable(name, exprResult, ps); + break; + } + //-- literal + default: + Element* element = resultDoc->createElement(nodeName); + ps->addToResultTree(element); + ps->getNodeStack()->push(element); + //-- handle attributes + NamedNodeMap* atts = actionElement->getAttributes(); + if ( atts ) { + String xsltNameSpace = ps->getXSLNamespace(); + NodeSet nonXSLAtts(atts->getLength()); + int i; + //-- process special XSL attributes first + for ( i = 0; i < atts->getLength(); i++ ) { + Attr* attr = (Attr*) atts->item(i); + //-- filter attributes in the XSLT namespace + String attrNameSpace; + XMLUtils::getNameSpace(attr->getName(), attrNameSpace); + if ( attrNameSpace.isEqual(xsltNameSpace) ) { + //-- check for useAttributeSet + String localPart; + XMLUtils::getLocalPart(attr->getName(), localPart); + if ( USE_ATTRIBUTE_SETS_ATTR.isEqual(localPart) ) { + processAttributeSets(attr->getValue(), node, ps); + } + continue; + } + else nonXSLAtts.add(attr); + } + //-- process all non XSL attributes + for ( i = 0; i < nonXSLAtts.size(); i++ ) { + Attr* attr = (Attr*) nonXSLAtts.get(i); + Attr* newAttr = resultDoc->createAttribute(attr->getName()); + //-- process Attribute Value Templates + String value; + processAttrValueTemplate(attr->getValue(), value, node, ps); + newAttr->setValue(value); + ps->addToResultTree(newAttr); + } + } + //-- process children + NodeList* nl = xslAction->getChildNodes(); + for (int i = 0; i < nl->getLength(); i++) { + processAction(node, nl->item(i),ps); + } + ps->getNodeStack()->pop(); + break; + } + } + + //cout << "XSLProcessor#processAction [exit]\n"; +} //-- processAction + +/** + * Processes the attribute sets specified in the names argument +**/ +void XSLProcessor::processAttributeSets + (const String& names, Node* node, ProcessorState* ps) +{ + //-- split names + Tokenizer tokenizer(names); + String name; + while ( tokenizer.hasMoreTokens() ) { + tokenizer.nextToken(name); + NodeSet* attSet = ps->getAttributeSet(name); + if ( attSet ) { + for ( int i = 0; i < attSet->size(); i++) { + processAction(node, attSet->get(i), ps); + } + } + } +} //-- processAttributeSets + +/** + * Processes the given attribute value as an AttributeValueTemplate + * @param attValue the attribute value to process + * @param result, the String in which to store the result + * @param context the current context node + * @param ps the current ProcessorState +**/ +void XSLProcessor::processAttrValueTemplate + (const String& attValue, String& result, Node* context, ProcessorState* ps) +{ + AttributeValueTemplate* avt = 0; + avt = exprParser.createAttributeValueTemplate(attValue); + ExprResult* exprResult = avt->evaluate(context,ps); + exprResult->stringValue(result); + delete exprResult; + delete avt; + +} //-- processAttributeValueTemplate + + +/** + * Processes the set of nodes using the given context, and ProcessorState +**/ +void XSLProcessor::processTemplate(Node* node, Node* xslTemplate, ProcessorState* ps) { + + if ( !xslTemplate ) { + //-- do default? + } + else { + NodeList* nl = xslTemplate->getChildNodes(); + for (int i = 0; i < nl->getLength(); i++) { + processAction(node, nl->item(i), ps); + } + } +} //-- processTemplate + +/** + * processes the xslVariable parameter as an xsl:variable using the given context, + * and ProcessorState. + * If the xslTemplate contains an "expr" attribute, the attribute is evaluated + * as an Expression and the ExprResult is returned. Otherwise the xslVariable is + * is processed as a template, and it's result is converted into an ExprResult + * @return an ExprResult +**/ +ExprResult* XSLProcessor::processVariable + (Node* node, Element* xslVariable, ProcessorState* ps) +{ + + if ( !xslVariable ) { + return new StringResult("unable to process variable"); + } + + //-- check for EXPR_ATTR + Attr* attr = xslVariable->getAttributeNode(EXPR_ATTR); + if ( attr ) { + Expr* expr = ps->getExpr(attr->getValue()); + return expr->evaluate(node, ps); + } + else { + NodeList* nl = xslVariable->getChildNodes(); + Document* resultTree = ps->getResultDocument(); + NodeStack* nodeStack = ps->getNodeStack(); + nodeStack->push(resultTree->createDocumentFragment()); + for (int i = 0; i < nl->getLength(); i++) { + processAction(node, nl->item(i), ps); + } + Node* node = nodeStack->pop(); + //-- add clean up for This new NodeSet; + NodeSet* nodeSet = new NodeSet(); + nodeSet->add(node); + return nodeSet; + } +} //-- processTemplate + +/** + * Performs the xsl:copy action as specified in the XSL Working Draft +**/ +void XSLProcessor::xslCopy(Node* node, Element* action, ProcessorState* ps) { + if ( !node ) return; + + Document* resultDoc = ps->getResultDocument(); + Node* copy = 0; + switch ( node->getNodeType() ) { + case Node::DOCUMENT_NODE: + //-- just process children + processTemplate(node, action, ps); + break; + case Node::ATTRIBUTE_NODE: + { + Attr* attr = (Attr*) node; + Attr* copyAtt = resultDoc->createAttribute(attr->getName()); + copyAtt->setValue(attr->getValue()); + copy = copyAtt; + break; + } + case Node::ELEMENT_NODE: + { + Element* element = (Element*)node; + String nodeName = element->getNodeName(); + copy = resultDoc->createElement(nodeName); + ps->addToResultTree(copy); + ps->getNodeStack()->push(copy); + //-- copy namespace attributes + // * add later * + processTemplate(node, action, ps); + ps->getNodeStack()->pop(); + return; + } + case Node::CDATA_SECTION_NODE: + { + CDATASection* cdata = (CDATASection*)node; + copy = resultDoc->createCDATASection(cdata->getData()); + break; + } + case Node::TEXT_NODE: + { + Text* text = (Text*)node; + copy = resultDoc->createTextNode(text->getData()); + break; + } + case Node::PROCESSING_INSTRUCTION_NODE: + { + ProcessingInstruction* pi = (ProcessingInstruction*)node; + copy = resultDoc->createProcessingInstruction(pi->getTarget(), pi->getData()); + break; + } + case Node::COMMENT_NODE: + { + Comment* comment = (Comment*)node; + copy = resultDoc->createComment(comment->getData()); + break; + } + default: + break; + } + if ( copy ) ps->addToResultTree(copy); +} //-- xslCopy + + +#ifdef MOZILLA +NS_IMETHODIMP +XSLProcessor::TransformDocument(nsIDOMElement* aSourceDOM, + nsIDOMElement* aStyleDOM, + nsIDOMDocument* aOutputDoc, + nsIObserver* aObserver) +{ + return NS_OK; +} +#endif + +XSLType::XSLType() { + this->type = LITERAL; +} //-- XSLType + +XSLType::XSLType(const XSLType& xslType) { + this->type = xslType.type; +} //-- XSLType + +XSLType::XSLType(short type) { + this->type = type; +} //-- XSLType + + + diff --git a/mozilla/extensions/transformiix/source/xsl/XSLProcessor.h b/mozilla/extensions/transformiix/source/xsl/XSLProcessor.h new file mode 100644 index 00000000000..a314a4f0a80 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/XSLProcessor.h @@ -0,0 +1,361 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#ifndef MITREXSL_XSLPROCESSOR_H +#define MITREXSL_XSLPROCESSOR_H + +#ifdef MOZILLA +#include "nsIDocumentTransformer.h" +#else +#include +#include +#include "CommandLineUtils.h" +#include "Printers.h" +#include "URIUtils.h" +#include "XMLParser.h" +#include "XMLDOMUtils.h" +#endif +#include "dom.h" +#include "ExprParser.h" +#include "MITREObject.h" +#include "NamedMap.h" +#include "Names.h" +#include "NodeSet.h" +#include "ProcessorState.h" +#include "String.h" +#include "Tokenizer.h" +#include "ErrorObserver.h" +#include "List.h" + +#ifdef MOZILLA + +/* bacd8ad0-552f-11d3-a9f7-000064657374 */ +#define MITRE_XSL_PROCESSOR_CID \ +{ 0xbacd8ad0, 0x552f, 0x11d3, {0xa9, 0xf7, 0x00, 0x00, 0x64, 0x65, 0x73, 0x74} } + +#endif + +/** + * A class for Processing XSL Stylesheets + * @author Keith Visco +**/ +class XSLProcessor +#ifdef MOZILLA +: nsIDocumentTransformer +#endif +{ +public: +#ifdef MOZILLA + // Define a Create method to be used with a factory: + static NS_METHOD + Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult); + + /** + * This macro expands into a declaration of the nsISupports interface. + * Every XPCOM component needs to implement nsISupports, as it acts + * as the gateway to other interfaces this component implements. You + * could manually declare QueryInterface, AddRef, and Release instead + * of using this macro, but why? + */ + // nsISupports interface + NS_DECL_ISUPPORTS + + // nsIDocumentTransformer methods + NS_IMETHOD TransformDocument(nsIDOMElement* aSourceDOM, + nsIDOMElement* aStyleDOM, + nsIDOMDocument* aOutputDoc, + nsIObserver* aObserver); +#endif + + /** + * A warning message used by all templates that do not allow non character + * data to be generated + **/ + static const String NON_TEXT_TEMPLATE_WARNING; + + /** + * Creates a new XSLProcessor + **/ + XSLProcessor(); + + /** + * Default destructor for XSLProcessor + **/ +#ifdef MOZILLA + virtual ~XSLProcessor(); +#else + ~XSLProcessor(); +#endif + + /** + * Registers the given ErrorObserver with this XSLProcessor + **/ + void addErrorObserver(ErrorObserver& errorObserver); + + /** + * Returns the name of this XSL processor + **/ + String& getAppName(); + + /** + * Returns the version of this XSL processor + **/ + String& getAppVersion(); + + //--------------------------------------------/ + //-- Methods that return the Result Document -/ + //--------------------------------------------/ + +#ifndef MOZILLA + /** + * Parses all XML Stylesheet PIs associated with the + * given XML document. If any stylesheet PIs are found with + * type="text/xsl" the href psuedo attribute value will be + * added to the given href argument. If multiple text/xsl stylesheet PIs + * are found, the one closest to the end of the document is used. + **/ + void getHrefFromStylesheetPI(Document& xmlDocument, String& href); + + /** + * Processes the given XML Document, the XSL stylesheet + * will be retrieved from the XML Stylesheet Processing instruction, + * otherwise an empty document will be returned. + * @param xmlDocument the XML document to process + * @param documentBase the document base of the XML document, for + * resolving relative URIs + * @return the result tree. + **/ + Document* process(Document& xmlDocument, String& documentBase); +#endif + + /** + * Processes the given XML Document using the given XSL document + * @return the result tree. + **/ + Document* process(Document& xmlDocument, Document& xslDocument); + +#ifndef MOZILLA + /** + * Reads an XML Document from the given XML input stream, and + * processes the document using the XSL document derived from + * the given XSL input stream. + * @return the result tree. + **/ + Document* process(istream& xmlInput, istream& xslInput); + + /** + * Reads an XML document from the given XML input stream. The + * XML document is processed using the associated XSL document + * retrieved from the XML document's Stylesheet Processing Instruction, + * otherwise an empty document will be returned. + * @param xmlDocument the XML document to process + * @param documentBase the document base of the XML document, for + * resolving relative URIs + * @return the result tree. + **/ + Document* process(istream& xmlInput, String& documentBase); + + //----------------------------------------------/ + //-- Methods that print the result to a stream -/ + //----------------------------------------------/ + + /** + * Reads an XML Document from the given XML input stream. + * The XSL Stylesheet is obtained from the XML Documents stylesheet PI. + * If no Stylesheet is found, an empty document will be the result; + * otherwise the XML Document is processed using the stylesheet. + * The result tree is printed to the given ostream argument, + * will not close the ostream argument + **/ + void process(istream& xmlInput, String& documentBase, ostream& out); + + /** + * Processes the given XML Document using the given XSL document. + * The result tree is printed to the given ostream argument, + * will not close the ostream argument + **/ + void process(Document& xmlDocument, Document& xslDocument, ostream& out); + + /** + * Reads an XML Document from the given XML input stream, and + * processes the document using the XSL document derived from + * the given XSL input stream. + * The result tree is printed to the given ostream argument, + * will not close the ostream argument + **/ + void process(istream& xmlInput, istream& xslInput, ostream& out); +#endif + +private: + + + /** + * Application Name and version + **/ + String appName; + String appVersion; + + /** + * The list of ErrorObservers + **/ + List errorObservers; + + /** + * Fatal ErrorObserver + **/ + SimpleErrorObserver fatalObserver; + + /** + * An expression parser for creating AttributeValueTemplates + **/ + ExprParser exprParser; + + /** + * The version of XSL which this Processes + **/ + String xslVersion; + + /** + * Named Map for quick reference to XSL Types + **/ + NamedMap xslTypes; + + /** + * Binds the given ExprResult to the given name + **/ + void bindVariable(String& name, ExprResult* exprResult, ProcessorState* ps); + +#ifndef MOZILLA + XMLPrinter* createPrinter(Document& xslDocument, ostream& out); +#endif + + /** + * Looks up the given XSLType with the given name + * The ProcessorState is used to get the current XSLT namespace + **/ + short getElementType(String& name, ProcessorState* ps); + + + /** + * Gets the Text value of the given DocumentFragment. The value is placed + * into the given destination String. If a non text node element is + * encountered and warningForNonTextNodes is turned on, the MB_FALSE + * will be returned, otherwise true is always returned. + * @param dfrag the document fragment to get the text from + * @param dest the destination string to place the text into. + * @param deep indicates to process non text nodes and recusively append + * their value. If this value is true, the allowOnlyTextNodes flag is ignored. + **/ + MBool getText + (DocumentFragment* dfrag, String& dest, MBool deep, MBool allowOnlyTextNodes); + + /** + * Notifies all registered ErrorObservers of the given error + **/ + void notifyError(const char* errorMessage); + + /** + * Notifies all registered ErrorObservers of the given error + **/ + void notifyError(String& errorMessage); + + /** + * Notifies all registered ErrorObservers of the given error + **/ + void notifyError(String& errorMessage, ErrorObserver::ErrorLevel level); + +#ifndef MOZILLA + /** + * Parses the contents of data, and returns the type and href psuedo attributes + **/ + void parseStylesheetPI(String& data, String& type, String& href); +#endif + + void process(Node* node, Node* context, ProcessorState* ps); + void process(Node* node, Node* context, String* mode, ProcessorState* ps); + + void processAction(Node* node, Node* xslAction, ProcessorState* ps); + + /** + * Processes the attribute sets specified in the names argument + **/ + void processAttributeSets(const String& names, Node* node, ProcessorState* ps); + + /** + * Processes the given attribute value as an AttributeValueTemplate + * @param attValue the attribute value to process + * @param result, the String in which to store the result + * @param context the current context node + * @param ps the current ProcessorState + **/ + void processAttrValueTemplate + (const String& attValue, String& result, Node* context, ProcessorState* ps); + + void processTemplate(Node* node, Node* xslTemplate, ProcessorState* ps); + + ExprResult* processVariable(Node* node, Element* xslVariable, ProcessorState* ps); + + /** + * Performs the xsl:copy action as specified in the XSL Working Draft + **/ + void xslCopy(Node* node, Element* action, ProcessorState* ps); + +}; //-- XSLProcessor + +class XSLType : public MITREObject { + +public: + enum _XSLType { + APPLY_IMPORTS = 1, + APPLY_TEMPLATES, + ATTRIBUTE, + ATTRIBUTE_SET, + CALL_TEMPLATE, + CHOOSE, + COMMENT, + COPY, + COPY_OF, + ELEMENT, + IF, + FOR_EACH, + LITERAL, + NUMBER, + OTHERWISE, + PARAM, + PI, + PRESERVE_SPACE, + STRIP_SPACE, + TEMPLATE, + TEXT, + VALUE_OF, + VARIABLE, + WHEN, + MESSAGE, + EXPR_DEBUG, // temporary, used for debugging + }; + + XSLType(const XSLType& xslType); + XSLType(); + XSLType(short type); + short type; +}; + +#endif diff --git a/mozilla/extensions/transformiix/source/xsl/expr/AdditiveExpr.cpp b/mozilla/extensions/transformiix/source/xsl/expr/AdditiveExpr.cpp new file mode 100644 index 00000000000..21c26518a97 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/AdditiveExpr.cpp @@ -0,0 +1,133 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * Represents a AdditiveExpr, an binary expression that + * performs an additive operation between it's lvalue and rvalue:
+ * + : addition + * - : substraction + * @author Keith Visco +**/ + +#include "Expr.h" + +/** + * Creates a new AdditiveExpr using the default operator (ADDITION) +**/ +AdditiveExpr::AdditiveExpr() { + this->op = ADDITION; + this->leftExpr = 0; + this->rightExpr = 0; +} //-- AdditiveExpr + +/** + * Creates a new AdditiveExpr using the given operator +**/ +AdditiveExpr::AdditiveExpr(Expr* leftExpr, Expr* rightExpr, short op) { + this->op = op; + this->leftExpr = leftExpr; + this->rightExpr = rightExpr; +} //-- AdditiveExpr + +AdditiveExpr::~AdditiveExpr() { + delete leftExpr; + delete rightExpr; +} //-- ~AdditiveExpr + +/** + * Sets the left side of this AdditiveExpr +**/ +void AdditiveExpr::setLeftExpr(Expr* leftExpr) { + this->leftExpr = leftExpr; +} //-- setLeftExpr + +/** + * Sets the right side of this AdditiveExpr +**/ +void AdditiveExpr::setRightExpr(Expr* rightExpr) { + this->rightExpr = rightExpr; +} //-- setRightExpr + +/** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation +**/ +ExprResult* AdditiveExpr::evaluate(Node* context, ContextState* cs) { + + + double rightDbl = Double::NaN; + ExprResult* exprRes = 0; + + if ( rightExpr ) { + exprRes = rightExpr->evaluate(context, cs); + if ( exprRes ) rightDbl = exprRes->numberValue(); + delete exprRes; + } + + double leftDbl = Double::NaN; + if ( leftExpr ) { + exprRes = leftExpr->evaluate(context, cs); + if ( exprRes ) leftDbl = exprRes->numberValue(); + delete exprRes; + } + + double result = 0; + + switch ( op ) { + case SUBTRACTION: + result = leftDbl - rightDbl; + break; + default: + result = leftDbl + rightDbl; + break; + } + return new NumberResult(result); +} //-- evaluate + +/** + * Returns the String representation of this Expr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this Expr. +**/ +void AdditiveExpr::toString(String& str) { + + if ( leftExpr ) leftExpr->toString(str); + else str.append("null"); + + switch ( op ) { + case SUBTRACTION: + str.append(" - "); + break; + default: + str.append(" + "); + break; + } + if ( rightExpr ) rightExpr->toString(str); + else str.append("null"); + +} //-- toString + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/AttributeExpr.cpp b/mozilla/extensions/transformiix/source/xsl/expr/AttributeExpr.cpp new file mode 100644 index 00000000000..2f6af415129 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/AttributeExpr.cpp @@ -0,0 +1,147 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "Expr.h" + +/** + * This class represents a ElementExpr as defined by the XSL + * Working Draft + *
+ * 
+ * @author Keith Visco + * This file was ported from XSL:P +**/ + +//- Constructors -/ + +AttributeExpr::AttributeExpr() { + this->isWild = MB_FALSE; +} //-- AttributeExpr + +AttributeExpr::AttributeExpr(String& name) { + //-- copy name + this->name = name; + this->isWild = MB_FALSE; +} //-- AttributeExpr + +/** + * Destructor +**/ +AttributeExpr::~AttributeExpr() { +} //-- ~AttributeExpr + + //------------------/ + //- Public Methods -/ +//------------------/ + +/** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation +**/ +ExprResult* AttributeExpr::evaluate(Node* context, ContextState* cs) { + + NodeSet* nodeSet = new NodeSet(); + if ( !context ) return nodeSet; + NamedNodeMap* atts = context->getAttributes(); + if ( atts ) { + for (int i = 0; i < atts->getLength(); i++ ) { + Attr* attr = (Attr*)atts->item(i); + if ( isWild ) nodeSet->add(attr); + else { + String attName = attr->getName(); + if ( name.isEqual(attName) ){ + nodeSet->add(attr); + } + } + } + } + return nodeSet; +} //-- evaluate + +/** + * Returns the default priority of this Pattern based on the given Node, + * context Node, and ContextState. + * If this pattern does not match the given Node under the current context Node and + * ContextState then Negative Infinity is returned. +**/ +double AttributeExpr::getDefaultPriority(Node* node, Node* context, ContextState* cs) { + return 0.0; +} //-- getDefaultPriority + +/** + * Returns the name of this ElementExpr + * @return the name of this ElementExpr +**/ +const String& AttributeExpr::getName() { + return (const String&) this->name; +} //-- getName + +void AttributeExpr::setName(const String& name) { + this->name.clear(); + this->name.append(name); +} //-- setName + +void AttributeExpr::setWild(MBool isWild) { + this->isWild = isWild; +} //-- setWild + //-----------------------------/ + //- Methods from NodeExpr.cpp -/ +//-----------------------------/ + +/** + * Returns the type of this NodeExpr + * @return the type of this NodeExpr +**/ +short AttributeExpr::getType() { + return NodeExpr::ATTRIBUTE_EXPR; +} //-- getType + +/** + * Determines whether this NodeExpr matches the given node within + * the given context +**/ +MBool AttributeExpr::matches(Node* node, Node* context, ContextState* cs) { + if ( (node) && (node->getNodeType() == Node::ATTRIBUTE_NODE) ) { + if ( isWild ) return MB_TRUE; + const String nodeName = ((Attr*)node)->getName(); + return nodeName.isEqual(this->name); + } + return MB_FALSE; +} //-- matches + + +/** + * Returns the String representation of this NodeExpr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this NodeExpr. +**/ +void AttributeExpr::toString(String& dest) { + dest.append('@'); + if (isWild) dest.append('*'); + else dest.append(this->name); +} //-- toString + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/AttributeValueTemplate.cpp b/mozilla/extensions/transformiix/source/xsl/expr/AttributeValueTemplate.cpp new file mode 100644 index 00000000000..b807a03b7a0 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/AttributeValueTemplate.cpp @@ -0,0 +1,95 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * AttributeValueTemplate + * @author Keith Visco +**/ + +#include "Expr.h" + +/** + * Create a new AttributeValueTemplate +**/ +AttributeValueTemplate::AttributeValueTemplate() {}; + +/** + * Default destructor +**/ +AttributeValueTemplate::~AttributeValueTemplate() { + ListIterator* iter = expressions.iterator(); + while ( iter->hasNext() ) { + iter->next(); //advance iterator to allow remove + Expr* expr = (Expr*)iter->remove(); + delete expr; + } + delete iter; + +} //-- ~AttributeValueTemplate + +/** + * Adds the given Expr to this AttributeValueTemplate +**/ +void AttributeValueTemplate::addExpr(Expr* expr) { + if (expr) expressions.add(expr); +} //-- addExpr + +/** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation +**/ +ExprResult* AttributeValueTemplate::evaluate(Node* context, ContextState* cs) { + ListIterator* iter = expressions.iterator(); + String result; + while ( iter->hasNext() ) { + Expr* expr = (Expr*)iter->next(); + ExprResult* exprResult = expr->evaluate(context, cs); + exprResult->stringValue(result); + delete exprResult; + } + delete iter; + return new StringResult(result); +} //-- evaluate + +/** +* Returns the String representation of this Expr. +* @param dest the String to use when creating the String +* representation. The String representation will be appended to +* any data in the destination String, to allow cascading calls to +* other #toString() methods for Expressions. +* @return the String representation of this Expr. +**/ +void AttributeValueTemplate::toString(String& str) { + ListIterator* iter = expressions.iterator(); + while ( iter->hasNext() ) { + str.append('{'); + Expr* expr = (Expr*)iter->next(); + expr->toString(str); + str.append('}'); + } + delete iter; +} //-- toString + + + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/BasicNodeExpr.cpp b/mozilla/extensions/transformiix/source/xsl/expr/BasicNodeExpr.cpp new file mode 100644 index 00000000000..74e52e13955 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/BasicNodeExpr.cpp @@ -0,0 +1,134 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "Expr.h" + +/** + * @author Keith Visco + * This file was ported from XSL:P +**/ + +//- Constructors -/ + +/** + * Creates a new BasicNodeExpr, which matchs any Node +**/ +BasicNodeExpr::BasicNodeExpr() { + this->type = NodeExpr::NODE_EXPR; +} //-- BasicNodeExpr + +/** + * Creates a new BasicNodeExpr of the given type +**/ +BasicNodeExpr::BasicNodeExpr(NodeExpr::NodeExprType nodeExprType) { + this->type = nodeExprType; +} //-- BasicNodeExpr + +/** + * Destroys this NodeExpr +**/ +BasicNodeExpr::~BasicNodeExpr() {}; + + //------------------/ + //- Public Methods -/ +//------------------/ + +/** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation +**/ +ExprResult* BasicNodeExpr::evaluate(Node* context, ContextState* cs) { + NodeSet* nodeSet = new NodeSet(); + if ( !context ) return nodeSet; + NodeList* nl = context->getChildNodes(); + for (int i = 0; i < nl->getLength(); i++ ) { + Node* node = nl->item(i); + if (matches(node, context, cs)) nodeSet->add(node); + } + return nodeSet; +} //-- evaluate + + //-----------------------------/ + //- Methods from NodeExpr.cpp -/ +//-----------------------------/ + +/** + * Returns the default priority of this Pattern based on the given Node, + * context Node, and ContextState. + * If this pattern does not match the given Node under the current context Node and + * ContextState then Negative Infinity is returned. +**/ +double BasicNodeExpr::getDefaultPriority(Node* node, Node* context, ContextState* cs) { + return -0.5; +} //-- getDefaultPriority + +/** + * Returns the type of this NodeExpr + * @return the type of this NodeExpr +**/ +short BasicNodeExpr::getType() { + return type; +} //-- getType + +/** + * Determines whether this NodeExpr matches the given node within + * the given context +**/ +MBool BasicNodeExpr::matches(Node* node, Node* context, ContextState* cs) { + if ( !node ) return MB_FALSE; + switch ( type ) { + case NodeExpr::COMMENT_EXPR: + return (MBool) (node->getNodeType() == Node::COMMENT_NODE); + case NodeExpr::PI_EXPR : + return (MBool) (node->getNodeType() == Node::PROCESSING_INSTRUCTION_NODE); + default: //-- node() + break; + } + return MB_TRUE; + +} //-- matches + + +/** + * Returns the String representation of this NodeExpr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this NodeExpr. +**/ +void BasicNodeExpr::toString(String& dest) { + switch ( type ) { + case NodeExpr::COMMENT_EXPR: + dest.append("comment()"); + break; + case NodeExpr::PI_EXPR : + dest.append("processing-instruction()"); + break; + default: //-- node() + dest.append("node()"); + break; + } +} //-- toString + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/BooleanFunctionCall.cpp b/mozilla/extensions/transformiix/source/xsl/expr/BooleanFunctionCall.cpp new file mode 100644 index 00000000000..c4cd126a80f --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/BooleanFunctionCall.cpp @@ -0,0 +1,96 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "FunctionLib.h" + +/** + * Creates a default BooleanFunctionCall, which always evaluates to False +**/ +BooleanFunctionCall::BooleanFunctionCall() : FunctionCall(FALSE_FN) { + this->type = FALSE; +} //-- BooleanFunctionCall + +/** + * Creates a BooleanFunctionCall of the given type +**/ +BooleanFunctionCall::BooleanFunctionCall(short type) : FunctionCall() +{ + switch ( type ) { + case BOOLEAN : + FunctionCall::setName(BOOLEAN_FN); + break; + case NOT : + FunctionCall::setName(NOT_FN); + break; + case TRUE : + FunctionCall::setName(TRUE_FN); + break; + default: + FunctionCall::setName(FALSE_FN); + break; + } + this->type = type; +} //-- BooleanFunctionCall + +/** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation +**/ +ExprResult* BooleanFunctionCall::evaluate(Node* context, ContextState* cs) { + + BooleanResult* result = new BooleanResult(); + ListIterator* iter = params.iterator(); + int argc = params.getLength(); + Expr* param = 0; + String err; + + + switch ( type ) { + case BOOLEAN : + if ( requireParams(1,1,cs) ) { + param = (Expr*)iter->next(); + ExprResult* exprResult = param->evaluate(context, cs); + result->setValue(exprResult->booleanValue()); + delete exprResult; + } + break; + case NOT : + if ( requireParams(1,1,cs) ) { + param = (Expr*)iter->next(); + ExprResult* exprResult = param->evaluate(context, cs); + result->setValue(!exprResult->booleanValue()); + delete exprResult; + } + break; + case TRUE : + result->setValue(MB_TRUE); + break; + default: + result->setValue(MB_FALSE); + break; + } + delete iter; + return result; +} //-- evaluate + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/BooleanResult.cpp b/mozilla/extensions/transformiix/source/xsl/expr/BooleanResult.cpp new file mode 100644 index 00000000000..6e92a1dbf75 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/BooleanResult.cpp @@ -0,0 +1,91 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * Boolean Expression result + * @author Keith Visco +**/ + +#include "ExprResult.h" + +/** + * Default Constructor +**/ +BooleanResult::BooleanResult() { + value = MB_FALSE; +} //-- BooleanResult + +BooleanResult::BooleanResult(const BooleanResult& boolResult) { + this->value = boolResult.getValue(); +} //-- BooleanResult + +/** + * Creates a new BooleanResult with the value of the given MBool parameter + * @param boolean the MBool to use for initialization of this BooleanResult's value +**/ +BooleanResult::BooleanResult(MBool boolean) { + this->value = boolean; +} //-- BooleanResult + +/** + * Returns the value of this BooleanResult + * @return the value of this BooleanResult +**/ +MBool BooleanResult::getValue() const { + return this->value; +} //-- getValue + +/** + * Sets the value of this BooleanResult + * @param boolean the MBool to use for this BooleanResult's value +**/ +void BooleanResult::setValue(MBool boolean) { + this->value = boolean; +} //-- setValue + +/** + * Sets the value of this BooleanResult + * @param boolResult the BooleanResult to use for setting this BooleanResult's value +**/ +void BooleanResult::setValue(const BooleanResult& boolResult) { + this->value = boolResult.getValue(); +} //-- setValue + +/* + * Virtual Methods from ExprResult +*/ + +short BooleanResult::getResultType() { + return ExprResult::BOOLEAN; +} //-- getResultType + +void BooleanResult::stringValue(String& str) { + if ( value ) str.append("true"); + else str.append("false"); +} //-- toString + +MBool BooleanResult::booleanValue() { + return this->value; +} //-- toBoolean + +double BooleanResult::numberValue() { + return ( value ) ? 1.0 : 0.0; +} //-- toNumber diff --git a/mozilla/extensions/transformiix/source/xsl/expr/ElementExpr.cpp b/mozilla/extensions/transformiix/source/xsl/expr/ElementExpr.cpp new file mode 100644 index 00000000000..3f596d634ba --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/ElementExpr.cpp @@ -0,0 +1,148 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * ElementExpr + * @author Keith Visco +**/ + +#include "Expr.h" + +/** + * This class represents a ElementExpr as defined by the XSL + * Working Draft + *
+ * 
+ * @author Keith Visco + * This file was ported from XSL:P +**/ + +//- Constructors -/ + +ElementExpr::ElementExpr() { + //-- do nothing +} //-- ElementExpr + +ElementExpr::ElementExpr(String& name) { + //-- copy name + this->name = name; +} //-- ElementExpr + +/** + * Destructor +**/ +ElementExpr::~ElementExpr() { +} //-- ~ElementExpr + + //------------------/ + //- Public Methods -/ +//------------------/ + +/** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation +**/ +ExprResult* ElementExpr::evaluate(Node* context, ContextState* cs) { + + NodeSet* nodeSet = new NodeSet(); + + if ( !context ) return nodeSet; + + NodeList* nl = context->getChildNodes(); + + for (int i = 0; i < nl->getLength(); i++ ) { + Node* node = nl->item(i); + if ( node->getNodeType() == Node::ELEMENT_NODE ) { + String tagName = node->getNodeName(); + if ( name.isEqual(tagName) ){ + nodeSet->add(node); + } + } + } + return nodeSet; +} //-- evaluate + +/** + * Returns the default priority of this Pattern based on the given Node, + * context Node, and ContextState. + * If this pattern does not match the given Node under the current context Node and + * ContextState then Negative Infinity is returned. +**/ +double ElementExpr::getDefaultPriority(Node* node, Node* context, ContextState* cs) { + return 0.0; +} //-- getDefaultPriority + +/** + * Returns the name of this ElementExpr + * @return the name of this ElementExpr +**/ +const String& ElementExpr::getName() { + return (const String&) this->name; +} //-- getName + +void ElementExpr::setName(const String& name) { + this->name.clear(); + this->name.append(name); +} //-- setName + + + //-----------------------------/ + //- Methods from NodeExpr.cpp -/ +//-----------------------------/ + +/** + * Returns the type of this NodeExpr + * @return the type of this NodeExpr +**/ +short ElementExpr::getType() { + return NodeExpr::ELEMENT_EXPR; +} //-- getType + +/** + * Determines whether this NodeExpr matches the given node within + * the given context +**/ +MBool ElementExpr::matches(Node* node, Node* context, ContextState* cs) { + if ( node) { + const String nodeName = node->getNodeName(); + return nodeName.isEqual(this->name); + } + return MB_FALSE; +} //-- matches + + +/** + * Returns the String representation of this NodeExpr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this NodeExpr. +**/ +void ElementExpr::toString(String& dest) { + dest.append(this->name); +} //-- toString + + + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/ErrorFunctionCall.cpp b/mozilla/extensions/transformiix/source/xsl/expr/ErrorFunctionCall.cpp new file mode 100644 index 00000000000..9ed4a7f1903 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/ErrorFunctionCall.cpp @@ -0,0 +1,51 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "FunctionLib.h" + +/** + * Creates an Error FunctionCall with no error message +**/ +ErrorFunctionCall::ErrorFunctionCall() : FunctionCall(ERROR_FN) {}; + +/** + * Creates an Error FunctionCall with the given error message +**/ +ErrorFunctionCall::ErrorFunctionCall(const String& errorMsg) : FunctionCall(ERROR_FN) { + //-- copy errorMsg + this->errorMessage = errorMsg; +} //-- ErrorFunctionCall + +/** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation +**/ +ExprResult* ErrorFunctionCall::evaluate(Node* context, ContextState* cs) { + return new StringResult( errorMessage); +} //-- evaluate + +void ErrorFunctionCall::setErrorMessage(String& errorMsg) { + //-- copy errorMsg + this->errorMessage = errorMsg; +} //-- setError diff --git a/mozilla/extensions/transformiix/source/xsl/expr/Expr.h b/mozilla/extensions/transformiix/source/xsl/expr/Expr.h new file mode 100644 index 00000000000..bbb74f18d51 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/Expr.h @@ -0,0 +1,1460 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * XSL expression class definitions. + * Much of this code was ported from XSL:P.
+ * @author Keith Visco + *
+ *
+ * Modifications:
+ * 19990806: Larry Fitzpatrick
+ *   - changed constant short declarations in many of the classes
+ *     with enumerations, commented with //--LF
+ * 
+ * +**/ + +#ifndef MITREXSL_EXPR_H +#define MITREXSL_EXPR_H + +#include +#include "String.h" +#include "ErrorObserver.h" +#include "NodeSet.h" +#include "List.h" +#include "Stack.h" +#include "dom.h" +#include "ExprResult.h" +#include "baseutils.h" +#include "MITREObject.h" +#include "primitives.h" + +class ContextState : public ErrorObserver { +public: + /** + * Returns the value of a given variable binding within the current scope + * @param the name to which the desired variable value has been bound + * @return the ExprResult which has been bound to the variable with the given + * name + **/ + virtual ExprResult* getVariable(String& name) = 0; + + /** + * Returns the Stack of context NodeSets + * @return the Stack of context NodeSets + **/ + virtual Stack* getNodeSetStack() = 0; + + virtual MBool isStripSpaceAllowed(Node* node) = 0; + +}; //-- ContextState + +/** + * A Base Class for all XSL Expressions + * @author Keith Visco +**/ +class Expr : public MITREObject { + +public: + + /** + * Virtual destructor, important for subclasses + **/ + virtual ~Expr() {}; + + /** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation + **/ + virtual ExprResult* evaluate(Node* context, ContextState* cs) = 0; + + /** + * Returns the String representation of this Expr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this Expr. + **/ + virtual void toString(String& str) = 0; + +}; //-- Expr + + +/** + * A base Pattern class + * @author Keith Visco +**/ +class Pattern { + +public: + + /** + * Virtual destructor, important for subclasses + **/ + virtual ~Pattern() {}; + + /** + * Returns the default priority of this Pattern based on the given Node, + * context Node, and ContextState. + * If this pattern does not match the given Node under the current context Node and + * ContextState then Negative Infinity is returned. + **/ + virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs) = 0; + + /** + * Determines whether this Pattern matches the given node within + * the given context + **/ + virtual MBool matches(Node* node, Node* context, ContextState* cs) = 0; + + + /** + * Returns the String representation of this Pattern. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this Pattern. + **/ + virtual void toString(String& dest) = 0; + +}; //-- Pattern + + +/** + * A Base class for all Expressions and Patterns + * @author Keith Visco +**/ +class PatternExpr : + public Expr, + public Pattern +{ + +public: + + /** + * Virtual destructor, important for subclasses + **/ + virtual ~PatternExpr() {}; + + /** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation + **/ + virtual ExprResult* evaluate(Node* context, ContextState* cs) = 0; + + /** + * Returns the default priority of this Pattern based on the given Node, + * context Node, and ContextState. + * If this pattern does not match the given Node under the current context Node and + * ContextState then Negative Infinity is returned. + **/ + virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs) = 0; + + /** + * Determines whether this PatternExpr matches the given node within + * the given context + **/ + virtual MBool matches(Node* node, Node* context, ContextState* cs) = 0; + + /** + * Returns the String representation of this PatternExpr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this PatternExpr. + **/ + virtual void toString(String& dest) = 0; + +}; //-- PatternExpr + +/** + * Represents an AttributeValueTemplate +**/ +class AttributeValueTemplate: public Expr { + +public: + + AttributeValueTemplate(); + + virtual ~AttributeValueTemplate(); + + /** + * Adds the given Expr to this AttributeValueTemplate + **/ + void addExpr(Expr* expr); + + /** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation + **/ + virtual ExprResult* evaluate(Node* context, ContextState* cs); + + /** + * Returns the String representation of this Expr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this Expr. + **/ + virtual void toString(String& str); + +private: + List expressions; +}; + + +/** + * This class represents a NodeTestExpr as defined by the XSL + * Working Draft + *
+ * 
+ * @author Keith Visco (kvisco@mitre.org) + * This file was ported from XSL:P +**/ +class NodeExpr : public PatternExpr { + +public: + + //-- NodeExpr Types + //-- LF - changed from const short to enum + enum NodeExprType { + ATTRIBUTE_EXPR = 1, + ELEMENT_EXPR, + TEXT_EXPR, + COMMENT_EXPR, + PI_EXPR, + NODE_EXPR, + WILD_CARD, + ROOT_EXPR + }; + + virtual ~NodeExpr() {}; + + //------------------/ + //- Public Methods -/ + //------------------/ + + /** + * Returns the default priority of this Pattern based on the given Node, + * context Node, and ContextState. + * If this pattern does not match the given Node under the current context Node and + * ContextState then Negative Infinity is returned. + **/ + virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs) = 0; + + /** + * Returns the type of this NodeExpr + * @return the type of this NodeExpr + **/ + virtual short getType() = 0; + + /** + * Determines whether this NodeExpr matches the given node within + * the given context + **/ + virtual MBool matches(Node* node, Node* context, ContextState* cs) = 0; + + /** + * Returns the String representation of this Pattern. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this Pattern. + **/ + virtual void toString(String& dest) = 0; + +}; //-- NodeExpr + +/** + * This class represents a AttributeExpr as defined by the XSL + * Working Draft + * @author Keith Visco + * This file was ported from XSL:P +**/ +class AttributeExpr : public NodeExpr { + +public: + + //------------------/ + //- Public Methods -/ + //------------------/ + + AttributeExpr(); + AttributeExpr(String& name); + virtual ~AttributeExpr(); + + void setWild(MBool isWild); + + /** + * Returns the name of this AttributeExpr + * @return the name of this AttributeExpr + **/ + const String& getName(); + + /** + * Sets the name of this AttributeExpr + * @param name the name of the element that this AttributeExpr matches + **/ + void setName(const String& name); + + //-----------------------------------/ + //- Method signatures from NodeExpr -/ + //-----------------------------------/ + + /** + * Returns the default priority of this Pattern based on the given Node, + * context Node, and ContextState. + * If this pattern does not match the given Node under the current context Node and + * ContextState then Negative Infinity is returned. + **/ + virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); + + /** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation + **/ + virtual ExprResult* evaluate(Node* context, ContextState* cs); + + /** + * Returns the type of this NodeExpr + * @return the type of this NodeExpr + **/ + short getType(); + + /** + * Determines whether this NodeExpr matches the given node within + * the given context + **/ + virtual MBool matches(Node* node, Node* context, ContextState* cs); + + /** + * Returns the String representation of this NodeExpr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this NodeExpr. + **/ + virtual void toString(String& dest); + +private: + + String name; + MBool isWild; + +}; //-- AttributeExpr + +/** + * @author Keith Visco + * This file was ported from XSL:P +**/ +class BasicNodeExpr : public NodeExpr { + +public: + + //------------------/ + //- Public Methods -/ + //------------------/ + + /** + * Creates a new BasicNodeExpr of type NodeExpr::NODE_EXPR, which matches + * any node + **/ + BasicNodeExpr(); + + /** + * Creates a new BasicNodeExpr of the given type + **/ + BasicNodeExpr::BasicNodeExpr(NodeExpr::NodeExprType nodeExprType); + + /** + * Destroys this BasicNodeExpr + **/ + virtual ~BasicNodeExpr(); + + //-----------------------------------/ + //- Method signatures from NodeExpr -/ + //-----------------------------------/ + + /** + * Returns the default priority of this Pattern based on the given Node, + * context Node, and ContextState. + * If this pattern does not match the given Node under the current context Node and + * ContextState then Negative Infinity is returned. + **/ + virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); + + /** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation + **/ + virtual ExprResult* evaluate(Node* context, ContextState* cs); + + /** + * Returns the type of this NodeExpr + * @return the type of this NodeExpr + **/ + short getType(); + + /** + * Determines whether this NodeExpr matches the given node within + * the given context + **/ + virtual MBool matches(Node* node, Node* context, ContextState* cs); + + /** + * Returns the String representation of this NodeExpr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this NodeExpr. + **/ + virtual void toString(String& dest); + +private: + NodeExpr::NodeExprType type; +}; //-- BasicNodeExpr + +/** + * This class represents a ElementExpr as defined by the XSL + * Working Draft + *
+ * 
+ * @author Keith Visco (kvisco@mitre.org) + * This file was ported from XSL:P +**/ +class ElementExpr : public NodeExpr { + +public: + + //------------------/ + //- Public Methods -/ + //------------------/ + + ElementExpr(); + ElementExpr(String& name); + virtual ~ElementExpr(); + + /** + * Returns the name of this ElementExpr + * @return the name of this ElementExpr + **/ + const String& getName(); + + /** + * Sets the name of this ElementExpr + * @param name the name of the element that this ElementExpr matches + **/ + void setName(const String& name); + + //-----------------------------------/ + //- Method signatures from NodeExpr -/ + //-----------------------------------/ + + /** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation + **/ + virtual ExprResult* evaluate(Node* context, ContextState* cs); + + /** + * Returns the default priority of this Pattern based on the given Node, + * context Node, and ContextState. + * If this pattern does not match the given Node under the current context Node and + * ContextState then Negative Infinity is returned. + **/ + virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); + + /** + * Returns the type of this NodeExpr + * @return the type of this NodeExpr + **/ + short getType(); + + /** + * Determines whether this NodeExpr matches the given node within + * the given context + **/ + virtual MBool matches(Node* node, Node* context, ContextState* cs); + + /** + * Returns the String representation of this NodeExpr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this NodeExpr. + **/ + virtual void toString(String& dest); + +private: + + String name; + +}; //-- ElementExpr + +/** + * This class represents a IdentityExpr, which only matches a node + * if it is equal to the context node + * @author Keith Visco + *
This class was ported from XSL:P, an open source Java based XSL processor +**/ +class IdentityExpr : public Expr { + +public: + + //------------------/ + //- Public Methods -/ + //------------------/ + + /** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation + **/ + virtual ExprResult* evaluate(Node* context, ContextState* cs); + + /** + * Returns the String representation of this NodeExpr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this NodeExpr. + **/ + virtual void toString(String& dest); + +}; //-- IdentityExpr + +/** + * This class represents a ParentExpr, which only selects a node + * if it is equal to the context node's parent + * @author Keith Visco + *
This class was ported from XSL:P, an open source Java based XSL processor +**/ +class ParentExpr : public Expr { + +public: + + //------------------/ + //- Public Methods -/ + //------------------/ + + /** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation + **/ + virtual ExprResult* evaluate(Node* context, ContextState* cs); + + + /** + * Returns the String representation of this NodeExpr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this NodeExpr. + **/ + virtual void toString(String& dest); + +}; //-- ParentExpr + +/** + * This class represents a TextExpr, which only matches any text node + * @author Keith Visco + *
This class was ported from XSL:P, an open source Java based XSL processor +**/ +class TextExpr : public NodeExpr { + +public: + + //------------------/ + //- Public Methods -/ + //------------------/ + + /** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation + **/ + virtual ExprResult* evaluate(Node* context, ContextState* cs); + + /** + * Returns the default priority of this Pattern based on the given Node, + * context Node, and ContextState. + * If this pattern does not match the given Node under the current context Node and + * ContextState then Negative Infinity is returned. + **/ + virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); + + /** + * Returns the type of this NodeExpr + * @return the type of this NodeExpr + **/ + virtual short getType(); + + /** + * Determines whether this NodeExpr matches the given node within + * the given context + **/ + virtual MBool matches(Node* node, Node* context, ContextState* cs); + + + /** + * Returns the String representation of this NodeExpr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this NodeExpr. + **/ + virtual void toString(String& dest); + +}; //-- TextExpr + +/** + * This class represents a WildCardExpr as defined by the XSL + * Working Draft + *
+ * 
+ * @author Keith Visco + *
This class was ported from XSL:P, an open source Java based XSL processor +**/ +class WildCardExpr : public NodeExpr { + +public: + + //------------------/ + //- Public Methods -/ + //------------------/ + + /** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation + **/ + virtual ExprResult* evaluate(Node* context, ContextState* cs); + + /** + * Returns the default priority of this Pattern based on the given Node, + * context Node, and ContextState. + * If this pattern does not match the given Node under the current context Node and + * ContextState then Negative Infinity is returned. + **/ + virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); + + /** + * Returns the type of this NodeExpr + * @return the type of this NodeExpr + **/ + virtual short getType(); + + /** + * Determines whether this NodeExpr matches the given node within + * the given context + **/ + virtual MBool matches(Node* node, Node* context, ContextState* cs); + + + /** + * Returns the String representation of this NodeExpr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this NodeExpr. + **/ + virtual void toString(String& dest); + +}; //-- WildCardExpr + + +/** + * Represents an ordered list of Predicates, + * for use with Step and Filter Expressions + * @author Keith Visco +**/ +class PredicateList { + +public: + + /** + * Creates a new PredicateList + **/ + PredicateList(); + /** + * Destructor, will delete all Expressions in the list, so remove + * any you may need + **/ + virtual ~PredicateList(); + + /** + * Adds the given Expr to the list + * @param expr the Expr to add to the list + **/ + void add(Expr* expr); + + + void evaluatePredicates(NodeSet* nodes, ContextState* cs); + + /** + * returns true if this predicate list is empty + **/ + MBool isEmpty(); + + /** + * Removes the given Expr from the list + * @param expr the Expr to remove from the list + **/ + Expr* remove(Expr* expr); + + /** + * Returns the String representation of this PredicateList. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this PredicateList. + **/ + virtual void toString(String& dest); + +private: + //-- list of predicates + List predicates; +}; //-- PredicateList + +class LocationStep : public PredicateList, public PatternExpr { + +public: + + // Axis Identifier Types + //-- LF changed from static const short to enum + enum _LocationStepType { + ANCESTOR_AXIS = 0, + ANCESTOR_OR_SELF_AXIS, + ATTRIBUTE_AXIS, + CHILD_AXIS, + DESCENDANT_AXIS, + DESCENDANT_OR_SELF_AXIS, + FOLLOWING_AXIS, + FOLLOWING_SIBLING_AXIS, + NAMESPACE_AXIS, + PARENT_AXIS, + PRECEDING_AXIS, + PRECEDING_SIBLING_AXIS, + SELF_AXIS + }; + + + /** + * Creates a new LocationStep using the default Axis Identifier and no + * NodeExpr (which matches nothing) + **/ + LocationStep(); + + /** + * Creates a new LocationStep using the default Axis Identifier and + * the given NodeExpr + * @param nodeExpr the NodeExpr to use when matching Nodes + **/ + LocationStep(NodeExpr* nodeExpr); + + /** + * Creates a new LocationStep using the given NodeExpr and Axis Identifier + * @param nodeExpr the NodeExpr to use when matching Nodes + * @param axisIdentifier the Axis Identifier in which to search for nodes + **/ + LocationStep(NodeExpr* nodeExpr, short axisIdentifier); + + /** + * Destructor, will delete all predicates and the given NodeExpr + **/ + virtual ~LocationStep(); + + /** + * Sets the Axis Identifier for this LocationStep + * @param axisIdentifier the Axis in which to search for nodes + **/ + void setAxisIdentifier(short axisIdentifier); + + /** + * Sets the NodeExpr of this LocationStep for use when matching nodes + * @param nodeExpr the NodeExpr to use when matching nodes + **/ + void setNodeExpr(NodeExpr* nodeExpr); + + //------------------------------------/ + //- Virtual methods from PatternExpr -/ + //------------------------------------/ + + /** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation + **/ + virtual ExprResult* evaluate(Node* context, ContextState* cs); + + /** + * Returns the default priority of this Pattern based on the given Node, + * context Node, and ContextState. + * If this pattern does not match the given Node under the current context Node and + * ContextState then Negative Infinity is returned. + **/ + virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); + + /** + * Determines whether this PatternExpr matches the given node within + * the given context + **/ + virtual MBool matches(Node* node, Node* context, ContextState* cs); + + /** + * Returns the String representation of this PatternExpr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this PatternExpr. + **/ + virtual void toString(String& dest); + +private: + + NodeExpr* nodeExpr; + short axisIdentifier; + + void fromDescendants(Node* context, ContextState* cs, NodeSet* nodes); + +}; //-- LocationStep + + +class FilterExpr : public PredicateList, public PatternExpr { + +public: + + /** + * Creates a new FilterExpr using the default no default Expr + * (which evaluates to nothing) + **/ + FilterExpr(); + + /** + * Creates a new FilterExpr using the given Expr + * @param expr the Expr to use for evaluation + **/ + FilterExpr(Expr* expr); + + /** + * Destructor, will delete all predicates and the given Expr + **/ + virtual ~FilterExpr(); + + /** + * Sets the Expr of this FilterExpr for evaluation + * @param expr the Expr to use for evaluation + **/ + void setExpr(Expr* expr); + + //------------------------------------/ + //- Virtual methods from PatternExpr -/ + //------------------------------------/ + + /** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation + **/ + virtual ExprResult* evaluate(Node* context, ContextState* cs); + + /** + * Returns the default priority of this Pattern based on the given Node, + * context Node, and ContextState. + * If this pattern does not match the given Node under the current context Node and + * ContextState then Negative Infinity is returned. + **/ + virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); + + /** + * Determines whether this PatternExpr matches the given node within + * the given context + **/ + virtual MBool matches(Node* node, Node* context, ContextState* cs); + + /** + * Returns the String representation of this PatternExpr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this PatternExpr. + **/ + virtual void toString(String& dest); + +private: + + Expr* expr; + +}; //-- FilterExpr + + +class NumberExpr : public Expr { + +public: + + NumberExpr(); + NumberExpr(double dbl); + ~NumberExpr(); + + /** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation + **/ + virtual ExprResult* evaluate(Node* context, ContextState* cs); + + /** + * Returns the String representation of this Expr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this Expr. + **/ + virtual void toString(String& str); + +private: + + NumberResult numberResult; +}; + +/** + * Represents a String expression +**/ +class StringExpr : public Expr { + +public: + + StringExpr(); + StringExpr(String& value); + StringExpr(const String& value); + ~StringExpr(); + + /** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation + **/ + virtual ExprResult* evaluate(Node* context, ContextState* cs); + + /** + * Returns the String representation of this Expr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this Expr. + **/ + virtual void toString(String& str); + +private: + + String value; +}; //-- StringExpr + +/** + * Represents an AdditiveExpr, a binary expression that + * performs an additive operation between it's lvalue and rvalue:
+ * + : add + * - : subtract +**/ +class AdditiveExpr : public Expr { + +public: + + //-- AdditiveExpr Types + //-- LF, changed from static const short to enum + enum _AdditiveExprType { ADDITION = 1, SUBTRACTION }; + + AdditiveExpr(); + AdditiveExpr(Expr* leftExpr, Expr* rightExpr, short op); + ~AdditiveExpr(); + + /** + * Sets the left side of this AdditiveExpr + **/ + void setLeftExpr(Expr* leftExpr); + + /** + * Sets the right side of this AdditiveExpr + **/ + void setRightExpr(Expr* rightExpr); + + + /** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation + **/ + virtual ExprResult* evaluate(Node* context, ContextState* cs); + + /** + * Returns the String representation of this Expr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this Expr. + **/ + virtual void toString(String& str); + + + +private: + short op; + Expr* leftExpr; + Expr* rightExpr; +}; //-- AdditiveExpr + +/** + * Represents a MultiplicativeExpr, a binary expression that + * performs a multiplicative operation between it's lvalue and rvalue:
+ * * : multiply + * mod : modulus + * div : divide + * +**/ +class MultiplicativeExpr : public Expr { + +public: + + //-- MultiplicativeExpr Types + //-- LF, changed from static const short to enum + enum _MultiplicativeExprType { DIVIDE = 1, MULTIPLY, MODULUS }; + + MultiplicativeExpr(); + MultiplicativeExpr(Expr* leftExpr, Expr* rightExpr, short op); + ~MultiplicativeExpr(); + + /** + * Sets the left side of this MultiplicativeExpr + **/ + void setLeftExpr(Expr* leftExpr); + + /** + * Sets the right side of this MultiplicativeExpr + **/ + void setRightExpr(Expr* rightExpr); + + + /** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation + **/ + virtual ExprResult* evaluate(Node* context, ContextState* cs); + + /** + * Returns the String representation of this Expr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this Expr. + **/ + virtual void toString(String& str); + + + +private: + short op; + Expr* leftExpr; + Expr* rightExpr; +}; //-- MultiplicativeExpr + +/** + * Represents a RelationalExpr, an expression that compares it's lvalue + * to it's rvalue using:
+ * = : equal to + * < : less than + * > : greater than + * <= : less than or equal to + * >= : greater than or equal to + * +**/ +class RelationalExpr : public Expr { + +public: + + //-- RelationalExpr Types + //-- LF, changed from static const short to enum + enum _RelationalExprType { + EQUAL = 1, + NOT_EQUAL, + LESS_THAN, + GREATER_THAN, + LESS_OR_EQUAL, + GREATER_OR_EQUAL + }; + + RelationalExpr(); + RelationalExpr(Expr* leftExpr, Expr* rightExpr, short op); + ~RelationalExpr(); + + /** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation + **/ + virtual ExprResult* evaluate(Node* context, ContextState* cs); + + /** + * Returns the String representation of this Expr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this Expr. + **/ + virtual void toString(String& str); + + + +private: + short op; + Expr* leftExpr; + Expr* rightExpr; +}; //-- RelationalExpr + +/** + * VariableRefExpr
+ * Represents a variable reference ($refname) + * @author Keith Visco +**/ +class VariableRefExpr : public Expr { + +public: + + VariableRefExpr(); + VariableRefExpr(const String& name); + VariableRefExpr(String& name); + ~VariableRefExpr(); + + /** + * Sets the name of the variable of reference + **/ + void setName(const String& name); + + /** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation + **/ + virtual ExprResult* evaluate(Node* context, ContextState* cs); + + /** + * Returns the String representation of this Expr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this Expr. + **/ + virtual void toString(String& str); + +private: + String name; + +}; //-- VariableRefExpr + +/** + * Represents a PathExpr + * @author Keith Visco +**/ +class PathExpr : public PatternExpr { + +public: + + //-- Path Operators + //-- RELATIVE_OP is the default + //-- LF, changed from static const short to enum + enum _PathOperator { ANCESTOR_OP=1, PARENT_OP, RELATIVE_OP} ; + + /** + * Creates a new PathExpr + **/ + PathExpr(); + + /** + * Destructor, will delete all Pattern Expressions + **/ + virtual ~PathExpr(); + + /** + * Adds the PatternExpr to this PathExpr + * @param expr the Expr to add to this PathExpr + * @param index the index at which to add the given Expr + **/ + void PathExpr::addPatternExpr(int index, PatternExpr* expr, short ancestryOp); + + /** + * Adds the PatternExpr to this PathExpr + * @param expr the Expr to add to this PathExpr + **/ + void addPatternExpr(PatternExpr* expr, short ancestryOp); + + virtual MBool isAbsolute(); + + //------------------------------------/ + //- Virtual methods from PatternExpr -/ + //------------------------------------/ + + /** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation + **/ + virtual ExprResult* evaluate(Node* context, ContextState* cs); + + /** + * Returns the default priority of this Pattern based on the given Node, + * context Node, and ContextState. + * If this pattern does not match the given Node under the current context Node and + * ContextState then Negative Infinity is returned. + **/ + virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); + + /** + * Determines whether this PatternExpr matches the given node within + * the given context + **/ + virtual MBool matches(Node* node, Node* context, ContextState* cs); + + /** + * Returns the String representation of this PatternExpr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this PatternExpr. + **/ + virtual void toString(String& dest); + +private: + + struct PathExprItem { + PatternExpr* pExpr; + short ancestryOp; + }; + + List expressions; + + /** + * Selects from the descendants of the context node + * all nodes that match the PatternExpr + * -- this will be moving to a Utility class + **/ + void fromDescendants(PatternExpr* pExpr, + Node* context, + ContextState* cs, + NodeSet* nodes); + +}; //-- PathExpr + +/** + * This class represents a RootExpr, which only matches the Document node + * @author Keith Visco + *
This class was ported from XSL:P, an open source Java based XSL processor +**/ +class RootExpr : public PathExpr { + +public: + + //------------------/ + //- Public Methods -/ + //------------------/ + + /** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation + **/ + virtual ExprResult* evaluate(Node* context, ContextState* cs); + + virtual MBool isAbsolute(); + + /** + * Returns the default priority of this Pattern based on the given Node, + * context Node, and ContextState. + * If this pattern does not match the given Node under the current context Node and + * ContextState then Negative Infinity is returned. + **/ + virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); + + /** + * Determines whether this NodeExpr matches the given node within + * the given context + **/ + virtual MBool matches(Node* node, Node* context, ContextState* cs); + + /** + * Returns the String representation of this PatternExpr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this PatternExpr. + **/ + virtual void toString(String& dest); + + +}; //-- RootExpr + +/** + * Represents a UnionExpr + * @author Keith Visco +**/ +class UnionExpr : public PatternExpr { + +public: + + /** + * Creates a new UnionExpr + **/ + UnionExpr(); + + /** + * Destructor, will delete all Path Expressions + **/ + virtual ~UnionExpr(); + + /** + * Adds the PathExpr to this UnionExpr + * @param expr the Expr to add to this UnionExpr + **/ + void addPathExpr(PathExpr* expr); + + /** + * Adds the PathExpr to this UnionExpr at the specified index + * @param expr the Expr to add to this UnionExpr + **/ + void addPathExpr(int index, PathExpr* expr); + + //------------------------------------/ + //- Virtual methods from PatternExpr -/ + //------------------------------------/ + + /** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation + **/ + virtual ExprResult* evaluate(Node* context, ContextState* cs); + + /** + * Returns the default priority of this Pattern based on the given Node, + * context Node, and ContextState. + * If this pattern does not match the given Node under the current context Node and + * ContextState then Negative Infinity is returned. + **/ + virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs); + + /** + * Determines whether this PatternExpr matches the given node within + * the given context + **/ + virtual MBool matches(Node* node, Node* context, ContextState* cs); + + /** + * Returns the String representation of this PatternExpr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this PatternExpr. + **/ + virtual void toString(String& dest); + +private: + + List expressions; + +}; //-- UnionExpr + +/* */ +#endif + + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/ExprLexer.cpp b/mozilla/extensions/transformiix/source/xsl/expr/ExprLexer.cpp new file mode 100644 index 00000000000..2cf8da1ac06 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/ExprLexer.cpp @@ -0,0 +1,645 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * Lexical analyzer for XPath expressions + * @author Keith Visco +**/ + +#include +#include "ExprLexer.h" + + //---------------------------/ + //- Implementation of Token -/ +//---------------------------/ + + +/** + * Default constructor for Token +**/ +Token::Token() { + this->type =0; +} //-- Token; + +/** + * Constructor for Token + * @param type, the type of Token being represented +**/ +Token::Token(short type) { + this->type = type; +} //-- Token; + +/** + * Constructor for Token + * @param value the value of this Token + * @param type, the type of Token being represented +**/ +Token::Token(const String& value, short type) { + this->type = type; + //-- make copy of value String + this->value = value; +} //-- Token + +Token::Token(UNICODE_CHAR uniChar, short type) { + this->type = type; + this->value.append(uniChar); +} //-- Token + +/** + * Copy Constructor +**/ +Token::Token(const Token& token) { + this->type = token.type; + this->value = token.value; +} //-- Token + +/** + * Destructor for Token +**/ +Token::~Token() { + //-- currently nothing is needed +} //-- ~Token + + + //--------------------------------/ + //- Implementation of ExprLexer -/ +//-------------------------------/ + +/* + * Complex Tokens +*/ +//-- Nodetype tokens +const String ExprLexer::COMMENT = "comment"; +const String ExprLexer::NODE = "node"; +const String ExprLexer::PI = "processing-instruction"; +const String ExprLexer::TEXT = "text"; + +//-- multiplicative operators +const String ExprLexer::MODULUS = "mod"; +const String ExprLexer::DIVIDE = "div"; + +/** + * The set of a XSL Expression Tokens +**/ +const Token ExprLexer::TOKENS[] = { + + //-- Nodetype tokens + Token(ExprLexer::COMMENT, Token::COMMENT), + Token(ExprLexer::NODE, Token::NODE), + Token(ExprLexer::PI, Token::PI), + Token(ExprLexer::TEXT, Token::TEXT), + //-- multiplicative operators + Token(ExprLexer::MODULUS, Token::MODULUS_OP), + Token(ExprLexer::DIVIDE, Token::DIVIDE_OP) +}; + +const short ExprLexer::NUMBER_OF_TOKENS = 6; + + //---------------/ + //- Contructors -/ +//---------------/ + +/** + * Creates a new ExprLexer using the given String +**/ +ExprLexer::ExprLexer(const String& pattern) { + + firstItem = 0; + lastItem = 0; + tokenCount = 0; + prevToken = 0; + parse(pattern); + currentItem = firstItem; +} //-- ExprLexer + +/** + * Destroys this instance of an ExprLexer +**/ +ExprLexer::~ExprLexer() { + //-- delete tokens + + //cout << "~ExprLexer() - start"<next; + //cout << "deleting token: " << currentItem->token->value << endl; + delete currentItem->token; + delete currentItem; + currentItem = temp; + } + //cout << "~ExprLexer() - done"<next; + } + return c; +} //-- countRemainingTokens + + +MBool ExprLexer::hasMoreTokens() { + return (MBool) ( currentItem ); +} //-- hasMoreTokens + +Token* ExprLexer::nextToken() { + if ( currentItem ) { + Token* token = currentItem->token; + currentItem = currentItem->next; + return token; + } + return 0; +} //-- nextToken + +void ExprLexer::pushBack() { + if ( !currentItem ) { + currentItem = lastItem; + } + else currentItem = currentItem->previous; +} //-- pushBack + +/* +Token* ExprLexer::lastToken() { + if (lastItem) { + return lastItem->token; + } + return 0; +} //-- lastToken +*/ + +Token* ExprLexer::peek() { + Token* token = 0; + TokenListItem* tlItem = currentItem; + if (tlItem) token = tlItem->token; + return token; +} //-- peek + +Token* ExprLexer::lookAhead(int offset) { + Token* token = 0; + TokenListItem* tlItem = currentItem; + //-- advance to proper offset + for ( int i = 0; i < offset; i++ ) + if ( tlItem ) tlItem = currentItem->next; + + if (tlItem) token = tlItem->token; + return token; +} //-- lookAhead + +void ExprLexer::addToken(Token* token) { + TokenListItem* tlItem = new TokenListItem; + tlItem->token = token; + tlItem->next = 0; + if (lastItem) { + tlItem->previous = lastItem; + lastItem->next = tlItem; + } + if (!firstItem) firstItem = tlItem; + lastItem = tlItem; + prevToken = token; + ++tokenCount; +} //-- addToken + +/** + * Returns true if the given character represents an Alpha letter +**/ +MBool ExprLexer::isAlphaChar(Int32 ch) { + if ((ch >= 'a' ) && (ch <= 'z' )) return MB_TRUE; + if ((ch >= 'A' ) && (ch <= 'Z' )) return MB_TRUE; + return MB_FALSE; +} //-- isAlphaChar + +/** + * Returns true if the given character represents a numeric letter (digit) +**/ +MBool ExprLexer::isDigit(Int32 ch) { + if ((ch >= '0') && (ch <= '9')) return MB_TRUE; + return MB_FALSE; +} //-- isDigit + +/** + * Returns true if the given character is an allowable QName character +**/ +MBool ExprLexer::isNCNameChar(Int32 ch) { + if (isDigit(ch) || isAlphaChar(ch)) return MB_TRUE; + return (MBool) ((ch == '.') ||(ch == '_') || (ch == '-')); +} //-- isNCNameChar + +/** + * Returns true if the given character is an allowable NCName character +**/ +MBool ExprLexer::isQNameChar(Int32 ch) { + return (MBool) (( ch == ':') || isNCNameChar(ch)); +} //-- isQNameChar + +/** + * Returns true if the given String is a valid XML QName +**/ +MBool ExprLexer::isValidQName(String& name) { + + int size = name.length(); + if ( size == 0 ) return MB_FALSE; + else if ( !isAlphaChar(name.charAt(0))) return MB_FALSE; + else { + for ( int i = 1; i < size; i++) { + if ( ! isQNameChar(name.charAt(i))) return MB_FALSE; + } + } + return MB_TRUE; +} //-- isValidQName + +MBool ExprLexer::isOperatorToken(Token* token) { + if ( !token ) return MB_FALSE; + switch ( token->type ) { + //-- relational operators + case Token::EQUAL_OP: + case Token::NOT_EQUAL_OP: + case Token::LESS_THAN_OP: + case Token::GREATER_THAN_OP: + case Token::LESS_OR_EQUAL_OP: + case Token::GREATER_OR_EQUAL_OP: + //-- additive operators + case Token::ADDITION_OP: + case Token::SUBTRACTION_OP: + //-- multiplicative operators + case Token::DIVIDE_OP: + case Token::MODULUS_OP: + case Token::MULTIPLY_OP: + return MB_TRUE; + default: + break; + } + + return MB_FALSE; +} //-- isOperatorToken + +MBool ExprLexer::matchDelimiter(UNICODE_CHAR ch) { + + short tokenType = 0; + MBool addChar = MB_TRUE; + switch (ch) { + case FORWARD_SLASH : + tokenType = Token::PARENT_OP; + break; + case L_PAREN : + tokenType = Token::L_PAREN; + break; + case R_PAREN : + tokenType = Token::R_PAREN; + break; + case L_BRACKET : + tokenType = Token::L_BRACKET; + break; + case R_BRACKET : + tokenType = Token::R_BRACKET; + break; + case COMMA : + tokenType = Token::COMMA; + break; + case PERIOD : + tokenType = Token::SELF_NODE; + break; + case EQUAL : + tokenType = Token::EQUAL_OP; + break; + case PLUS : + tokenType = Token::ADDITION_OP; + break; + case HYPHEN : + tokenType = Token::SUBTRACTION_OP; + break; + case VERT_BAR: + tokenType = Token::UNION_OP; + break; + case ASTERIX: + tokenType = Token::WILD_CARD; + break; + case AT_SIGN: + tokenType = Token::AT_SIGN; + break; + case DOLLAR_SIGN: + tokenType = Token::VAR_REFERENCE; + addChar = MB_FALSE; + break; + default: + return MB_FALSE;; + } + Token* token = 0; + if ( addChar ) token = new Token(ch, tokenType); + else token = new Token(tokenType); + + addToken(token); + return MB_TRUE; +} //-- matchDelimiter + +/** + * Returns true if the value of the given String matches + * an OperatorName +**/ +MBool ExprLexer::matchesOperator(String& buffer) { + + int index = 0; + while (index < NUMBER_OF_TOKENS) { + Token tok = TOKENS[index++]; + if ( tok.value.isEqual(buffer) ) { + if (isOperatorToken( &tok )) return MB_TRUE; + } + } + return MB_FALSE; + +} //-- matchesOperator + +/** + * Matches the given String to the appropriate Token + * @param buffer the current StringBuffer representing the value of the Token + * @param ch, the current delimiter token +**/ +void ExprLexer::matchToken(String& buffer, UNICODE_CHAR ch) { + + if ( buffer.length() == 0) return; + + Token* match = new Token(); + MBool foundMatch = MB_FALSE; + int index = 0; + + //-- check previous token + switch(prevToken->type) { + case Token::VAR_REFERENCE : + if ( prevToken->value.length() == 0) { + prevToken->value.append(buffer); + buffer.clear(); + return; + } + break; + default: + break; + } + + //-- look for next match + while ( !foundMatch && (index < NUMBER_OF_TOKENS) ) { + + Token tok = TOKENS[index++]; + + if ( tok.value.isEqual(buffer) ) { + + foundMatch = MB_TRUE; + + switch (tok.type) { + + //-- NodeType tokens + case Token::COMMENT: + case Token::NODE : + case Token::PI : + case Token::TEXT : + // make sure next delimiter is '(' + if ( ch == L_PAREN) { + //-- copy buffer + match->value = buffer; + //-- copy type + match->type = tok.type; + } + break; + case Token::MULTIPLY_OP : + case Token::DIVIDE_OP: + case Token::MODULUS_OP: + switch ( prevToken->type ) { + case Token::AT_SIGN : + case Token::NULL_TOKEN: + case Token::L_PAREN: + case Token::L_BRACKET: + foundMatch = MB_FALSE; + break; //-- do not match + default: + if ( isOperatorToken(prevToken) ) { + foundMatch = MB_FALSE; + break; //-- do not match + } + match->value = buffer; + match->type = tok.type; + } + break; + default : + //-- copy buffer + match->value = buffer; + match->type = tok.type; + break; + } + } //-- if equal + } //-- while + + if (!foundMatch) { + //-- copy buffer + match->value = buffer; + //-- look for function name + if ( ch == L_PAREN) match->type = Token::FUNCTION_NAME; + else match->type = Token::CNAME; + } + addToken(match); + buffer.clear(); +} //-- matchToken + +/** + * Parses the given String into the set of Tokens +**/ +void ExprLexer::parse(const String& pattern) { + + + String tokenBuffer; + MBool inLiteral = MB_FALSE; + MBool inNumber = MB_FALSE; + + Int32 currentPos = 0; + + UNICODE_CHAR ch = '\0'; + UNICODE_CHAR prevCh = ch; + + //-- initialize previous token, this will automatically get + //-- deleted when it goes out of scope + Token nullToken('\0', Token::NULL_TOKEN); + + prevToken = &nullToken; + + while (currentPos < pattern.length()) { + + prevCh = ch; + ch = pattern.charAt(currentPos); + + if ( inLiteral ) { + //-- look for end of literal + if ( ch == S_QUOTE ) { + inLiteral = MB_FALSE; + addToken(new Token(tokenBuffer, Token::LITERAL)); + tokenBuffer.clear(); + } + else { + tokenBuffer.append(ch); + } + } + else if ( inNumber ) { + if (isDigit(ch) || (ch == '.')) { + tokenBuffer.append(ch); + } + else { + inNumber = MB_FALSE; + addToken(new Token(tokenBuffer, Token::NUMBER)); + tokenBuffer.clear(); + //-- push back last char + --currentPos; + } + } + else if (isDigit(ch)) { + if ((tokenBuffer.length() == 0 ) || matchesOperator(tokenBuffer) ) { + //-- match operator and free up token buffer + matchToken(tokenBuffer, ch); + inNumber = MB_TRUE; + } + else if (( tokenBuffer.length() == 1 ) && (prevCh = '-')) { + inNumber = MB_TRUE; + } + tokenBuffer.append(ch); + } + else { + switch (ch) { + //-- ignore whitespace + case SPACE: + case TAB: + case CR: + case LF: + break; + case S_QUOTE : + matchToken(tokenBuffer, ch); + inLiteral = MB_TRUE; + break; + case PERIOD: + if ( inNumber ) tokenBuffer.append(ch); + else if ( prevToken->type == Token::SELF_NODE ) { + prevToken->type = Token::PARENT_NODE; + } + else matchDelimiter(ch); + break; + case COLON: + if ( prevCh == ch) { + Int32 bufSize = tokenBuffer.length(); + tokenBuffer.setLength(bufSize-1); + addToken(new Token(tokenBuffer, Token::AXIS_IDENTIFIER)); + tokenBuffer.clear(); + } + else tokenBuffer.append(ch); + break; + case FORWARD_SLASH : + matchToken(tokenBuffer, ch); + if ( prevToken->type == Token::PARENT_OP ) { + prevToken->type = Token::ANCESTOR_OP; + prevToken->value.append(ch); + } + else matchDelimiter(ch); + break; + case BANG : //-- used as previous...see EQUAL + break; + case EQUAL: + matchToken(tokenBuffer, ch); + matchDelimiter(ch); + if ( prevCh == BANG ) { + prevToken->type = Token::NOT_EQUAL_OP; + } + break; + case HYPHEN : + if ( isValidQName(tokenBuffer) ) tokenBuffer.append(ch); + else { + switch ( prevToken->type ) { + case Token::NULL_TOKEN: + case Token::L_PAREN: + case Token::L_BRACKET: + case Token::COMMA: + inNumber = MB_TRUE; + tokenBuffer.append(ch); + break; + default: + matchToken(tokenBuffer, ch); + matchDelimiter(ch); + break; + } + } + break; + case ASTERIX: + matchToken(tokenBuffer, ch); + switch ( prevToken->type ) { + case Token::AT_SIGN : + case Token::NULL_TOKEN: + case Token::L_PAREN: + case Token::L_BRACKET: + matchDelimiter(ch); + break; + default: + if ( isOperatorToken(prevToken) ) { + matchDelimiter(ch); + break; //-- do not match + } + addToken( new Token(ch, Token::MULTIPLY_OP) ); + } + break; + case L_PAREN: + case R_PAREN: + case L_BRACKET: + case R_BRACKET: + case COMMA: + case AT_SIGN : + case PLUS: + case DOLLAR_SIGN : + case VERT_BAR: + matchToken(tokenBuffer, ch); + matchDelimiter(ch); + break; + default: + switch (prevCh) { + case SPACE : + case TAB : + case CR : + case LF : + matchToken(tokenBuffer, ch); + tokenBuffer.append(ch); + break; + default: + tokenBuffer.append(ch); + break; + } + break; + } + } + ++currentPos; + } + //-- end lexical parsing of current token + //-- freeBuffer if needed + + if ( inNumber ) { + addToken(new Token(tokenBuffer, Token::NUMBER)); + } + else matchToken(tokenBuffer, ch); + prevToken = 0; +} //-- parse + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/ExprLexer.h b/mozilla/extensions/transformiix/source/xsl/expr/ExprLexer.h new file mode 100644 index 00000000000..c75119467cb --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/ExprLexer.h @@ -0,0 +1,274 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + + +#ifndef MITREXSL_EXPRLEXER_H +#define MITREXSL_EXPRLEXER_H + +#include "String.h" +#include "baseutils.h" +#include + +/** + * A Token class for the ExprLexer. + *
This class was ported from XSL:P, an open source Java based XSL processor + * @author Keith Visco + *
+ *
+ * Modifications:
+ * 19990806: Larry Fitzpatrick
+ *   - changed constant short declarations in Token and ExprLexer to
+ *     enumerations, commented with //--LF
+ * 
+ * +**/ +class Token { + +public: + + //---------------/ + //- Token Types -/ + //---------------/ + + //-- LF - changed from static const short declarations to enum + //-- token types + enum _TokenTypes { + //-- Trivial Tokens + ERROR = 0, + NULL_TOKEN, + LITERAL, + NUMBER, + CNAME, + L_PAREN, + R_PAREN, + L_BRACKET, + R_BRACKET, + COMMA, + FUNCTION_NAME, + WILD_CARD, + AT_SIGN, + VAR_REFERENCE, + PARENT_NODE, + SELF_NODE, + AXIS_IDENTIFIER, + //-------------/ + //- operators -/ + //-------------/ + //-- relational + EQUAL_OP, + NOT_EQUAL_OP, + LESS_THAN_OP, + GREATER_THAN_OP, + LESS_OR_EQUAL_OP, + GREATER_OR_EQUAL_OP, + //-- additive operators + ADDITION_OP, + SUBTRACTION_OP, + //-- multiplicative + DIVIDE_OP , + MULTIPLY_OP, + MODULUS_OP, + //-- path operators + PARENT_OP, + ANCESTOR_OP, + UNION_OP, + //-- node type tokens + COMMENT, + NODE, + PI, + TEXT + }; + + + /** + * Default Constructor + **/ + Token(); + Token(short type); + Token(const String& value, short type); + Token(UNICODE_CHAR uniChar, short type); + /** + * Copy Constructor + **/ + Token(const Token& token); + + ~Token(); + String value; + short type; +}; //--Token + +/** + * A class for splitting an "Expr" String into tokens and + * performing basic Lexical Analysis. + * + *
This class was ported from XSL:P, an open source Java based XSL processor + * @author Keith Visco +**/ +class ExprLexer { + + +public: + + /* + * Trivial Tokens + */ + //-- LF, changed to enum + enum _TrivialTokens { + S_QUOTE = '\'', + L_PAREN = '(', + R_PAREN = ')', + L_BRACKET = '[', + R_BRACKET = ']', + COMMA = ',', + PERIOD = '.', + ASTERIX = '*', + FORWARD_SLASH = '/', + EQUAL = '=', + BANG = '!', + VERT_BAR = '|', + AT_SIGN = '@', + DOLLAR_SIGN = '$', + PLUS = '+', + HYPHEN = '-', + COLON = ':', + //-- whitespace tokens + SPACE = ' ', + TAB = '\t', + CR = '\n', + LF = '\r' + }; + + + /* + * Complex Tokens + */ + //-- Nodetype tokens + static const String COMMENT; + static const String NODE; + static const String PI; + static const String TEXT; + + //-- Multiplicative + static const String MODULUS; + static const String DIVIDE; + + /* + * Default Token Set + */ + static const Token TOKENS[]; + static const short NUMBER_OF_TOKENS; + + /** + * Constructor for ExprLexer + **/ + ExprLexer(const String& pattern); + + ~ExprLexer(); + + /** + * Counts the total number of tokens in this Lexer, even if the token + * has already been seen + * @return the total number of tokens in this Lexer + **/ + int countAllTokens(); + + /** + * Counts the remaining number of tokens in this Lexer + * @return the number of remaining tokens in this Lexer + **/ + int countRemainingTokens(); + + /** + * Returns the type of token that was last return by a call to nextToken + **/ + + Token* lookAhead(int offset); + Token* nextToken(); + Token* peek(); + void pushBack(); + MBool hasMoreTokens(); + + MBool isOperatorToken(Token* token); + +private: + + struct TokenListItem { + Token* token; + TokenListItem* next; + TokenListItem* previous; + }; + + TokenListItem* currentItem; + TokenListItem* firstItem; + TokenListItem* lastItem; + + int tokenCount; + + Token* prevToken; + + void addToken(Token* token); + + /** + * Returns true if the given character represents an Alpha letter + **/ + static MBool isAlphaChar(Int32 ch); + + /** + * Returns true if the given character represents a numeric letter (digit) + **/ + static MBool isDigit(Int32 ch); + + /** + * Returns true if the given character is an allowable QName character + **/ + static MBool isQNameChar(Int32 ch); + + /** + * Returns true if the given character is an allowable NCName character + **/ + static MBool isNCNameChar(Int32 ch); + + /** + * Returns true if the given String is a valid XML QName + **/ + static MBool isValidQName(String& name); + + MBool matchDelimiter(UNICODE_CHAR ch); + + /** + * Returns true if the value of the given String matches + * an OperatorName + **/ + MBool matchesOperator(String& buffer); + + /** + * Matches the given String to the appropriate Token + * @param buffer the current StringBuffer representing the value of the Token + * @param ch, the current delimiter token + **/ + void matchToken(String& buffer, UNICODE_CHAR ch); + + + void parse(const String& pattern); + +}; //-- ExprLexer + +#endif diff --git a/mozilla/extensions/transformiix/source/xsl/expr/ExprParser.cpp b/mozilla/extensions/transformiix/source/xsl/expr/ExprParser.cpp new file mode 100644 index 00000000000..8d69f23f0a1 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/ExprParser.cpp @@ -0,0 +1,793 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * ExprParser + * This class is used to parse XSL Expressions + * @author Keith Visco + * @see ExprLexer +**/ + +#include "ExprParser.h" + +const String ExprParser::L_CURLY_BRACE = "{"; +const String ExprParser::R_CURLY_BRACE = "}"; + +/** + * Creates a new ExprParser +**/ +ExprParser::ExprParser() {}; + +/** + * Default Destructor +**/ +ExprParser::~ExprParser() {}; + +/** + * Creates an Attribute Value Template using the given value +**/ +AttributeValueTemplate* ExprParser::createAttributeValueTemplate + (const String& attValue) +{ + + AttributeValueTemplate* avt = new AttributeValueTemplate(); + Int32 size = attValue.length(); + char* chars = new char[size+1]; + attValue.toChar(chars); + int cc = 0; + String buffer; + MBool inExpr = MB_FALSE; + MBool inLiteral = MB_FALSE; + char endLiteral = '"'; + char prevCh = '\0'; + + while ( cc < size) { + char ch = chars[cc++]; + // if in literal just add ch to buffer + if ( inLiteral && (ch != endLiteral) ) { + buffer.append(ch); + prevCh = ch; + continue; + } + switch ( ch ) { + case '\'' : + case '"' : + buffer.append(ch); + if (inLiteral) inLiteral = MB_FALSE; + else { + inLiteral = MB_TRUE; + endLiteral = ch; + } + break; + case '{' : + // Ignore case where we find two { without a } + if (!inExpr) { + //-- clear buffer + if ( buffer.length() > 0) { + avt->addExpr(new StringExpr(buffer)); + buffer.clear(); + } + inExpr = MB_TRUE; + } + else if (prevCh == ch) { + inExpr = MB_FALSE; + buffer.append(ch); + } + else { + buffer.append(ch); //-- simply append '{' + ch = '\0'; + } + break; + case '}': + if (inExpr) { + inExpr = MB_FALSE; + avt->addExpr(createExpr(buffer)); + buffer.clear(); + //-- change in case another '}' follows + ch = '\0'; + } + else if (prevCh != ch) { + if ( buffer.length() > 0) buffer.append('}'); + else avt->addExpr(new StringExpr(R_CURLY_BRACE)); + } + break; + default: + buffer.append(ch); + break; + } + prevCh = ch; + } + if ( buffer.length() > 0) { + if ( inExpr ) { + //-- error + String errMsg("#error evaluating AttributeValueTemplate. "); + errMsg.append("Missing '}' after: "); + errMsg.append(buffer); + avt->addExpr(new StringExpr(errMsg)); + } + else avt->addExpr(new StringExpr(buffer)); + } + + //-- cleanup + delete chars; + + return avt; + +} //-- createAttributeValueTemplate + +Expr* ExprParser::createExpr(const String& pattern) { + ExprLexer lexer(pattern); + return createExpr(lexer); +} //-- createExpr + +PatternExpr* ExprParser::createPatternExpr(const String& pattern) { + ExprLexer lexer(pattern); + return createUnionExpr(lexer); +} //-- createPatternExpr + +LocationStep* ExprParser::createLocationStep(const String& path) { + ExprLexer lexer(path); + LocationStep* lstep = createLocationStep(lexer); + return lstep; +} //-- createLocationPath + + //--------------------/ + //- Private Methods -/ +//-------------------/ + +/** + * Creates a binary Expr for the given operator +**/ +Expr* ExprParser::createBinaryExpr (Expr* left, Expr* right, Token* op) { + if ( !op ) return 0; + switch(op->type) { + case Token::ADDITION_OP : + return new AdditiveExpr(left, right, AdditiveExpr::ADDITION); + case Token::DIVIDE_OP : + return new MultiplicativeExpr(left, right, MultiplicativeExpr::DIVIDE); + case Token::EQUAL_OP : + return new RelationalExpr(left, right, RelationalExpr::EQUAL); + case Token::MODULUS_OP : + return new MultiplicativeExpr(left, right, MultiplicativeExpr::MODULUS); + case Token::MULTIPLY_OP : + return new MultiplicativeExpr(left, right, MultiplicativeExpr::MULTIPLY); + case Token::SUBTRACTION_OP: + return new AdditiveExpr(left, right, AdditiveExpr::SUBTRACTION); + default: + break; + + } + return 0; + //return new ErrorExpr(); +} //-- createBinaryExpr + + +Expr* ExprParser::createExpr(ExprLexer& lexer) { + + MBool done = MB_FALSE; + + Expr* expr = 0; + + while ( lexer.hasMoreTokens() && (!done)) { + + Token* tok = lexer.nextToken(); + switch ( tok->type ) { + case Token::R_BRACKET: + case Token::R_PAREN: + case Token::COMMA : + lexer.pushBack(); + done = MB_TRUE; + break; + case Token::L_PAREN: //-- Grouping Expression + expr = createExpr(lexer); + //-- look for end ')' + if ( lexer.hasMoreTokens() && + ( lexer.nextToken()->type == Token::R_PAREN ) ) break; + else { + //-- error + delete expr; + expr = new StringExpr("missing ')' in expression"); + } + break; + case Token::ANCESTOR_OP: + case Token::PARENT_OP: + lexer.pushBack(); + if ( !expr ) expr = createPathExpr(lexer); + else { + PathExpr* pathExpr = createPathExpr(lexer); + pathExpr->addPatternExpr(0, (PatternExpr*)expr, + PathExpr::RELATIVE_OP); + expr = pathExpr; + } + done = MB_TRUE; + break; + case Token::UNION_OP : + { + UnionExpr* unionExpr = createUnionExpr(lexer); + unionExpr->addPathExpr(0, (PathExpr*)expr ); + expr = unionExpr; + done = MB_TRUE; + break; + } + case Token::LITERAL : + expr = new StringExpr(tok->value); + break; + case Token::NUMBER: + { + StringResult str(tok->value); + expr = new NumberExpr(str.numberValue()); + break; + } + case Token::FUNCTION_NAME: + { + lexer.pushBack(); + expr = createFunctionCall(lexer); + break; + } + case Token::VAR_REFERENCE: + expr = new VariableRefExpr(tok->value); + break; + case Token::ADDITION_OP: + case Token::DIVIDE_OP: + case Token::EQUAL_OP: + case Token::MODULUS_OP: + case Token::MULTIPLY_OP: + case Token::SUBTRACTION_OP: + { + Expr* left = expr; + Expr* right = createExpr(lexer); + expr = createBinaryExpr(left, right, tok); + break; + } + default: + lexer.pushBack(); + expr = createPatternExpr(lexer); + break; + } + } + return expr; + +} //-- createExpr + +FilterExpr* ExprParser::createFilterExpr(ExprLexer& lexer) { + + FilterExpr* filterExpr = new FilterExpr(); + Token* tok = lexer.nextToken(); + if ( !tok ) return filterExpr; + + Expr* expr = 0; + switch ( tok->type ) { + case Token::FUNCTION_NAME : + expr = createFunctionCall(lexer); + filterExpr->setExpr(expr); + break; + case Token::VAR_REFERENCE : + expr = new VariableRefExpr(tok->value); + filterExpr->setExpr(expr); + break; + case Token::L_PAREN: + //-- primary group expr: + expr = createExpr(lexer); + tok = lexer.nextToken(); + if ( (!tok) || (tok->type != Token::R_PAREN ) ) { + String errMsg("error: "); + expr->toString(errMsg); + errMsg.append(" - missing ')'"); + delete expr; //-- free up current expr + expr = new ErrorFunctionCall(errMsg); + } + filterExpr->setExpr(expr); + break; + case Token::PARENT_NODE : + expr = new ParentExpr(); + filterExpr->setExpr(expr); + break; + case Token::SELF_NODE : + expr = new IdentityExpr(); + filterExpr->setExpr(expr); + break; + default: + break; + } + + //-- handle predicates + + return filterExpr; + +} //-- createFilterExpr + +FunctionCall* ExprParser::createFunctionCall(ExprLexer& lexer) { + + if ( !lexer.hasMoreTokens() ) { + //-- should never see this, I hope + return new ErrorFunctionCall("no tokens, invalid function call"); + } + + FunctionCall* fnCall = 0; + + Token* tok = lexer.nextToken(); + + if ( tok->type != Token::FUNCTION_NAME ) { + return new ErrorFunctionCall("invalid function call"); + } + + String fnName = tok->value; + + //-- compare function names + //-- * we should hash these names for speed + + if ( BOOLEAN_FN.isEqual(tok->value) ) { + fnCall = new BooleanFunctionCall(BooleanFunctionCall::BOOLEAN); + } + else if ( CONCAT_FN.isEqual(tok->value) ) { + fnCall = new StringFunctionCall(StringFunctionCall::CONCAT); + } + else if ( CONTAINS_FN.isEqual(tok->value) ) { + fnCall = new StringFunctionCall(StringFunctionCall::CONTAINS); + } + else if ( COUNT_FN.isEqual(tok->value) ) { + fnCall = new NodeSetFunctionCall(NodeSetFunctionCall::COUNT); + } + else if ( FALSE_FN.isEqual(tok->value) ) { + fnCall = new BooleanFunctionCall(); + } + else if ( LAST_FN.isEqual(tok->value) ) { + fnCall = new NodeSetFunctionCall(NodeSetFunctionCall::LAST); + } + else if ( LOCAL_PART_FN.isEqual(tok->value) ) { + fnCall = new NodeSetFunctionCall(NodeSetFunctionCall::LOCAL_PART); + } + else if ( NAME_FN.isEqual(tok->value) ) { + fnCall = new NodeSetFunctionCall(NodeSetFunctionCall::NAME); + } + else if ( NAMESPACE_FN.isEqual(tok->value) ) { + fnCall = new NodeSetFunctionCall(NodeSetFunctionCall::NAMESPACE); + } + else if ( NOT_FN.isEqual(tok->value) ) { + fnCall = new BooleanFunctionCall(BooleanFunctionCall::NOT); + } + else if ( POSITION_FN.isEqual(tok->value) ) { + fnCall = new NodeSetFunctionCall(NodeSetFunctionCall::POSITION); + } + else if ( STARTS_WITH_FN.isEqual(tok->value) ) { + fnCall = new StringFunctionCall(StringFunctionCall::STARTS_WITH); + } + else if ( STRING_FN.isEqual(tok->value) ) { + fnCall = new StringFunctionCall(StringFunctionCall::STRING); + } + else if ( STRING_LENGTH_FN.isEqual(tok->value) ) { + fnCall = new StringFunctionCall(StringFunctionCall::STRING_LENGTH); + } + else if ( SUBSTRING_FN.isEqual(tok->value) ) { + fnCall = new StringFunctionCall(StringFunctionCall::SUBSTRING); + } + else if ( SUBSTRING_AFTER_FN.isEqual(tok->value) ) { + fnCall = new StringFunctionCall(StringFunctionCall::SUBSTRING_AFTER); + } + else if ( SUBSTRING_BEFORE_FN.isEqual(tok->value) ) { + fnCall = new StringFunctionCall(StringFunctionCall::SUBSTRING_BEFORE); + } + else if ( TRANSLATE_FN.isEqual(tok->value) ) { + fnCall = new StringFunctionCall(StringFunctionCall::TRANSLATE); + } + else if ( TRUE_FN.isEqual(tok->value) ) { + fnCall = new BooleanFunctionCall(BooleanFunctionCall::TRUE); + } + else { + //-- create error function() for now, should be ext function + String err = "not a valid function: "; + err.append(tok->value); + fnCall = new ErrorFunctionCall(err); + } + //-- handle parametes + List params; + String* errMsg = parseParameters(¶ms, lexer); + if (errMsg) { + String err("error with function call, \""); + err.append(fnName); + err.append("\" : "); + err.append(*errMsg); + fnCall = new ErrorFunctionCall(err); + delete errMsg; + } + // copy params + else if (params.getLength() > 0) { + ListIterator* iter = params.iterator(); + while ( iter->hasNext() ) fnCall->addParam( (Expr*)iter->next() ); + delete iter; + } + return fnCall; +} //-- createFunctionCall + +LocationStep* ExprParser::createLocationStep(ExprLexer& lexer) { + + LocationStep* lstep = new LocationStep(); + short axisIdentifier = LocationStep::CHILD_AXIS; + + //-- get Axis Identifier, if present + Token* tok = lexer.peek(); + MBool setDefaultAxis = MB_TRUE; + if ( tok->type == Token::AXIS_IDENTIFIER ) { + //-- eat token + lexer.nextToken(); + setDefaultAxis = MB_FALSE; + + //-- should switch to a hash here for speed if necessary + if ( ANCESTOR_AXIS.isEqual(tok->value) ) + axisIdentifier = LocationStep::ANCESTOR_AXIS; + else if ( ANCESTOR_OR_SELF_AXIS.isEqual(tok->value) ) + axisIdentifier = LocationStep::ANCESTOR_OR_SELF_AXIS; + else if ( ATTRIBUTE_AXIS.isEqual(tok->value) ) + axisIdentifier = LocationStep::ATTRIBUTE_AXIS; + else if ( CHILD_AXIS.isEqual(tok->value) ) + axisIdentifier = LocationStep::CHILD_AXIS; + else if ( DESCENDANT_AXIS.isEqual(tok->value) ) + axisIdentifier = LocationStep::DESCENDANT_AXIS; + else if ( DESCENDANT_OR_SELF_AXIS.isEqual(tok->value) ) + axisIdentifier = LocationStep::DESCENDANT_OR_SELF_AXIS; + else if ( FOLLOWING_AXIS.isEqual(tok->value) ) + axisIdentifier = LocationStep::FOLLOWING_AXIS; + else if ( FOLLOWING_SIBLING_AXIS.isEqual(tok->value) ) + axisIdentifier = LocationStep::FOLLOWING_SIBLING_AXIS; + else if ( NAMESPACE_AXIS.isEqual(tok->value) ) + axisIdentifier = LocationStep::NAMESPACE_AXIS; + else if ( PARENT_AXIS.isEqual(tok->value) ) + axisIdentifier = LocationStep::PARENT_AXIS; + else if ( PRECEDING_AXIS.isEqual(tok->value) ) + axisIdentifier = LocationStep::PRECEDING_AXIS; + else if ( PRECEDING_SIBLING_AXIS.isEqual(tok->value) ) + axisIdentifier = LocationStep::PRECEDING_SIBLING_AXIS; + else if ( SELF_AXIS.isEqual(tok->value) ) + axisIdentifier = LocationStep::SELF_AXIS; + //-- child axis is default + else { + //-- handle error gracefully, simply ignore invalid axis and + //-- use default. Add error message when message observer + //-- is implemented + setDefaultAxis = MB_TRUE; + } + + } + + //-- parse NodeExpr + NodeExpr* nodeExpr = createNodeExpr(lexer); + lstep->setNodeExpr(nodeExpr); + + + //-- set default axis identifiers + if ((setDefaultAxis) && (nodeExpr)) { + switch ( nodeExpr->getType() ) { + case NodeExpr::ATTRIBUTE_EXPR: + axisIdentifier = LocationStep::ATTRIBUTE_AXIS; + break; + default: + axisIdentifier = LocationStep::CHILD_AXIS; + } + } + lstep->setAxisIdentifier(axisIdentifier); + + //-- handle predicates + + parsePredicates(lstep, lexer); + + String foo; + lstep->toString(foo); + //cout << "returning LocationStep: "<< foo <type <type ) { + case Token::CNAME : + nodeExpr = new ElementExpr(tok->value); + break; + case Token::WILD_CARD: + nodeExpr = new WildCardExpr(); + break; + case Token::COMMENT: + nodeExpr = new BasicNodeExpr(NodeExpr::COMMENT_EXPR); + errMsg = parseParameters(¶ms, lexer); + //-- ignore errMsg for now + delete errMsg; + break; + case Token::NODE : + nodeExpr = new BasicNodeExpr(); + errMsg = parseParameters(¶ms, lexer); + //-- ignore errMsg for now + delete errMsg; + break; + case Token::PI : + nodeExpr = new BasicNodeExpr(NodeExpr::PI_EXPR); + errMsg = parseParameters(¶ms, lexer); + //-- ignore errMsg for now + delete errMsg; + break; + case Token::TEXT : + nodeExpr = new TextExpr(); + errMsg = parseParameters(¶ms, lexer); + //-- ignore errMsg for now + delete errMsg; + break; + case Token::AT_SIGN: + tok = lexer.nextToken(); + if ( !tok ) { + //-- handle error + } + else if (tok->type == Token::CNAME) { + nodeExpr = new AttributeExpr(tok->value); + } + else if ( tok->type == Token::WILD_CARD ) { + AttributeExpr* attExpr = new AttributeExpr(); + attExpr->setWild(MB_TRUE); + nodeExpr = attExpr; + } + else { + //-- handle error + } + break; + default: + break; + } + return nodeExpr; +} //-- createNodeExpr + +/** + * Creates a PathExpr using the given ExprLexer + * @param lexer the ExprLexer for retrieving Tokens +**/ +PathExpr* ExprParser::createPathExpr(ExprLexer& lexer) { + + + //-- check for RootExpr + if ( lexer.countRemainingTokens() == 1 ) { + if ( lexer.peek()->type == Token::PARENT_OP ) { + lexer.nextToken(); //-- eat token + return new RootExpr(); + } + } + + PathExpr* pathExpr = new PathExpr(); + short ancestryOp = PathExpr::RELATIVE_OP; + + while ( lexer.hasMoreTokens() ) { + Token* tok = lexer.nextToken(); + switch ( tok->type ) { + case Token::R_PAREN: + case Token::R_BRACKET: + case Token::UNION_OP: + lexer.pushBack(); + return pathExpr; + case Token::ANCESTOR_OP : + ancestryOp = PathExpr::ANCESTOR_OP; + break; + case Token::PARENT_OP : + ancestryOp = PathExpr::PARENT_OP; + break; + default: + lexer.pushBack(); + pathExpr->addPatternExpr(createPatternExpr(lexer), ancestryOp); + ancestryOp = PathExpr::RELATIVE_OP; + break; + } + } + + /* * + String tmp; + pathExpr->toString(tmp); + cout << "creating pathExpr: " << tmp << endl; + /* */ + + return pathExpr; +} //-- createPathExpr + +/** + * Creates a PatternExpr using the given ExprLexer + * @param lexer the ExprLexer for retrieving Tokens +**/ +PatternExpr* ExprParser::createPatternExpr(ExprLexer& lexer) { + + PatternExpr* pExpr = 0; + Token* tok = lexer.peek(); + if ( isLocationStepToken(tok) ) { + pExpr = createLocationStep(lexer); + } + else if ( isFilterExprToken(tok) ) { + pExpr = createFilterExpr(lexer); + } + else { + cout << "invalid token: " << tok->value << endl; + //-- eat token for now + lexer.nextToken(); + } + return pExpr; +} //-- createPatternExpr + +/** + * Creates a PathExpr using the given ExprLexer + * @param lexer the ExprLexer for retrieving Tokens +**/ +UnionExpr* ExprParser::createUnionExpr(ExprLexer& lexer) { + UnionExpr* unionExpr = new UnionExpr(); + + while ( lexer.hasMoreTokens() ) { + Token* tok = lexer.nextToken(); + switch ( tok->type ) { + + case Token::R_PAREN: + case Token::R_BRACKET: + lexer.pushBack(); + return unionExpr; + case Token::UNION_OP : + //-- eat token + break; + default: + lexer.pushBack(); + unionExpr->addPathExpr(createPathExpr(lexer)); + break; + } + } + //String tmp; + //unionExpr->toString(tmp); + //cout << "creating UnionExpr: " << tmp << endl; + return unionExpr; +} //-- createUnionExpr + +MBool ExprParser::isFilterExprToken(Token* token) { + if ( !token ) return MB_FALSE; + switch (token->type) { + case Token::LITERAL: + case Token::NUMBER: + case Token::FUNCTION_NAME: + case Token::VAR_REFERENCE: + case Token::L_PAREN: // grouping expr + case Token::PARENT_NODE: + case Token::SELF_NODE : + return MB_TRUE; + default: + return MB_FALSE; + } +} //-- isFilterExprToken + +MBool ExprParser::isLocationStepToken(Token* token) { + if (!token) return MB_FALSE; + return ((token->type == Token::AXIS_IDENTIFIER) || isNodeTypeToken(token)); +} //-- isLocationStepToken + +MBool ExprParser::isNodeTypeToken(Token* token) { + if (!token) return MB_FALSE; + + switch ( token->type ) { + case Token::AT_SIGN: + case Token::CNAME: + case Token::WILD_CARD: + case Token::COMMENT: + case Token::NODE : + case Token::PI : + case Token::TEXT : + return MB_TRUE; + default: + return MB_FALSE; + } +} //-- isLocationStepToken + +/** + * Using the given lexer, parses the tokens if they represent a predicate list + * If an error occurs a non-zero String pointer will be returned containing the + * error message. + * @param predicateList, the PredicateList to add predicate expressions to + * @param lexer the ExprLexer to use for parsing tokens + * @return 0 if successful, or a String pointer to the error message +**/ +String* ExprParser::parsePredicates(PredicateList* predicateList, ExprLexer& lexer) { + + String* errorMsg = 0; + + Token* tok = lexer.peek(); + + if ( !tok ) return 0; //-- no predicates + if ( tok->type != Token::L_BRACKET ) return 0; //-- not start of predicate list + + lexer.nextToken(); + + while ( lexer.hasMoreTokens() ) { + tok = lexer.peek(); + if(!tok) { + //-- error missing ']' + errorMsg = new String("missing close of predicate expression ']'"); + break; + } + if ( tok->type == Token::R_BRACKET) { + lexer.nextToken(); //-- eat ']' + break; + } + Expr* expr = createExpr(lexer); + predicateList->add(expr); + } + return errorMsg; + +} //-- parsePredicates + + +/** + * Using the given lexer, parses the tokens if they represent a parameter list + * If an error occurs a non-zero String pointer will be returned containing the + * error message. + * @param list, the List to add parameter expressions to + * @param lexer the ExprLexer to use for parsing tokens + * @return 0 if successful, or a String pointer to the error message +**/ +String* ExprParser::parseParameters(List* list, ExprLexer& lexer) { + + String* errorMsg = 0; + + Token* tok = lexer.peek(); + + if ( !tok ) return 0; //-- no params + if ( tok->type != Token::L_PAREN ) return 0; //-- not start of param list + + lexer.nextToken(); //-- eat L_PAREN + + MBool done = MB_FALSE; + MBool foundSep = MB_FALSE; + + while ( lexer.hasMoreTokens() && !done) { + tok = lexer.peek(); + switch ( tok->type ) { + case Token::R_PAREN : + if (foundSep) errorMsg = new String("missing expression after ','"); + lexer.nextToken(); //-- eat R_PAREN + done = MB_TRUE; + break; + case Token::COMMA: //-- param separator + //-- eat COMMA + lexer.nextToken(); + foundSep = MB_TRUE; + break; + default: + if ((list->getLength() > 0) && (!foundSep)) { + errorMsg = new String("missing ',' or ')'"); + done = MB_TRUE; + break; + } + foundSep = MB_FALSE; + Expr* expr = createExpr(lexer); + list->add(expr); + break; + } + } + return errorMsg; + +} //-- parseParameters + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/ExprParser.h b/mozilla/extensions/transformiix/source/xsl/expr/ExprParser.h new file mode 100644 index 00000000000..d97d10a56a6 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/ExprParser.h @@ -0,0 +1,98 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * ExprParser + * This class is used to parse XSL Expressions + * @author Keith Visco + * @see ExprLexer +**/ + +#ifndef MITREXSL_EXPRPARSER_H +#define MITREXSL_EXPRPARSER_H + +#include "String.h" +#include "ExprLexer.h" +#include "Expr.h" +#include "FunctionLib.h" +#include "List.h" +#include "Names.h" +#include + +class ExprParser { + +public: + + static const String R_CURLY_BRACE; + static const String L_CURLY_BRACE; + + /** + * Creates a new ExprParser + **/ + ExprParser(); + + /** + * destroys the ExprParser + **/ + ~ExprParser(); + + Expr* createExpr (const String& pattern); + PatternExpr* createPatternExpr (const String& pattern); + LocationStep* createLocationStep(const String& path); + + /** + * Creates an Attribute Value Template using the given value + **/ + AttributeValueTemplate* createAttributeValueTemplate(const String& attValue); + + +private: + + + Expr* createBinaryExpr (Expr* left, Expr* right, Token* op); + Expr* createExpr (ExprLexer& lexer); + FilterExpr* createFilterExpr (ExprLexer& lexer); + FunctionCall* createFunctionCall (ExprLexer& lexer); + LocationStep* createLocationStep (ExprLexer& lexer); + NodeExpr* createNodeExpr (ExprLexer& lexer); + PathExpr* createPathExpr (ExprLexer& lexer); + PatternExpr* createPatternExpr (ExprLexer& lexer); + UnionExpr* createUnionExpr (ExprLexer& lexer); + + MBool isFilterExprToken (Token* tok); + MBool isLocationStepToken (Token* tok); + MBool isNodeTypeToken (Token* tok); + + /** + * Using the given lexer, parses the tokens if they represent a predicate list + * If an error occurs a non-zero String pointer will be returned containing the + * error message. + * @param predicateList, the PredicateList to add predicate expressions to + * @param lexer the ExprLexer to use for parsing tokens + * @return 0 if successful, or a String pointer to the error message + **/ + String* parsePredicates(PredicateList* predicateList, ExprLexer& lexer); + String* parseParameters(List* list, ExprLexer& lexer); + + +}; //-- ExprParser + +#endif diff --git a/mozilla/extensions/transformiix/source/xsl/expr/ExprResult.h b/mozilla/extensions/transformiix/source/xsl/expr/ExprResult.h new file mode 100644 index 00000000000..5c895927a1b --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/ExprResult.h @@ -0,0 +1,156 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The program is provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + */ + +#include "MITREObject.h" +#include "String.h" +#include "baseutils.h" +#include "primitives.h" + +#ifndef MITREXSL_EXPRRESULT_H +#define MITREXSL_EXPRRESULT_H + + +/* + * ExprResult + *
+ * Classes Represented: + * BooleanResult, ExprResult, NumberResult, StringResult + *
+ * Note: for NodeSet, see NodeSet.h
+ * @author Keith Visco + *
+ *
+ * Modifications:
+ * 19990806: Larry Fitzpatrick
+ *   - changed constant short result types to enum
+ * 
+*/ + +/** + * Represents the result of an expression evaluation + * @author Keith Visco +**/ +class ExprResult : public MITREObject { + +public: + + //-- ResultTypes + enum _ResultType { + NODESET = 1, + STRING, + BOOLEAN, + TREE_FRAGMENT, + NUMBER + }; + + virtual ~ExprResult() {}; + + /** + * Returns the type of ExprResult represented + * @return the type of ExprResult represented + **/ + virtual short getResultType() = 0; + /** + * Creates a String representation of this ExprResult + * @param str the destination string to append the String representation to. + **/ + virtual void stringValue(String& str) = 0; + + /** + * Converts this ExprResult to a Boolean (MBool) value + * @return the Boolean value + **/ + virtual MBool booleanValue() = 0; + + /** + * Converts this ExprResult to a Number (double) value + * @return the Number value + **/ + virtual double numberValue() = 0; + +}; + +class BooleanResult : public ExprResult { + +public: + + BooleanResult(); + BooleanResult(MBool boolean); + BooleanResult(const BooleanResult& boolResult); + + MBool getValue() const; + + void setValue(MBool boolean); + + void setValue(const BooleanResult& boolResult); + + virtual short getResultType(); + virtual void stringValue(String& str); + virtual MBool booleanValue(); + virtual double numberValue(); + +private: + MBool value; +}; + +class NumberResult : public ExprResult { + +public: + + NumberResult(); + NumberResult(double dbl); + NumberResult(const NumberResult& nbrResult); + + double getValue() const; + + void setValue(double dbl); + + void setValue(const NumberResult& nbrResult); + + MBool isNaN() const; + + virtual short getResultType(); + virtual void stringValue(String& str); + virtual MBool booleanValue(); + virtual double numberValue(); + +private: + double value; + +}; + + +class StringResult : public ExprResult { + +public: + + StringResult(); + StringResult(String& str); + StringResult(const String& str); + StringResult(const StringResult& strResult); + + String& getValue(); + void setValue(const String& str); + + virtual short getResultType(); + virtual void stringValue(String& str); + virtual MBool booleanValue(); + virtual double numberValue(); + + +private: + String value; +}; + +#endif + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/FilterExpr.cpp b/mozilla/extensions/transformiix/source/xsl/expr/FilterExpr.cpp new file mode 100644 index 00000000000..8fa1d9a7fec --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/FilterExpr.cpp @@ -0,0 +1,142 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "Expr.h" + + +/** + * @author Keith Visco +**/ +//-- Implementation of FilterExpr --/ + + +FilterExpr::FilterExpr() : PredicateList() { + expr = 0; +} + +/** + * Creates a new FilterExpr using the given Expr + * @param expr the Expr to use for evaluation +**/ +FilterExpr::FilterExpr(Expr* expr) : PredicateList() { + this->expr = expr; +} //-- FilterExpr + +/** + * Destroys this FilterExpr, all predicates and the expr will be deleted +**/ +FilterExpr::~FilterExpr() { + delete expr; +} //-- ~FilterExpr + +/** + * Sets the Expr of this FilterExpr for use during evaluation + * @param expr the Expr to use for evaluation +**/ +void FilterExpr::setExpr(Expr* expr) { + this->expr = expr; +} //-- setExpr + + + //------------------------------------/ + //- Virtual methods from PatternExpr -/ +//------------------------------------/ + +/** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ProcessorState containing the stack information needed + * for evaluation + * @return the result of the evaluation + * @see PatternExpr +**/ +ExprResult* FilterExpr::evaluate(Node* context, ContextState* cs) { + + NodeSet* nodes = new NodeSet(); + + if (( !context ) || (! expr )) return nodes; + + + ExprResult* exprResult = expr->evaluate(context, cs); + NodeSet* nodeSet = 0; + + switch (exprResult->getResultType()) { + case ExprResult::NODESET: + nodeSet = (NodeSet*)exprResult; + break; + /* + case ExprResult.TREE_FRAGMENT: + nodeSet = new NodeSet(1); + nodeSet.add(((TreeFragmentResult)exprResult).getValue()); + break; + */ + default: + break; + /* + throw new InvalidExprException + ("expecting NodeSet or TreeFragment as the result of the "+ + "expression: " + primaryExpr); + */ + } + + //-- filter nodes (apply predicates) + evaluatePredicates(nodeSet, cs); + + return nodeSet; +} //-- evaluate + +/** + * Returns the default priority of this Pattern based on the given Node, + * context Node, and ContextState. + * If this pattern does not match the given Node under the current context Node and + * ContextState then Negative Infinity is returned. +**/ +double FilterExpr::getDefaultPriority(Node* node, Node* context, ContextState* cs) { + //-- this method will never be called, it's only here since + //-- I made it manditory for PatternExprs I will remove it soon + return Double::NEGATIVE_INFINITY; +} //-- getDefaultPriority + +/** + * Determines whether this PatternExpr matches the given node within + * the given context +**/ +MBool FilterExpr::matches(Node* node, Node* context, ContextState* cs) { + + if ( !expr ) return MB_FALSE; + NodeSet* nodes = (NodeSet*)evaluate(node, cs); + MBool result = (nodes->contains(node)); + delete nodes; + return result; + +} //-- matches + +/** + * Creates a String representation of this Expr + * @param str the destination String to append to + * @see Expr +**/ +void FilterExpr::toString(String& str) { + if ( expr ) expr->toString(str); + else str.append("null"); + PredicateList::toString(str); +} //-- toString + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/FunctionCall.cpp b/mozilla/extensions/transformiix/source/xsl/expr/FunctionCall.cpp new file mode 100644 index 00000000000..7d3ab235d1e --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/FunctionCall.cpp @@ -0,0 +1,197 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "FunctionLib.h" + +/** + * This class represents a FunctionCall as defined by the XSL Working Draft + * @author Keith Visco + * This file was ported from XSL:P +**/ + +const String FunctionCall::INVALID_PARAM_COUNT = + "invalid number of parameters for function: "; + +//- Constructors -/ + +/** + * Creates a new FunctionCall +**/ +FunctionCall::FunctionCall() { + this->name = "void"; +} //-- FunctionCall + +/** + * Creates a new FunctionCall with the given function + * Note: The object references in parameters will be deleted when this + * FunctionCall gets destroyed. +**/ +FunctionCall::FunctionCall(const String& name) { + //-- copy name + this->name = name; +} //-- FunctionCall + +/** + * Creates a new FunctionCall with the given function name and parameter list + * Note: The object references in parameters will be deleted when this + * FunctionCall gets destroyed. +**/ +FunctionCall::FunctionCall(const String& name, List* parameters) { + //-- copy name + this->name = name; + + if (parameters) { + ListIterator* pIter = parameters->iterator(); + while ( pIter->hasNext() ) { + params.add(pIter->next()); + } + delete pIter; + } + +} //-- FunctionCall + + +/** + * Destructor +**/ +FunctionCall::~FunctionCall() { + + ListIterator* iter = params.iterator(); + while ( iter->hasNext() ) { + iter->next(); + Expr* expr = (Expr*) iter->remove(); + delete expr; + } + delete iter; +} //-- ~FunctionCall + + //------------------/ + //- Public Methods -/ +//------------------/ + +/** + * Adds the given parameter to this FunctionCall's parameter list + * @param expr the Expr to add to this FunctionCall's parameter list +**/ +void FunctionCall::addParam(Expr* expr) { + if ( expr ) params.add(expr); +} //-- addParam + +/** + * Evaluates the given Expression and converts it's result to a String. + * The value is appended to the given destination String +**/ +void FunctionCall::evaluateToString + (Expr* expr, Node* context, ContextState* cs, String& dest) +{ + if (!expr) return; + ExprResult* exprResult = expr->evaluate(context, cs); + exprResult->stringValue(dest); + delete exprResult; +} //-- evaluateToString + +/** + * Evaluates the given Expression and converts it's result to a number. +**/ +double FunctionCall::evaluateToNumber + (Expr* expr, Node* context, ContextState* cs) +{ + double result = Double::NaN; + if (!expr) return result; + ExprResult* exprResult = expr->evaluate(context, cs); + result = exprResult->numberValue(); + delete exprResult; + return result; +} //-- evaluateToNumber + +/** + * Returns the name of this FunctionCall + * @return the name of this FunctionCall +**/ +const String& FunctionCall::getName() { + return (const String&) this->name; +} //-- getName + +/** + * Called to check number of parameters +**/ +MBool FunctionCall::requireParams + (int paramCountMin, int paramCountMax, ContextState* cs) +{ + + int argc = params.getLength(); + if (( argc < paramCountMin) || (argc > paramCountMax)) { + String err(INVALID_PARAM_COUNT); + toString(err); + cs->recieveError(err); + return MB_FALSE; + } + return MB_TRUE; +} //-- requireParams + +/** + * Called to check number of parameters +**/ +MBool FunctionCall::requireParams(int paramCountMin, ContextState* cs) { + int argc = params.getLength(); + if (argc < paramCountMin) { + String err(INVALID_PARAM_COUNT); + toString(err); + cs->recieveError(err); + return MB_FALSE; + } + return MB_TRUE; +} //-- requireParams + +/** + * Sets the function name of this FunctionCall + * @param name the name of this Function +**/ +void FunctionCall::setName(const String& name) { + this->name.clear(); + this->name.append(name); +} //-- setName + +/** + * Returns the String representation of this NodeExpr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this NodeExpr. +**/ +void FunctionCall::toString(String& dest) { + dest.append(this->name); + dest.append('('); + //-- add parameters + ListIterator* iterator = params.iterator(); + int argc = 0; + while ( iterator->hasNext() ) { + if ( argc > 0 ) dest.append(','); + Expr* expr = (Expr*)iterator->next(); + expr->toString(dest); + ++argc; + + } + delete iterator; + dest.append(')'); +} //-- toString + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/FunctionLib.h b/mozilla/extensions/transformiix/source/xsl/expr/FunctionLib.h new file mode 100644 index 00000000000..926173af230 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/FunctionLib.h @@ -0,0 +1,281 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + + + +#ifndef MITREXSL_FUNCTIONLIB_H +#define MITREXSL_FUNCTIONLIB_H + +#include "String.h" +#include "primitives.h" +#include "NodeSet.h" +#include "List.h" +#include "dom.h" +#include "ExprResult.h" +#include "baseutils.h" +#include "Expr.h" +#include "Names.h" +#include "XMLUtils.h" +#include + +/** + * This class represents a FunctionCall as defined by the XSL + * Working Draft. + * This file was ported from XSL:P
+ * @author Keith Visco + *
+ *
+ * Modifications:
+ * 19990805: Keith Visco
+ *   - added NodeSetFunctionCall
+ *   - moved position() function into NodeSetFunctionCall
+ *   - removed PositionFunctionCall
+ * 19990806: Larry Fitzpatrick
+ *   - changed constant short declarations for BooleanFunctionCall
+ *     with enumerations
+ * 19990806: Keith Visco
+ *   - added StringFunctionCall
+ *   - stated using Larry's enum suggestion instead of using static const shorts,
+ *     as you can see, I am a Java developer! ;-)
+ * 
+**/ +class FunctionCall : public Expr { + +public: + + static const String INVALID_PARAM_COUNT; + + + virtual ~FunctionCall(); + + /** + * Adds the given parameter to this FunctionCall's parameter list + * @param expr the Expr to add to this FunctionCall's parameter list + **/ + void addParam(Expr* expr); + + /** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation + **/ + virtual ExprResult* evaluate(Node* context, ContextState* cs) = 0; + + /** + * Returns the name of this FunctionCall + * @return the name of this FunctionCall + **/ + const String& getName(); + + virtual MBool requireParams(int paramCountMin, ContextState* cs); + + virtual MBool requireParams(int paramCountMin, + int paramCountMax, + ContextState* cs); + + /** + * Sets the function name of this FunctionCall + * @param name the name of this Function + **/ + void setName(const String& name); + /** + * Returns the String representation of this Pattern. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this Pattern. + **/ + virtual void toString(String& dest); + + +protected: + + List params; + + FunctionCall(); + FunctionCall(const String& name); + FunctionCall(const String& name, List* parameters); + + + /** + * Evaluates the given Expression and converts it's result to a String. + * The value is appended to the given destination String + **/ + void FunctionCall::evaluateToString + (Expr* expr, Node* context, ContextState* cs, String& dest); + + /** + * Evaluates the given Expression and converts it's result to a number. + **/ + double evaluateToNumber(Expr* expr, Node* context, ContextState* cs); + +private: + + String name; +}; //-- FunctionCall + +/** + * Represents the Set of boolean functions + * @author Keith Visco +**/ +class BooleanFunctionCall : public FunctionCall { + +public: + + enum _BooleanFunctions { BOOLEAN = 1, FALSE, NOT, TRUE }; + + /** + * Creates a default BooleanFunctionCall, which always evaluates to False + **/ + BooleanFunctionCall(); + + /** + * Creates a BooleanFunctionCall of the given type + **/ + BooleanFunctionCall(short type); + + /** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation + **/ + virtual ExprResult* evaluate(Node* context, ContextState* cs); + +private: + short type; +}; //-- BooleanFunctionCall + +/** + * Internal Function created when there is an Error during parsing + * an Expression +**/ +class ErrorFunctionCall : public FunctionCall { +public: + + ErrorFunctionCall(); + ErrorFunctionCall(const String& errorMsg); + + /** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation + **/ + virtual ExprResult* evaluate(Node* context, ContextState* cs); + + void setErrorMessage(String& errorMsg); + +private: + + String errorMessage; + +}; //-- ErrorFunctionCall + +/** + * Represents the XPath NodeSet function calls +**/ +class NodeSetFunctionCall : public FunctionCall { + +public: + + enum _NodeSetFunctions { + COUNT = 1, //-- count() + LAST, //-- last() + LOCAL_PART, //-- local-part() + NAMESPACE, //-- namespace() + NAME, //-- name() + POSITION //-- position() + }; + + /** + * Creates a default NodeSetFunction call. Position function is the default. + **/ + NodeSetFunctionCall(); + + /** + * Creates a NodeSetFunctionCall of the given type + **/ + NodeSetFunctionCall(short type); + + /** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation + **/ + virtual ExprResult* evaluate(Node* context, ContextState* cs); + +private: + short type; +}; //-- NodeSetFunctionCall + + +/** + * Represents the XPath String Function Calls +**/ +class StringFunctionCall : public FunctionCall { + +public: + + enum _StringFunctions { + CONCAT = 1, //-- concat() + CONTAINS, //-- contains() + NORMALIZE, //-- normalize() + STARTS_WITH, //-- starts-with() + STRING, //-- string() + STRING_LENGTH, //-- string-length() + SUBSTRING, //-- substring() + SUBSTRING_AFTER, //-- substring-after() + SUBSTRING_BEFORE, //-- substring-before() + TRANSLATE //-- translate() + }; + + /** + * Creates a default String function. String() function is the default. + **/ + StringFunctionCall(); + + /** + * Creates a String function of the given type + **/ + StringFunctionCall(short type); + + /** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation + **/ + virtual ExprResult* evaluate(Node* context, ContextState* cs); + +private: + short type; +}; //-- StringFunctionCall + +#endif diff --git a/mozilla/extensions/transformiix/source/xsl/expr/IdentityExpr.cpp b/mozilla/extensions/transformiix/source/xsl/expr/IdentityExpr.cpp new file mode 100644 index 00000000000..2616ef61c6c --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/IdentityExpr.cpp @@ -0,0 +1,53 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * @author Keith Visco +**/ +#include "Expr.h" + +/** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation +**/ +ExprResult* IdentityExpr::evaluate(Node* context, ContextState* cs) { + NodeSet* nodeSet = new NodeSet(); + if ( context ) { + nodeSet->add(context); + } + return nodeSet; +} //-- evaluate + +/** + * Returns the String representation of this NodeExpr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this NodeExpr. +**/ +void IdentityExpr::toString(String& dest) { + dest.append('.'); +} //-- toString + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/LocationStep.cpp b/mozilla/extensions/transformiix/source/xsl/expr/LocationStep.cpp new file mode 100644 index 00000000000..606c3d6fc6b --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/LocationStep.cpp @@ -0,0 +1,307 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * LocationStep + * @author Keith Visco +**/ + +#include "Expr.h" + +/** + * Creates a new LocationStep using the default Axis Identifier and no + * NodeExpr (which matches nothing) +**/ +LocationStep::LocationStep() : PredicateList() { + nodeExpr = 0; + this->axisIdentifier = CHILD_AXIS; +} //-- LocationStep + +/** + * Creates a new LocationStep using the default Axis Identifier and + * the given NodeExpr + * @param nodeExpr the NodeExpr to use when matching Nodes +**/ +LocationStep::LocationStep(NodeExpr* nodeExpr) : PredicateList() { + this->nodeExpr = nodeExpr; + this->axisIdentifier = CHILD_AXIS; +} //-- LocationStep + +/** + * Creates a new LocationStep using the given NodeExpr and Axis Identifier + * @param nodeExpr the NodeExpr to use when matching Nodes + * @param axisIdentifier the Axis Identifier in which to search for nodes +**/ +LocationStep::LocationStep(NodeExpr* nodeExpr, short axisIdentifier) : PredicateList() { + this->nodeExpr = nodeExpr; + this->axisIdentifier = axisIdentifier; +} //-- LocationStep + +/** + * Destroys this LocationStep + * All predicates will be deleted + * The NodeExpr will be deleted +**/ +LocationStep::~LocationStep() { + delete nodeExpr; +} //-- ~LocationStep + +/** + * Sets the Axis Identifier for this LocationStep + * @param axisIdentifier the Axis in which to search for nodes +**/ +void LocationStep::setAxisIdentifier(short axisIdentifier) { + this->axisIdentifier = axisIdentifier; +} //-- setAxisIdentifier + + +/** + * Sets the NodeExpr of this LocationStep for use when matching nodes + * @param nodeExpr the NodeExpr to use when matching nodes +**/ +void LocationStep::setNodeExpr(NodeExpr* nodeExpr) { + this->nodeExpr = nodeExpr; +} //-- setNodeExpr + + + //------------------------------------/ + //- Virtual methods from PatternExpr -/ +//------------------------------------/ + +/** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ProcessorState containing the stack information needed + * for evaluation + * @return the result of the evaluation + * @see PatternExpr +**/ +ExprResult* LocationStep::evaluate(Node* context, ContextState* cs) { + + NodeSet* nodes = new NodeSet(); + if (( !context ) || (! nodeExpr )) return nodes; + + Node* node = context; + switch (axisIdentifier) { + case ANCESTOR_AXIS : + if (node) node = context->getParentNode(); + //-- do not break here + case ANCESTOR_OR_SELF_AXIS : + while (node) { + if (nodeExpr->matches(node, context, cs)) { + nodes->add(node); + } + node = node->getParentNode(); + } + break; + case ATTRIBUTE_AXIS : + { + NamedNodeMap* atts = context->getAttributes(); + if ( atts ) { + for ( int i = 0; i < atts->getLength(); i++ ) { + Attr* attr = (Attr*)atts->item(i); + if ( nodeExpr->matches(attr, context, cs) ) nodes->add(attr); + } + } + break; + } + case DESCENDANT_OR_SELF_AXIS : + if ( nodeExpr->matches(context, context, cs)) + nodes->add(context); + //-- do not break here + case DESCENDANT_AXIS : + fromDescendants(context, cs, nodes); + break; + case FOLLOWING_AXIS : + { + node = context->getNextSibling(); + while (node) { + if (nodeExpr->matches(node, context, cs)) + nodes->add(node); + + if (node->hasChildNodes()) + fromDescendants(node, cs, nodes); + + Node* tmpNode = node->getNextSibling(); + if (!tmpNode) { + node = node->getParentNode(); + if ((node) && (node->getNodeType() != Node::DOCUMENT_NODE)) + node = node->getNextSibling(); + } + else node = tmpNode; + } + break; + } + case FOLLOWING_SIBLING_AXIS : + node = context->getNextSibling(); + while (node) { + if (nodeExpr->matches(node, context, cs)) + nodes->add(node); + node = node->getNextSibling(); + } + break; + case NAMESPACE_AXIS : //-- not yet implemented + cout << "namespace axis not yet implemented"<getParentNode(); + if ( nodeExpr->matches(parent, context, cs) ) + nodes->add(parent); + break; + } + case PRECEDING_AXIS : + node = context->getPreviousSibling(); + if ( !node ) node = context->getParentNode(); + while (node) { + if (nodeExpr->matches(node, context, cs)) + nodes->add(node); + + Node* temp = node->getPreviousSibling(); + if (!temp) node = node->getParentNode(); + else node = temp; + } + break; + case PRECEDING_SIBLING_AXIS: + node = context->getPreviousSibling(); + while (node) { + if (nodeExpr->matches(node, context, cs)) + nodes->add(node); + node = node->getPreviousSibling(); + } + break; + case SELF_AXIS : + if ( nodeExpr->matches(context, context, cs) ) + nodes->add(context); + break; + default: //-- Children Axis + { + NodeList* nl = context->getChildNodes(); + for (int i = 0; i < nl->getLength(); i++ ) { + if ( nodeExpr->matches(nl->item(i), context, cs) ) + nodes->add(nl->item(i)); + } + break; + } + } //-- switch + + //-- apply predicates + evaluatePredicates(nodes, cs); + + return nodes; +} //-- evaluate + +/** + * Returns the default priority of this Pattern based on the given Node, + * context Node, and ContextState. + * If this pattern does not match the given Node under the current context Node and + * ContextState then Negative Infinity is returned. +**/ +double LocationStep::getDefaultPriority(Node* node, Node* context, ContextState* cs) { + + if ( !nodeExpr ) { + return Double::NEGATIVE_INFINITY; + } + if (!PredicateList::isEmpty()) { + return 0.5; + } + return nodeExpr->getDefaultPriority(node, context, cs); + +} //-- getDefaultPriority + + +void LocationStep::fromDescendants(Node* context, ContextState* cs, NodeSet* nodes) { + + if (( !context ) || (! nodeExpr )) return; + + NodeList* nl = context->getChildNodes(); + for (int i = 0; i < nl->getLength(); i++) { + Node* child = nl->item(i); + if (nodeExpr->matches(child, context, cs)) + nodes->add(child); + //-- check childs descendants + if (child->hasChildNodes()) fromDescendants(child, cs, nodes); + } + +} //-- fromDescendants + +/** + * Determines whether this PatternExpr matches the given node within + * the given context +**/ +MBool LocationStep::matches(Node* node, Node* context, ContextState* cs) { + + if ( !nodeExpr ) return MB_FALSE; + NodeSet* nodes = (NodeSet*) evaluate(context, cs); + MBool result = nodes->contains(node); + delete nodes; + return result; + +} //-- matches + +/** + * Creates a String representation of this Expr + * @param str the destination String to append to + * @see Expr +**/ +void LocationStep::toString(String& str) { + switch (axisIdentifier) { + case ANCESTOR_AXIS : + str.append("ancestor::"); + break; + case ANCESTOR_OR_SELF_AXIS : + str.append("ancestor-or-self::"); + break; + case DESCENDANT_AXIS: + str.append("descendant::"); + break; + case DESCENDANT_OR_SELF_AXIS: + str.append("descendant-or-self::"); + break; + case FOLLOWING_AXIS : + str.append("following::"); + break; + case FOLLOWING_SIBLING_AXIS: + str.append("following-sibling::"); + break; + case NAMESPACE_AXIS: + str.append("namespace::"); + break; + case PARENT_AXIS : + str.append("parent::"); + break; + case PRECEDING_AXIS : + str.append("preceding::"); + break; + case PRECEDING_SIBLING_AXIS : + str.append("preceding-sibling::"); + break; + case SELF_AXIS : + str.append("self::"); + break; + default: + break; + } + if ( nodeExpr ) nodeExpr->toString(str); + else str.append("null"); + PredicateList::toString(str); +} //-- toString + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/Makefile b/mozilla/extensions/transformiix/source/xsl/expr/Makefile new file mode 100644 index 00000000000..42d1c45776e --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/Makefile @@ -0,0 +1,155 @@ +target: exprlib + +CC = g++ + +EXPR_PATH = . +ROOT_PATH = ../.. +XML_PATH = $(ROOT_PATH)/xml +DOM_PATH = $(XML_PATH)/dom +BASE_PATH = $(ROOT_PATH)/base +XSLUTIL_PATH = $(PROCESSOR_PATH)/util +PROCESSOR_PATH = .. + +INCLUDE_PATHS = -I $(EXPR_PATH) \ + -I $(DOM_PATH) \ + -I $(BASE_PATH) \ + -I $(XML_PATH) \ + -I $(XSLUTIL_PATH) \ + -I $(PROCESSOR_PATH) \ + -I- + + +EXPR_OBJS = AdditiveExpr.o \ + AttributeExpr.o \ + AttributeValueTemplate.o \ + BasicNodeExpr.o \ + BooleanResult.o \ + ElementExpr.o \ + ExprLexer.o \ + ExprParser.o \ + FilterExpr.o \ + IdentityExpr.o \ + LocationStep.o \ + MultiplicativeExpr.o \ + NumberExpr.o \ + NumberResult.o \ + PredicateList.o \ + ParentExpr.o \ + PathExpr.o \ + RelationalExpr.o \ + RootExpr.o \ + StringExpr.o \ + StringResult.o \ + TextExpr.o \ + UnionExpr.o \ + VariableRefExpr.o \ + WildCardExpr.o + +FUNCTION_CALL_OBJS = \ + BooleanFunctionCall.o \ + ErrorFunctionCall.o \ + FunctionCall.o \ + NodeSetFunctionCall.o \ + StringFunctionCall.o + +ALL_OBJS = $(EXPR_OBJS) \ + $(FUNCTION_CALL_OBJS) \ + +exprlib: $(ALL_OBJS) + +AdditiveExpr.o: Expr.h AdditiveExpr.cpp + $(CC) $(INCLUDE_PATHS) -c AdditiveExpr.cpp + + +AttributeExpr.o: Expr.h AttributeExpr.cpp + $(CC) $(INCLUDE_PATHS) -c AttributeExpr.cpp + +AttributeValueTemplate.o: Expr.h AttributeValueTemplate.cpp + $(CC) $(INCLUDE_PATHS) -c AttributeValueTemplate.cpp + +BasicNodeExpr.o: Expr.h BasicNodeExpr.cpp + $(CC) $(INCLUDE_PATHS) -c BasicNodeExpr.cpp + +BooleanResult.o: ExprResult.h BooleanResult.cpp + $(CC) $(INCLUDE_PATHS) -c BooleanResult.cpp + +ElementExpr.o: Expr.h ElementExpr.cpp + $(CC) $(INCLUDE_PATHS) -c ElementExpr.cpp + +ExprLexer.o: ExprLexer.cpp ExprLexer.h + $(CC) $(INCLUDE_PATHS) -c ExprLexer.cpp + +ExprParser.o: Expr.h ExprParser.cpp ExprParser.h + $(CC) $(INCLUDE_PATHS) -c ExprParser.cpp + +FilterExpr.o: FilterExpr.cpp Expr.h + $(CC) $(INCLUDE_PATHS) -c FilterExpr.cpp + +IdentityExpr.o: Expr.h IdentityExpr.cpp + $(CC) $(INCLUDE_PATHS) -c IdentityExpr.cpp + +LocationStep.o: Expr.h LocationStep.cpp + $(CC) $(INCLUDE_PATHS) -c LocationStep.cpp + +MultiplicativeExpr.o: Expr.h MultiplicativeExpr.cpp + $(CC) $(INCLUDE_PATHS) -c MultiplicativeExpr.cpp + +NumberExpr.o: Expr.h NumberExpr.cpp + $(CC) $(INCLUDE_PATHS) -c NumberExpr.cpp + +NumberResult.o: ExprResult.h NumberResult.cpp + $(CC) $(INCLUDE_PATHS) -c NumberResult.cpp + +ParentExpr.o: Expr.h ParentExpr.cpp + $(CC) $(INCLUDE_PATHS) -c ParentExpr.cpp + +PathExpr.o: Expr.h PathExpr.cpp + $(CC) $(INCLUDE_PATHS) -c PathExpr.cpp + +PredicateList.o: Expr.h PredicateList.cpp + $(CC) $(INCLUDE_PATHS) -c PredicateList.cpp + +RelationalExpr.o: Expr.h RelationalExpr.cpp + $(CC) $(INCLUDE_PATHS) -c RelationalExpr.cpp + +RootExpr.o: Expr.h RootExpr.cpp + $(CC) $(INCLUDE_PATHS) -c RootExpr.cpp + +StringExpr.o: Expr.h StringExpr.cpp + $(CC) $(INCLUDE_PATHS) -c StringExpr.cpp + +StringResult.o: ExprResult.h StringResult.cpp + $(CC) $(INCLUDE_PATHS) -c StringResult.cpp + +TextExpr.o: Expr.h TextExpr.cpp + $(CC) $(INCLUDE_PATHS) -c TextExpr.cpp + +UnionExpr.o: Expr.h UnionExpr.cpp + $(CC) $(INCLUDE_PATHS) -c UnionExpr.cpp + +VariableRefExpr.o: Expr.h VariableRefExpr.cpp + $(CC) $(INCLUDE_PATHS) -c VariableRefExpr.cpp + +WildCardExpr.o: Expr.h WildCardExpr.cpp + $(CC) $(INCLUDE_PATHS) -c WildCardExpr.cpp + + +######################## +## FunctionCall package +######################## + + +BooleanFunctionCall.o: FunctionLib.h BooleanFunctionCall.cpp + $(CC) $(INCLUDE_PATHS) -c BooleanFunctionCall.cpp + +ErrorFunctionCall.o: FunctionLib.h ErrorFunctionCall.cpp + $(CC) $(INCLUDE_PATHS) -c ErrorFunctionCall.cpp + +FunctionCall.o: FunctionLib.h FunctionCall.cpp + $(CC) $(INCLUDE_PATHS) -c FunctionCall.cpp + +NodeSetFunctionCall.o: FunctionLib.h NodeSetFunctionCall.cpp + $(CC) $(INCLUDE_PATHS) -c NodeSetFunctionCall.cpp + +StringFunctionCall.o: FunctionLib.h StringFunctionCall.cpp + $(CC) $(INCLUDE_PATHS) -c StringFunctionCall.cpp diff --git a/mozilla/extensions/transformiix/source/xsl/expr/MultiplicativeExpr.cpp b/mozilla/extensions/transformiix/source/xsl/expr/MultiplicativeExpr.cpp new file mode 100644 index 00000000000..b10726a2fd2 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/MultiplicativeExpr.cpp @@ -0,0 +1,140 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * Represents a MultiplicativeExpr, an binary expression that + * performs a multiplicative operation between it's lvalue and rvalue:
+ * * : multiply + * mod : modulus + * div : divide + * @author Keith Visco +**/ + +#include "Expr.h" + +/** + * Creates a new MultiplicativeExpr using the default operator (MULTIPLY) +**/ +MultiplicativeExpr::MultiplicativeExpr() { + this->op = MULTIPLY; + this->leftExpr = 0; + this->rightExpr = 0; +} //-- RelationalExpr + +/** + * Creates a new MultiplicativeExpr using the given operator +**/ +MultiplicativeExpr::MultiplicativeExpr(Expr* leftExpr, Expr* rightExpr, short op) { + this->op = op; + this->leftExpr = leftExpr; + this->rightExpr = rightExpr; +} //-- MultiplicativeExpr + +MultiplicativeExpr::~MultiplicativeExpr() { + delete leftExpr; + delete rightExpr; +} //-- ~MultiplicativeExpr + +/** + * Sets the left side of this MultiplicativeExpr +**/ +void MultiplicativeExpr::setLeftExpr(Expr* leftExpr) { + this->leftExpr = leftExpr; +} //-- setLeftExpr + +/** + * Sets the right side of this MultiplicativeExpr +**/ +void MultiplicativeExpr::setRightExpr(Expr* rightExpr) { + this->rightExpr = rightExpr; +} //-- setRightExpr + +/** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation +**/ +ExprResult* MultiplicativeExpr::evaluate(Node* context, ContextState* cs) { + + + double rightDbl = Double::NaN; + ExprResult* exprRes = 0; + + if ( rightExpr ) { + exprRes = rightExpr->evaluate(context, cs); + if ( exprRes ) rightDbl = exprRes->numberValue(); + delete exprRes; + } + + double leftDbl = Double::NaN; + if ( leftExpr ) { + exprRes = leftExpr->evaluate(context, cs); + if ( exprRes ) leftDbl = exprRes->numberValue(); + delete exprRes; + } + + double result = 0; + + switch ( op ) { + case DIVIDE: + result = (leftDbl / rightDbl); + break; + case MODULUS: + result = fmod(leftDbl, rightDbl); + break; + default: + result = leftDbl * rightDbl; + break; + } + return new NumberResult(result); +} //-- evaluate + +/** + * Returns the String representation of this Expr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this Expr. +**/ +void MultiplicativeExpr::toString(String& str) { + + if ( leftExpr ) leftExpr->toString(str); + else str.append("null"); + + switch ( op ) { + case DIVIDE: + str.append(" div "); + break; + case MODULUS: + str.append(" mod "); + break; + default: + str.append(" * "); + break; + } + if ( rightExpr ) rightExpr->toString(str); + else str.append("null"); + +} //-- toString + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/NodeSetFunctionCall.cpp b/mozilla/extensions/transformiix/source/xsl/expr/NodeSetFunctionCall.cpp new file mode 100644 index 00000000000..04d49d3219f --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/NodeSetFunctionCall.cpp @@ -0,0 +1,160 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * NodeSetFunctionCall + * A representation of the XPath NodeSet funtions + * @author Keith Visco +**/ + +#include "FunctionLib.h" + +/** + * Creates a default NodeSetFunctionCall. The Position function + * is the default +**/ +NodeSetFunctionCall::NodeSetFunctionCall() : FunctionCall(POSITION_FN) { + type = POSITION; +} //-- NodeSetFunctionCall + +/** + * Creates a NodeSetFunctionCall of the given type +**/ +NodeSetFunctionCall::NodeSetFunctionCall(short type) : FunctionCall() { + this->type = type; + switch ( type ) { + case COUNT : + FunctionCall::setName(COUNT_FN); + break; + case LAST : + FunctionCall::setName(LAST_FN); + break; + case LOCAL_PART: + FunctionCall::setName(LOCAL_PART_FN); + break; + case NAME: + FunctionCall::setName(NAME_FN); + break; + case NAMESPACE: + FunctionCall::setName(NAMESPACE_FN); + break; + default: + FunctionCall::setName(POSITION_FN); + break; + } +} //-- NodeSetFunctionCall + +/** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation +**/ +ExprResult* NodeSetFunctionCall::evaluate(Node* context, ContextState* cs) { + NodeSet* nodeSet = (NodeSet*)cs->getNodeSetStack()->peek(); + ListIterator* iter = params.iterator(); + Int32 argc = params.getLength(); + ExprResult* result = 0; + Expr* param = 0; + switch ( type ) { + case COUNT : + if ( argc == 1 ) { + double count = 0.0; + param = (Expr*)iter->next(); + ExprResult* exprResult = param->evaluate(context, cs); + if ( exprResult->getResultType() != ExprResult::NODESET ) { + String err("NodeSet expected as argument to count()"); + cs->recieveError(err); + } + else count = (double) ((NodeSet*)exprResult)->size(); + delete exprResult; + result = new NumberResult(count); + } + else { + String err(INVALID_PARAM_COUNT); + this->toString(err); + cs->recieveError(err); + result = new NumberResult(0.0); + } + break; + case LAST : + if ( nodeSet ) result = new NumberResult((double)nodeSet->size()); + else result = new NumberResult(0.0); + break; + case LOCAL_PART: + case NAME: + case NAMESPACE : + { + String name; + Node* node = 0; + if ( argc < 2 ) { + + //-- check for optional arg + if ( argc == 1) { + param = (Expr*)iter->next(); + ExprResult* exprResult = param->evaluate(context, cs); + if ( exprResult->getResultType() != ExprResult::NODESET ) { + String err("NodeSet expected as argument to "); + this->toString(err); + cs->recieveError(err); + } + else { + NodeSet* nodes = (NodeSet*)exprResult; + if (nodes->size() > 0) node = nodes->get(0); + } + delete exprResult; + } + if ( !node ) node = context; + + switch ( type ) { + case LOCAL_PART : + XMLUtils::getLocalPart(node->getNodeName(),name); + break; + case NAMESPACE : + XMLUtils::getNameSpace(node->getNodeName(),name); + break; + default: + name = node->getNodeName(); + break; + } + result = new StringResult(name); + } + else { + String err(INVALID_PARAM_COUNT); + this->toString(err); + cs->recieveError(err); + result = new StringResult(""); + } + break; + } + default : //-- position + if ( nodeSet ) + result = new NumberResult((double)nodeSet->indexOf(context)+1); + else + result = new NumberResult(0.0); + break; + } + delete iter; + return result; +} //-- evaluate + + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/NumberExpr.cpp b/mozilla/extensions/transformiix/source/xsl/expr/NumberExpr.cpp new file mode 100644 index 00000000000..432f83abdd3 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/NumberExpr.cpp @@ -0,0 +1,61 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "Expr.h" + + //--------------/ + //- NumberExpr -/ +//--------------/ + +NumberExpr::NumberExpr() { + numberResult.setValue(0.0); +} //-- NumberExpr + +NumberExpr::NumberExpr(double dbl) { + numberResult.setValue(dbl); +} //-- NumberExpr + +NumberExpr::~NumberExpr() { +} //-- ~NumberExpr + +/** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation +**/ +ExprResult* NumberExpr::evaluate(Node* context, ContextState* cs) { + return new NumberResult(numberResult); +} //-- evaluate + +/** + * Returns the String representation of this Expr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this Expr. +**/ +void NumberExpr::toString(String& str) { + numberResult.stringValue(str); +} //-- toString + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/NumberResult.cpp b/mozilla/extensions/transformiix/source/xsl/expr/NumberResult.cpp new file mode 100644 index 00000000000..aac93a05713 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/NumberResult.cpp @@ -0,0 +1,102 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * NumberResult + * Represents the a number as the result of evaluating an Expr + * @author Keith Visco +**/ + +#include "ExprResult.h" + +/** + * Default Constructor +**/ +NumberResult::NumberResult() { + value = 0.0; +} //-- NumberResult + +NumberResult::NumberResult(const NumberResult& nbrResult) { + this->value = nbrResult.getValue(); +} //-- NumberResult + +/** + * Creates a new NumberResult with the value of the given double parameter + * @param dbl the double to use for initialization of this NumberResult's value +**/ +NumberResult::NumberResult(double dbl) { + this->value = dbl; +} //-- NumberResult + +/** + * Returns the value of this NumberResult + * @return the value of this NumberResult +**/ +double NumberResult::getValue() const { + return this->value; +} //-- getValue + +/** + * +**/ +MBool NumberResult::isNaN() const { + return Double::isNaN(value); +} //-- isNaN +/** + * Sets the value of this NumberResult + * @param dbl the double to use for this NumberResult's value +**/ +void NumberResult::setValue(double dbl) { + this->value = dbl; +} //-- setValue + +/** + * Sets the value of this NumberResult + * @param nbrResult the NumberResult to use for setting this NumberResult's value +**/ +void NumberResult::setValue(const NumberResult& nbrResult) { + this->value = nbrResult.getValue(); +} //-- setValue + +/* + * Virtual Methods from ExprResult +*/ + +short NumberResult::getResultType() { + return ExprResult::NUMBER; +} //-- getResultType + +void NumberResult::stringValue(String& str) { + int intVal = (int)value; + if (intVal == value) { //-- no fraction + Integer::toString(intVal, str); + } + else Double::toString(value, str); +} //-- stringValue + +MBool NumberResult::booleanValue() { + return (MBool)(this->value != 0.0); +} //-- booleanValue + +double NumberResult::numberValue() { + return this->value; +} //-- numberValue + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/ParentExpr.cpp b/mozilla/extensions/transformiix/source/xsl/expr/ParentExpr.cpp new file mode 100644 index 00000000000..3f4cba82a14 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/ParentExpr.cpp @@ -0,0 +1,53 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * @author Keith Visco +**/ +#include "Expr.h" + +/** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation +**/ +ExprResult* ParentExpr::evaluate(Node* context, ContextState* cs) { + NodeSet* nodeSet = new NodeSet(); + if ( !context ) return nodeSet; + Node* node = context->getParentNode(); + if (node) nodeSet->add(node); + return nodeSet; +} //-- evaluate + +/** + * Returns the String representation of this NodeExpr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this NodeExpr. +**/ +void ParentExpr::toString(String& dest) { + dest.append(".."); +} //-- toString + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/Parser.cpp b/mozilla/extensions/transformiix/source/xsl/expr/Parser.cpp new file mode 100644 index 00000000000..41c76a1605d --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/Parser.cpp @@ -0,0 +1,176 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * Test App for Expressions + * @author Keith Visco +**/ + +#include "Expr.h" +#include "ExprLexer.h" +#include "ExprParser.h" +#include "String.h" +#include "NamedMap.h" +#include + +void main(int argc, char** argv) { + + + cout <value; + + //-- do padding + for ( int i = token->value.length(); i < 20; i++) cout<<" "; + + //-- print token type + switch (token->type) { + case Token::AT_SIGN: + cout << "#AT_SIGN"; + break; + case Token::PARENT_OP : + cout<<"#PARENT_OP"; + break; + case Token::ANCESTOR_OP : + cout<<"#ANCESTOR_OP"; + break; + case Token::L_PAREN : + cout<<"#L_PAREN"; + break; + case Token::R_PAREN : + cout<<"#R_PAREN"; + break; + case Token::L_BRACKET: + cout<<"#L_BRACKET"; + break; + case Token::R_BRACKET: + cout<<"#R_BRACKET"; + break; + case Token::COMMA: + cout<<"#COMMA"; + break; + case Token::LITERAL: + cout<<"#LITERAL"; + break; + case Token::CNAME: + cout<<"#CNAME"; + break; + case Token::COMMENT: + cout<<"#COMMENT"; + break; + case Token::NODE: + cout<<"#NODE"; + break; + case Token::PI: + cout<<"#PI"; + break; + case Token::TEXT: + cout<<"#TEXT"; + break; + case Token::FUNCTION_NAME: + cout<<"#FUNCTION_NAME"; + break; + case Token::WILD_CARD: + cout << "#WILDCARD"; + break; + case Token::NUMBER: + cout << "#NUMBER"; + break; + case Token::PARENT_NODE : + cout << "#PARENT_NODE"; + break; + case Token::SELF_NODE : + cout << "#SELF_NODE"; + break; + case Token::VAR_REFERENCE: + cout << "#VAR_REFERENCE"; + case Token::AXIS_IDENTIFIER: + cout << "#AXIS_IDENTIFIER"; + break; + default: + if ( lexer.isOperatorToken(token) ) { + cout << "#operator"; + } + else cout<<"#unknown"; + break; + } + } + else cout<<"NULL"; + cout<toString(resultString); + cout << "result: "<toString(resultString); + cout << "result of avt: "<hasNext() ) { + iter->next(); + PathExprItem* pxi = (PathExprItem*)iter->remove(); + delete pxi->pExpr; + delete pxi; + } + delete iter; +} //-- ~PathExpr + +/** + * Adds the PatternExpr to this PathExpr + * @param expr the Expr to add to this PathExpr + * @param index the index at which to add the given Expr +**/ +void PathExpr::addPatternExpr(int index, PatternExpr* expr, short ancestryOp) { + if (expr) { + PathExprItem* pxi = new PathExprItem; + pxi->pExpr = expr; + pxi->ancestryOp = ancestryOp; + expressions.insert(index, pxi); + } +} //-- addPattenExpr + +/** + * Adds the PatternExpr to this PathExpr + * @param expr the Expr to add to this PathExpr +**/ +void PathExpr::addPatternExpr(PatternExpr* expr, short ancestryOp) { + if (expr) { + PathExprItem* pxi = new PathExprItem; + pxi->pExpr = expr; + pxi->ancestryOp = ancestryOp; + expressions.add(pxi); + } +} //-- addPattenExpr + +MBool PathExpr::isAbsolute() { + if ( expressions.getLength() > 0 ) { + ListIterator* iter = expressions.iterator(); + PathExprItem* pxi = (PathExprItem*)iter->next(); + delete iter; + return (pxi->ancestryOp != RELATIVE_OP); + } + return MB_FALSE; +} //-- isAbsolute + + //------------------------------------/ + //- Virtual methods from PatternExpr -/ +//------------------------------------/ + +/** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation +**/ +ExprResult* PathExpr::evaluate(Node* context, ContextState* cs) { + //-- add selectExpr functionality here + + if ( (!context) || (expressions.getLength() == 0)) + return new NodeSet(0); + + NodeSet* nodes = new NodeSet(); + + if ((isAbsolute()) && (context->getNodeType() != Node::DOCUMENT_NODE)) + nodes->add(context->getOwnerDocument()); + else + nodes->add(context); + + + ListIterator* iter = expressions.iterator(); + + MBool ancestorMode = MB_FALSE; + while ( iter->hasNext() ) { + + PathExprItem* pxi = (PathExprItem*)iter->next(); + ancestorMode = (ancestorMode || (pxi->ancestryOp == ANCESTOR_OP)); + NodeSet* tmpNodes = 0; + cs->getNodeSetStack()->push(nodes); + for (int i = 0; i < nodes->size(); i++) { + Node* node = nodes->get(i); + NodeSet* xNodes = (NodeSet*) pxi->pExpr->evaluate(node, cs); + if ( tmpNodes ) { + xNodes->copyInto(*tmpNodes); + } + else { + tmpNodes = xNodes; + xNodes = 0; + } + delete xNodes; + //-- handle ancestorMode + if ( ancestorMode ) fromDescendants(pxi->pExpr, node, cs, tmpNodes); + } + delete (NodeSet*) cs->getNodeSetStack()->pop(); + nodes = tmpNodes; + if ( nodes->size() == 0 ) break; + } + delete iter; + return nodes; +} //-- evaluate + +/** + * Selects from the descendants of the context node + * all nodes that match the PatternExpr + * -- this will be moving to a Utility class +**/ +void PathExpr::fromDescendants + (PatternExpr* pExpr, Node* context, ContextState* cs, NodeSet* nodes) +{ + + if (( !context ) || (! pExpr )) return; + + NodeList* nl = context->getChildNodes(); + for (int i = 0; i < nl->getLength(); i++) { + Node* child = nl->item(i); + if (pExpr->matches(child, context, cs)) + nodes->add(child); + //-- check childs descendants + if (child->hasChildNodes()) + fromDescendants(pExpr, child, cs, nodes); + } +} //-- fromDescendants + +/** + * Returns the default priority of this Pattern based on the given Node, + * context Node, and ContextState. + * If this pattern does not match the given Node under the current context Node and + * ContextState then Negative Infinity is returned. +**/ +double PathExpr::getDefaultPriority(Node* node, Node* context, ContextState* cs) { + + if ( matches(node, context, cs) ) { + int size = expressions.getLength(); + if ( size == 1) { + ListIterator* iter = expressions.iterator(); + PathExprItem* pxi = (PathExprItem*)iter->next(); + delete iter; + return pxi->pExpr->getDefaultPriority(node, context, cs); + } + else if ( size > 1 ) { + return 0.5; + } + } + return Double::NEGATIVE_INFINITY; +} //-- getDefaultPriority + +/** + * Determines whether this PatternExpr matches the given node within + * the given context +**/ +MBool PathExpr::matches(Node* node, Node* context, ContextState* cs) { + NodeSet* nodeSet = (NodeSet*) evaluate(context, cs); + MBool result = nodeSet->contains(node); + delete nodeSet; + return result; +} //-- matches + + +/** + * Returns the String representation of this PatternExpr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this PatternExpr. +**/ +void PathExpr::toString(String& dest) { + ListIterator* iter = expressions.iterator(); + while ( iter->hasNext() ) { + //-- set operator + PathExprItem* pxi = (PathExprItem*)iter->next(); + switch ( pxi->ancestryOp ) { + case ANCESTOR_OP: + dest.append("//"); + break; + case PARENT_OP: + dest.append('/'); + break; + default: + break; + } + pxi->pExpr->toString(dest); + } + delete iter; +} //-- toString + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/PredicateList.cpp b/mozilla/extensions/transformiix/source/xsl/expr/PredicateList.cpp new file mode 100644 index 00000000000..809c47cafa9 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/PredicateList.cpp @@ -0,0 +1,137 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "Expr.h" + +/** + * Represents an ordered list of Predicates, + * for use with Step and Filter Expressions + * @author Keith Visco +**/ +//-- PredicateList Implementation --/ + +PredicateList::PredicateList() { +} //-- PredicateList + +/** + * Destructor, will delete all Expressions in the list, so remove + * any you may need +**/ +PredicateList::~PredicateList() { + //cout << "-PredicateList() - start"<hasNext() ) { + iter->next(); + Expr* expr = (Expr*) iter->remove(); + delete expr; + } + delete iter; + //cout << "~PredicateList() - end"<size()); + + Stack* nsStack = cs->getNodeSetStack(); + nsStack->push(nodes); + while ( iter->hasNext() ) { + int nIdx = 0; + + Expr* expr = (Expr*) iter->next(); + //-- filter each node currently in the NodeSet + for (nIdx = 0; nIdx < nodes->size(); nIdx++) { + + Node* node = nodes->get(nIdx); + + //-- if expr evaluates to true using the node as it's context, + //-- then we can keep it, otherwise add to remove list + ExprResult* exprResult = expr->evaluate(node,cs); + if ( !exprResult ) { + cout << "ExprResult == null" << endl; + } + else { + switch(exprResult->getResultType()) { + case ExprResult::NUMBER : + { + //-- handle default position() + int position = nodes->indexOf(node)+1; + if (( position <= 0 ) || + ( ((double)position) != exprResult->numberValue())) + remNodes.add(node); + + break; + } + default: + if (! exprResult->booleanValue() ) remNodes.add(node); + break; + } + } + } + //-- remove unmatched nodes + for (nIdx = 0; nIdx < remNodes.size(); nIdx++) + nodes->remove(remNodes.get(nIdx)); + //-- clear remove list + remNodes.clear(); + } + nsStack->pop(); + delete iter; +} //-- evaluatePredicates + +/** + * returns true if this predicate list is empty +**/ +MBool PredicateList::isEmpty() { + return (MBool)(predicates.getLength()>0); +} //-- isEmpty + +/** + * Removes the given Expr from the list + * @param expr the Expr to remove from the list +**/ +Expr* PredicateList::remove(Expr* expr) { + return (Expr*)predicates.remove(expr); +} //-- remove + +void PredicateList::toString(String& dest) { + + ListIterator* iter = predicates.iterator(); + + while ( iter->hasNext() ) { + Expr* expr = (Expr*) iter->next(); + dest.append("["); + expr->toString(dest); + dest.append("]"); + } + delete iter; + +} //-- toString + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/RelationalExpr.cpp b/mozilla/extensions/transformiix/source/xsl/expr/RelationalExpr.cpp new file mode 100644 index 00000000000..d72962ffb35 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/RelationalExpr.cpp @@ -0,0 +1,135 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "Expr.h" + + //------------------/ + //- RelationalExpr -/ +//------------------/ + +RelationalExpr::RelationalExpr() { + this->op = EQUAL; + this->leftExpr = 0; + this->rightExpr = 0; +} //-- RelationalExpr + +RelationalExpr::RelationalExpr(Expr* leftExpr, Expr* rightExpr, short op) { + this->op = op; + this->leftExpr = leftExpr; + this->rightExpr = rightExpr; +} //-- RelationalExpr + +RelationalExpr::~RelationalExpr() { + delete leftExpr; + delete rightExpr; +} //-- ~RelationalExpr + +/** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation +**/ +ExprResult* RelationalExpr::evaluate(Node* context, ContextState* cs) { + + + double rightDbl = Double::NaN; + ExprResult* exprRes = 0; + + if ( rightExpr ) { + exprRes = rightExpr->evaluate(context, cs); + if ( exprRes ) rightDbl = exprRes->numberValue(); + delete exprRes; + } + + double leftDbl = Double::NaN; + + if ( leftExpr ) { + exprRes = leftExpr->evaluate(context, cs); + if ( exprRes ) leftDbl = exprRes->numberValue(); + delete exprRes; + } + + MBool result = MB_FALSE; + + switch ( op ) { + case NOT_EQUAL: + result = (MBool) (leftDbl != rightDbl); + break; + case LESS_THAN: + result = (MBool) (leftDbl < rightDbl); + break; + case LESS_OR_EQUAL: + result = (MBool) (leftDbl <= rightDbl); + break; + case GREATER_THAN : + result = (MBool) (leftDbl > rightDbl); + break; + case GREATER_OR_EQUAL: + result = (MBool) (leftDbl >= rightDbl); + break; + default: + result = (MBool) (leftDbl == rightDbl); + break; + } + return new BooleanResult(result); +} //-- evaluate + +/** + * Returns the String representation of this Expr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this Expr. +**/ +void RelationalExpr::toString(String& str) { + + if ( leftExpr ) leftExpr->toString(str); + else str.append("null"); + + switch ( op ) { + case NOT_EQUAL: + str.append("!="); + break; + case LESS_THAN: + str.append("<"); + break; + case LESS_OR_EQUAL: + str.append("<="); + break; + case GREATER_THAN : + str.append(">"); + break; + case GREATER_OR_EQUAL: + str.append(">="); + break; + default: + str.append("="); + break; + } + + if ( rightExpr ) rightExpr->toString(str); + else str.append("null"); + +} //-- toString + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/RootExpr.cpp b/mozilla/extensions/transformiix/source/xsl/expr/RootExpr.cpp new file mode 100644 index 00000000000..49bee44a059 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/RootExpr.cpp @@ -0,0 +1,77 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "Expr.h" + +MBool RootExpr::isAbsolute() { + return MB_TRUE; +} //-- isAbsolute + +/** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation +**/ +ExprResult* RootExpr::evaluate(Node* context, ContextState* cs) { + NodeSet* nodeSet = new NodeSet(); + if ( !context ) return nodeSet; + nodeSet->add(context->getOwnerDocument()); + return nodeSet; +} //-- evaluate + +/** + * Returns the default priority of this Pattern based on the given Node, + * context Node, and ContextState. + * If this pattern does not match the given Node under the current context Node and + * ContextState then Negative Infinity is returned. +**/ +double RootExpr::getDefaultPriority(Node* node, Node* context, ContextState* cs) { + if ( matches(node, context, cs) ) { + return 0.5; + } + else return Double::NEGATIVE_INFINITY; +} //-- getDefaultPriority + +/** + * Determines whether this NodeExpr matches the given node within + * the given context +**/ +MBool RootExpr::matches(Node* node, Node* context, ContextState* cs) { + if ( node ) { + return (MBool) (node->getNodeType() == Node::DOCUMENT_NODE); + } + return MB_FALSE; +} //-- matches + +/** + * Returns the String representation of this PatternExpr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this PatternExpr. +**/ +void RootExpr::toString(String& dest) { + dest.append('/'); +} //-- toString + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/StringExpr.cpp b/mozilla/extensions/transformiix/source/xsl/expr/StringExpr.cpp new file mode 100644 index 00000000000..97148b4fb52 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/StringExpr.cpp @@ -0,0 +1,73 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "Expr.h" + +/** + * StringExpr + * @author Keith Visco +**/ + +/** + * Creates a new StringExpr +**/ +StringExpr::StringExpr() {}; + +StringExpr::StringExpr(String& value) { + //-- copy value + this->value = value; +} //-- StringExpr + +StringExpr::StringExpr(const String& value) { + //-- copy value + this->value.append(value); +} //-- StringExpr + +/** + * Default Destructor +**/ +StringExpr::~StringExpr() {}; + +/** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation +**/ +ExprResult* StringExpr::evaluate(Node* context, ContextState* cs) { + return new StringResult(value); +} //-- evaluate + +/** + * Returns the String representation of this Expr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this Expr. +**/ +void StringExpr::toString(String& str) { + str.append('\''); + str.append(value); + str.append('\''); +} //-- toString + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/StringFunctionCall.cpp b/mozilla/extensions/transformiix/source/xsl/expr/StringFunctionCall.cpp new file mode 100644 index 00000000000..c36ca70d4cd --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/StringFunctionCall.cpp @@ -0,0 +1,236 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * StringFunctionCall + * A representation of the XPath String funtions + * @author Keith Visco +**/ + +#include "FunctionLib.h" + +/** + * Creates a default StringFunctionCall. The string() function + * is the default +**/ +StringFunctionCall::StringFunctionCall() : FunctionCall(STRING_FN) { + type = STRING; +} //-- StringFunctionCall + +/** + * Creates a StringFunctionCall of the given type +**/ +StringFunctionCall::StringFunctionCall(short type) : FunctionCall() { + this->type = type; + switch ( type ) { + case CONCAT: + FunctionCall::setName(CONCAT_FN); + break; + case CONTAINS: + FunctionCall::setName(CONTAINS_FN); + break; + case STARTS_WITH: + FunctionCall::setName(STARTS_WITH_FN); + break; + case STRING_LENGTH: + FunctionCall::setName(STRING_LENGTH_FN); + break; + case SUBSTRING: + FunctionCall::setName(SUBSTRING_FN); + break; + case SUBSTRING_AFTER: + FunctionCall::setName(SUBSTRING_AFTER_FN); + break; + case SUBSTRING_BEFORE: + FunctionCall::setName(SUBSTRING_BEFORE_FN); + break; + case TRANSLATE: + FunctionCall::setName(TRANSLATE_FN); + break; + default: + FunctionCall::setName(STRING_FN); + break; + } +} //-- StringFunctionCall + +/** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation +**/ +ExprResult* StringFunctionCall::evaluate(Node* context, ContextState* cs) { + ListIterator* iter = params.iterator(); + Int32 argc = params.getLength(); + String err; + ExprResult* result = 0; + switch ( type ) { + case CONCAT : + if ( requireParams(2, cs) ) { + String resultStr; + while(iter->hasNext()) { + evaluateToString((Expr*)iter->next(),context, cs, resultStr); + } + result = new StringResult(resultStr); + } + else result = new StringResult(""); + break; + case CONTAINS : + if ( requireParams(2, 2, cs) ) { + String arg1, arg2; + evaluateToString((Expr*)iter->next(),context, cs, arg1); + evaluateToString((Expr*)iter->next(),context, cs, arg2); + result = new BooleanResult((MBool)(arg1.indexOf(arg2) >= 0)); + } + else result = new BooleanResult(MB_FALSE); + break; + + case STARTS_WITH : + if ( requireParams(2, 2, cs) ) { + String arg1, arg2; + evaluateToString((Expr*)iter->next(),context, cs, arg1); + evaluateToString((Expr*)iter->next(),context, cs, arg2); + result = new BooleanResult((MBool)(arg1.indexOf(arg2) == 0)); + } + else result = new BooleanResult(MB_FALSE); + break; + case STRING_LENGTH: + if ( requireParams(0, 1, cs) ) { + String resultStr; + if ( argc == 1) { + evaluateToString((Expr*)iter->next(),context, cs, resultStr); + } + else XMLDOMUtils::getNodeValue(context, &resultStr); + result = new NumberResult( (double) resultStr.length()); + } + else result = new NumberResult(0.0); + break; + case SUBSTRING: + if ( requireParams(2, 3, cs) ) { + String src; + evaluateToString((Expr*)iter->next(),context, cs, src); + double dbl = evaluateToNumber((Expr*)iter->next(), context, cs); + + //-- check for NaN + if ( Double::isNaN(dbl)) { + result = new StringResult(""); + break; + } + + Int32 startIdx = (Int32)ceil(dbl); + Int32 endIdx = src.length(); + if ( argc == 3) { + dbl += evaluateToNumber((Expr*)iter->next(),context, cs); + if (dbl == Double::POSITIVE_INFINITY) endIdx++; + else if ( dbl == Double::NEGATIVE_INFINITY ) endIdx = 0; + else endIdx = (Int32)floor(dbl); + } + String resultStr; + //-- strings are indexed starting at 1 for XSL + //-- adjust to a 0-based index + if (startIdx > 0) startIdx--; + else if (startIdx == 0 ) endIdx--; + else startIdx=0; + src.subString(startIdx,endIdx,resultStr); + result = new StringResult(resultStr); + } + else result = new StringResult(""); + break; + + case SUBSTRING_AFTER: + if ( requireParams(2, 2, cs) ) { + String arg1, arg2; + evaluateToString((Expr*)iter->next(),context, cs, arg1); + evaluateToString((Expr*)iter->next(),context, cs, arg2); + Int32 idx = arg1.indexOf(arg2); + if ((idx >= 0)&&(idxnext(),context, cs, arg1); + evaluateToString((Expr*)iter->next(),context, cs, arg2); + Int32 idx = arg1.indexOf(arg2); + if ((idx >= 0)&&(idxnext(),context, cs, src); + evaluateToString((Expr*)iter->next(),context, cs, oldChars); + evaluateToString((Expr*)iter->next(),context, cs, newChars); + Int32 size = src.length(); + char* chars = new char[size+1]; + src.toChar(chars); + src.clear(); + Int32 newIdx = 0; + for (Int32 i = 0; i < size; i++) { + Int32 idx = oldChars.indexOf(chars[i]); + if (idx >= 0) { + UNICODE_CHAR nchar = newChars.charAt(idx); + if (nchar != -1) src.append(nchar); + } + else src.append(chars[i]); + } + return new StringResult(src); + } + result = new StringResult(""); + break; + + default : //-- string( object? ) + if ( requireParams(0, 1, cs) ) { + String resultStr; + if (iter->hasNext()) { + evaluateToString((Expr*)iter->next(),context, cs, resultStr); + } + else { + String temp; + XMLDOMUtils::getNodeValue(context, &temp); + if ( cs->isStripSpaceAllowed(context) ) { + XMLUtils::stripSpace(temp, resultStr); + } + else resultStr.append(temp); + } + result = new StringResult(resultStr); + } + else result = new StringResult(""); + break; + } + delete iter; + return result; +} //-- evaluate + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/StringResult.cpp b/mozilla/extensions/transformiix/source/xsl/expr/StringResult.cpp new file mode 100644 index 00000000000..e9e386cb199 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/StringResult.cpp @@ -0,0 +1,90 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * StringResult + * Represents a String as a Result of evaluating an Expr + * @author Keith Visco +**/ +#include "ExprResult.h" + + +/** + * Default Constructor +**/ +StringResult::StringResult() { +} //-- StringResult + +/** + * Creates a new StringResult with the value of the given String parameter + * @param str the String to use for initialization of this StringResult's value +**/ +StringResult::StringResult(String& str) { + //-- copy str + this->value = str; +} //-- StringResult + +/** + * Creates a new StringResult with the value of the given String parameter + * @param str the String to use for initialization of this StringResult's value +**/ +StringResult::StringResult(const String& str) { + //-- copy str + this->value = str; +} //-- StringResult + +/** + * Returns the value of this StringResult +**/ +String& StringResult::getValue() { + return this->value; +} //-- getValue + +/** + * Sets the value of this StringResult + * @param str the String to use for this StringResult's value +**/ +void StringResult::setValue(const String& str){ + // copy str + this->value = str; +} //-- setValue + +/* + * Virtual Methods from ExprResult +*/ + +short StringResult::getResultType() { + return ExprResult::STRING; +} //-- getResultType + +void StringResult::stringValue(String& str) { + str.append(this->value); +} //-- stringValue + +MBool StringResult::booleanValue() { + return (MBool)(this->value.length()); +} //-- booleanValue + +double StringResult::numberValue() { + Double dbl(value); + return dbl.doubleValue(); +} //-- numberValue + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/TextExpr.cpp b/mozilla/extensions/transformiix/source/xsl/expr/TextExpr.cpp new file mode 100644 index 00000000000..8ae6330d985 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/TextExpr.cpp @@ -0,0 +1,89 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "Expr.h" + +/** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation +**/ +ExprResult* TextExpr::evaluate(Node* context, ContextState* cs) { + + NodeSet* nodeSet = new NodeSet(); + + if ( !context ) return nodeSet; + + NodeList* nl = context->getChildNodes(); + + for (int i = 0; i < nl->getLength(); i++ ) { + Node* node = nl->item(i); + if ( node->getNodeType() == Node::TEXT_NODE ) + nodeSet->add(node); + } + + return nodeSet; +} //-- evaluate + +/** + * Returns the default priority of this Pattern based on the given Node, + * context Node, and ContextState. + * If this pattern does not match the given Node under the current context Node and + * ContextState then Negative Infinity is returned. +**/ +double TextExpr::getDefaultPriority(Node* node, Node* context, ContextState* cs) { + return -0.5; +} //-- getDefaultPriority + +/** + * Returns the type of this NodeExpr + * @return the type of this NodeExpr +**/ +short TextExpr::getType() { + return NodeExpr::TEXT_EXPR; +} //-- getType + +/** + * Determines whether this NodeExpr matches the given node within + * the given context +**/ +MBool TextExpr::matches(Node* node, Node* context, ContextState* cs) { + if ( node ) { + return (MBool) (node->getNodeType() == Node::TEXT_NODE); + } + return MB_FALSE; +} //-- matches + + +/** + * Returns the String representation of this NodeExpr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this NodeExpr. +**/ +void TextExpr::toString(String& dest) { + dest.append("text()"); +} //-- toString + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/UnionExpr.cpp b/mozilla/extensions/transformiix/source/xsl/expr/UnionExpr.cpp new file mode 100644 index 00000000000..31c01e3c82e --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/UnionExpr.cpp @@ -0,0 +1,161 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "Expr.h" + + //-------------/ + //- UnionExpr -/ +//-------------/ + + +/** + * Creates a new UnionExpr +**/ +UnionExpr::UnionExpr() { + //-- do nothing +} + +/** + * Destructor, will delete all Path Expressions +**/ +UnionExpr::~UnionExpr() { + ListIterator* iter = expressions.iterator(); + while ( iter->hasNext() ) { + iter->next(); + delete (PathExpr*)iter->remove(); + } + delete iter; +} //-- ~UnionExpr + +/** + * Adds the PathExpr to this UnionExpr + * @param pathExpr the PathExpr to add to this UnionExpr +**/ +void UnionExpr::addPathExpr(PathExpr* pathExpr) { + if (pathExpr) expressions.add(pathExpr); +} //-- addPathExpr + +/** + * Adds the PathExpr to this UnionExpr + * @param pathExpr the PathExpr to add to this UnionExpr +**/ +void UnionExpr::addPathExpr(int index, PathExpr* pathExpr) { + if (pathExpr) expressions.insert(index, pathExpr); +} //-- addPathExpr + + //------------------------------------/ + //- Virtual methods from PatternExpr -/ +//------------------------------------/ + +/** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation +**/ +ExprResult* UnionExpr::evaluate(Node* context, ContextState* cs) { + + if ( (!context) || (expressions.getLength() == 0)) + return new NodeSet(0); + + NodeSet* nodes = new NodeSet(); + + ListIterator* iter = expressions.iterator(); + + while ( iter->hasNext() ) { + + PathExpr* pExpr = (PathExpr*)iter->next(); + NodeSet* tmpNodes = (NodeSet*)pExpr->evaluate(context, cs); + for (int j = 0; j < tmpNodes->size(); j++) { + nodes->add(tmpNodes->get(j)); + } + delete tmpNodes; + } + + delete iter; + return nodes; +} //-- evaluate + +/** + * Returns the default priority of this Pattern based on the given Node, + * context Node, and ContextState. + * If this pattern does not match the given Node under the current context Node and + * ContextState then Negative Infinity is returned. +**/ +double UnionExpr::getDefaultPriority(Node* node, Node* context, ContextState* cs) { + + //-- find highest priority + double priority = Double::NEGATIVE_INFINITY; + ListIterator* iter = expressions.iterator(); + while ( iter->hasNext() ) { + PathExpr* pExpr = (PathExpr*)iter->next(); + if ( pExpr->matches(node, context, cs) ) { + double tmpPriority = pExpr->getDefaultPriority(node, context, cs); + priority = (tmpPriority > priority) ? tmpPriority : priority; + } + } + delete iter; + return priority; + +} //-- getDefaultPriority + +/** + * Determines whether this UnionExpr matches the given node within + * the given context +**/ +MBool UnionExpr::matches(Node* node, Node* context, ContextState* cs) { + + ListIterator* iter = expressions.iterator(); + + while ( iter->hasNext() ) { + PathExpr* pExpr = (PathExpr*)iter->next(); + if ( pExpr->matches(node, context, cs) ) { + delete iter; + return MB_TRUE; + } + } + delete iter; + return MB_FALSE; +} //-- matches + + +/** + * Returns the String representation of this PatternExpr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this PatternExpr. +**/ +void UnionExpr::toString(String& dest) { + ListIterator* iter = expressions.iterator(); + + short count = 0; + while ( iter->hasNext() ) { + //-- set operator + if (count > 0) dest.append(" | "); + ((PathExpr*)iter->next())->toString(dest); + ++count; + } + delete iter; +} //-- toString + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/VariableRefExpr.cpp b/mozilla/extensions/transformiix/source/xsl/expr/VariableRefExpr.cpp new file mode 100644 index 00000000000..c9cc9377331 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/VariableRefExpr.cpp @@ -0,0 +1,113 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "Expr.h" + + //-------------------/ + //- VariableRefExpr -/ +//-------------------/ + +/** + * Default constructor +**/ +VariableRefExpr::VariableRefExpr() { +} //-- VariableRefExpr + +/** + * Creates a VariableRefExpr with the given variable name +**/ +VariableRefExpr::VariableRefExpr(const String& name) { + this->name = name; +} //-- VariableRefExpr + +/** + * Creates a VariableRefExpr with the given variable name +**/ +VariableRefExpr::VariableRefExpr(String& name) { + this->name = name; +} //-- VariableRefExpr + +/** + * Default destructor +**/ +VariableRefExpr::~VariableRefExpr() { +} //-- ~VariableRefExpr + +/** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation +**/ +ExprResult* VariableRefExpr::evaluate(Node* context, ContextState* cs) { + + ExprResult* exprResult = cs->getVariable(name); + //-- make copy to prevent deletetion + //-- I know, I should add a #copy method to ExprResult, I will + ExprResult* copyOfResult = 0; + + if ( exprResult ) { + switch ( exprResult->getResultType() ) { + //-- BooleanResult + case ExprResult::BOOLEAN : + copyOfResult = new BooleanResult(exprResult->booleanValue()); + break; + //-- NodeSet + case ExprResult::NODESET : + { + NodeSet* src = (NodeSet*)exprResult; + NodeSet* dest = new NodeSet(src->size()); + for ( int i = 0; i < src->size(); i++) + dest->add(src->get(i)); + copyOfResult = dest; + break; + } + //-- NumberResult + case ExprResult::NUMBER : + copyOfResult = new NumberResult(exprResult->numberValue()); + break; + //-- StringResult + default: + StringResult* strResult = new StringResult(); + exprResult->stringValue(strResult->getValue()); + copyOfResult = strResult; + break; + } + } + else copyOfResult = new StringResult(); + + return copyOfResult; +} //-- evaluate + +/** + * Returns the String representation of this Expr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this Expr. +**/ +void VariableRefExpr::toString(String& str) { + str.append('$'); + str.append(name); +} //-- toString + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/WildCardExpr.cpp b/mozilla/extensions/transformiix/source/xsl/expr/WildCardExpr.cpp new file mode 100644 index 00000000000..274585157d0 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/WildCardExpr.cpp @@ -0,0 +1,97 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "Expr.h" + +/** + * This class represents a WildCardExpr as defined by the XSL + * Working Draft + *
+ * 
+ * @author Keith Visco + *
This class was ported from XSL:P, an open source Java based XSL processor +**/ + +/** + * Evaluates this Expr based on the given context node and processor state + * @param context the context node for evaluation of this Expr + * @param ps the ContextState containing the stack information needed + * for evaluation + * @return the result of the evaluation +**/ +ExprResult* WildCardExpr::evaluate(Node* context, ContextState* cs) { + + NodeSet* nodeSet = new NodeSet(); + + if ( !context ) return nodeSet; + + NodeList* nl = context->getChildNodes(); + + for (int i = 0; i < nl->getLength(); i++ ) { + Node* node = nl->item(i); + if ( node->getNodeType() == Node::ELEMENT_NODE ) + nodeSet->add(node); + } + return nodeSet; +} //-- evaluate + +/** + * Returns the default priority of this Pattern based on the given Node, + * context Node, and ContextState. + * If this pattern does not match the given Node under the current context Node and + * ContextState then Negative Infinity is returned. +**/ +double WildCardExpr::getDefaultPriority(Node* node, Node* context, ContextState* cs) { + return -0.5; +} //-- getDefaultPriority + +/** + * Returns the type of this NodeExpr + * @return the type of this NodeExpr +**/ +short WildCardExpr::getType() { + return NodeExpr::WILD_CARD; +} //-- getType + +/** + * Determines whether this NodeExpr matches the given node within + * the given context +**/ +MBool WildCardExpr::matches(Node* node, Node* context, ContextState* cs) { + if ( node ) { + return (MBool) (node->getNodeType() == Node::ELEMENT_NODE); + } + return MB_FALSE; +} //-- matches + + +/** + * Returns the String representation of this NodeExpr. + * @param dest the String to use when creating the String + * representation. The String representation will be appended to + * any data in the destination String, to allow cascading calls to + * other #toString() methods for Expressions. + * @return the String representation of this NodeExpr. +**/ +void WildCardExpr::toString(String& dest) { + dest.append("*"); +} //-- toString + diff --git a/mozilla/extensions/transformiix/source/xsl/expr/makefile.win b/mozilla/extensions/transformiix/source/xsl/expr/makefile.win new file mode 100644 index 00000000000..3b789aca9b5 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/makefile.win @@ -0,0 +1,109 @@ +#!nmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH=..\..\..\..\..\.. + +LIBRARY_NAME=transformix_xsl_expr +MODULE=transformix +REQUIRES=xpcom raptor + +CPPSRCS= \ + AdditiveExpr.cpp \ + AttributeExpr.cpp \ + AttributeValueTemplate.cpp \ + BasicNodeExpr.cpp \ + BooleanFunctionCall.cpp \ + BooleanResult.cpp \ + ElementExpr.cpp \ + ErrorFunctionCall.cpp \ + ExprLexer.cpp \ + ExprParser.cpp \ + FilterExpr.cpp \ + FunctionCall.cpp \ + IdentityExpr.cpp \ + LocationStep.cpp \ + MultiplicativeExpr.cpp \ + NodeSetFunctionCall.cpp \ + NumberExpr.cpp \ + NumberResult.cpp \ + ParentExpr.cpp \ + Parser.cpp \ + PathExpr.cpp \ + PredicateList.cpp \ + RelationalExpr.cpp \ + RootExpr.cpp \ + StringExpr.cpp \ + StringFunctionCall.cpp \ + StringResult.cpp \ + TextExpr.cpp \ + UnionExpr.cpp \ + VariableRefExpr.cpp \ + WildCardExpr.cpp \ + $(NULL) + +CPP_OBJS= \ + .\$(OBJDIR)\AdditiveExpr.obj \ + .\$(OBJDIR)\AttributeExpr.obj \ + .\$(OBJDIR)\AttributeValueTemplate.obj \ + .\$(OBJDIR)\BasicNodeExpr.obj \ + .\$(OBJDIR)\BooleanFunctionCall.obj \ + .\$(OBJDIR)\BooleanResult.obj \ + .\$(OBJDIR)\ElementExpr.obj \ + .\$(OBJDIR)\ErrorFunctionCall.obj \ + .\$(OBJDIR)\ExprLexer.obj \ + .\$(OBJDIR)\ExprParser.obj \ + .\$(OBJDIR)\FilterExpr.obj \ + .\$(OBJDIR)\FunctionCall.obj \ + .\$(OBJDIR)\IdentityExpr.obj \ + .\$(OBJDIR)\LocationStep.obj \ + .\$(OBJDIR)\MultiplicativeExpr.obj \ + .\$(OBJDIR)\NodeSetFunctionCall.obj \ + .\$(OBJDIR)\NumberExpr.obj \ + .\$(OBJDIR)\NumberResult.obj \ + .\$(OBJDIR)\ParentExpr.obj \ + .\$(OBJDIR)\Parser.obj \ + .\$(OBJDIR)\PathExpr.obj \ + .\$(OBJDIR)\PredicateList.obj \ + .\$(OBJDIR)\RelationalExpr.obj \ + .\$(OBJDIR)\RootExpr.obj \ + .\$(OBJDIR)\StringExpr.obj \ + .\$(OBJDIR)\StringFunctionCall.obj \ + .\$(OBJDIR)\StringResult.obj \ + .\$(OBJDIR)\TextExpr.obj \ + .\$(OBJDIR)\UnionExpr.obj \ + .\$(OBJDIR)\VariableRefExpr.obj \ + .\$(OBJDIR)\WildCardExpr.obj \ + $(NULL) + +EXPORTS = \ + $(NULL) + +LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor -I..\..\base -I..\util -I..\..\xml\dom \ + -I..\..\xml -I ..\..\xsl + +LCFLAGS = \ + $(LCFLAGS) \ + $(DEFINES) \ + $(NULL) + +include <$(DEPTH)\config\rules.mak> + +libs:: $(LIBRARY) + $(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib + +clobber:: + rm -f $(DIST)\lib\$(LIBRARY_NAME).lib diff --git a/mozilla/extensions/transformiix/source/xsl/expr/parser.mk b/mozilla/extensions/transformiix/source/xsl/expr/parser.mk new file mode 100644 index 00000000000..ce58ae796ae --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/expr/parser.mk @@ -0,0 +1,28 @@ + +CC = g++ + +ROOT_PATH = ../.. +BASE_PATH = $(ROOT_PATH)/base +XML_PATH = $(ROOT_PATH)/xml +DOM_PATH = $(XML_PATH)/dom +XSL_PATH = $(ROOT_PATH)/xsl +XSLUTIL_PATH = $(XSL_PATH)/util + +INCLUDE_PATHS = -I . \ + -I $(BASE_PATH) \ + -I $(XML_PATH) \ + -I $(DOM_PATH) \ + -I $(XSL_PATH) \ + -I $(XSLUTIL_PATH) \ + -I- + +OBJS = *.o \ + $(BASE_PATH)/*.o \ + $(XML_PATH)/*.o \ + $(DOM_PATH)/*.o \ + $(XSL_PATH)/Names.o \ + $(XSLUTIL_PATH)/*.o + +target: + $(CC) $(INCLUDE_PATHS) $(OBJS) parser.cpp -o parser.exe + diff --git a/mozilla/extensions/transformiix/source/xsl/makefile.win b/mozilla/extensions/transformiix/source/xsl/makefile.win new file mode 100644 index 00000000000..e3bf38473c0 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/makefile.win @@ -0,0 +1,58 @@ +#!nmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH=..\..\..\..\.. + +DIRS=expr util + +LIBRARY_NAME=transformix_xsl +MODULE=transformix +REQUIRES=xpcom raptor + +DEFINES=-DMOZILLA + +CPPSRCS= \ + XSLProcessor.cpp \ + ProcessorState.cpp \ + Names.cpp \ + $(NULL) + +CPP_OBJS= \ + .\$(OBJDIR)\XSLProcessor.obj \ + .\$(OBJDIR)\ProcessorState.obj \ + .\$(OBJDIR)\Names.obj \ + $(NULL) + +EXPORTS = \ + XSLProcessor.h \ + $(NULL) + +LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor -I.\expr -I.\util -I..\xml\dom \ + -I..\base -I ..\xml + +LCFLAGS = \ + $(LCFLAGS) \ + $(DEFINES) \ + $(NULL) + +include <$(DEPTH)\config\rules.mak> + +libs:: $(LIBRARY) + $(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib + +clobber:: + rm -f $(DIST)\lib\$(LIBRARY_NAME).lib diff --git a/mozilla/extensions/transformiix/source/xsl/util/Makefile b/mozilla/extensions/transformiix/source/xsl/util/Makefile new file mode 100644 index 00000000000..9bd04d12a83 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/util/Makefile @@ -0,0 +1,25 @@ +BASE_PATH = ../../base +EXPR_PATH = ../expr +XML_PATH = ../../xml +DOM_PATH = $(XML_PATH)/dom + +INCLUDE_PATHS = -I . \ + -I $(BASE_PATH) \ + -I $(EXPR_PATH) \ + -I $(DOM_PATH) \ + -I $(XML_PATH) \ + -I- + +ALL_OBJS = NodeSet.o \ + NodeStack.o + + +CC = g++ $(INCLUDE_PATHS) + +target: $(ALL_OBJS) + +NodeSet.o: NodeSet.h NodeSet.cpp + $(CC) -c NodeSet.cpp + +NodeStack.o: NodeStack.h NodeStack.cpp + $(CC) -c NodeStack.cpp \ No newline at end of file diff --git a/mozilla/extensions/transformiix/source/xsl/util/NodeSet.cpp b/mozilla/extensions/transformiix/source/xsl/util/NodeSet.cpp new file mode 100644 index 00000000000..2c5241ce276 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/util/NodeSet.cpp @@ -0,0 +1,340 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "NodeSet.h" +#include +/** + * NodeSet
+ * This class was ported from XSL:P.
+ * @author Keith Visco + *
+ *
+ * Modifications:
+ * 19990806: Larry Fitzpatrick
+ *   - moved initialization of DEFAULT_SIZE from NodeSet.h to here
+ * 
+ * +**/ + + + //-------------/ + //- Constants -/ +//-------------/ +const int NodeSet::DEFAULT_SIZE = 25; + + + //----------------/ + //- Constructors -/ +//----------------/ + +/** + * Creates a new NodeSet with the default Size +**/ +NodeSet::NodeSet() { + initialize(DEFAULT_SIZE); +} //-- NodeSet + +/** + * Creates a new NodeSet with the default Size +**/ +NodeSet::NodeSet(int size) { + initialize(size); +} //-- NodeSet + +/** + * Creates a new NodeSet, copying the Node references from the source + * NodeSet +**/ +NodeSet::NodeSet(const NodeSet& source) { + initialize(source.size()); + source.copyInto(*this); +} //--NodeSet + +/** + * Helper method for Constructors +**/ +void NodeSet::initialize(int size) { + elements = new Node*[size]; + for ( int i = 0; i < size; i++ ) elements[i] = 0; + elementCount = 0; + bufferSize = size; + initialSize = size; +} //-- initialize + +/** + * Destructor for NodeSet +**/ +NodeSet::~NodeSet() { + delete [] elements; +} //-- ~NodeSet + +/** + * Adds the specified Node to this NodeSet if it is not already + * contained within in this NodeSet. + * @param node the Node to add to the NodeSet + * @return true if the Node is added to the NodeSet +**/ +MBool NodeSet::add(Node* node) { + if (!contains(node)) { + if (elementCount == bufferSize) increaseSize(); + elements[elementCount++] = node; + return MB_TRUE; + } + return MB_FALSE; +} //-- add + +/** + * Adds the specified Node to the NodeSet at the specified index, + * as long as the Node is not already contained within the set + * @param node the Node to add to the NodeSet + * @return true if the Node is added to the NodeSet. If the index is + * out of bounds the Node will not be added to the set and false will be returned. +**/ +MBool NodeSet::add(int index, Node* node) +{ + if ((index < 0) || (index > elementCount)) return MB_FALSE; + + if (contains(node)) return MB_FALSE; + + // make sure we have room to add the object + if (elementCount == bufferSize) increaseSize(); + + if (index == elementCount) { + elements[elementCount++] = node; + } + else { + shiftUp(index); + elements[index] = node; + ++elementCount; + } + return MB_TRUE; +} //-- add + +/** + * Removes all elements from the list +**/ +void NodeSet::clear() { + for (int i = 0; i < elementCount; i++) { + elements[i] = 0; + } + elementCount = 0; +} //-- clear + +/** + * Returns true if the specified Node is contained in the set. + * if the specfied Node is null, then if the NodeSet contains a null + * value, true will be returned. + * @param node the element to search the NodeSet for + * @return true if specified Node is contained in the NodeSet +**/ +MBool NodeSet::contains(Node* node) { + return (MBool)(indexOf(node) >= 0); +} //-- contains + +/** + * Copies the elements of this NodeSet, into the destination NodeSet +**/ +void NodeSet::copyInto(NodeSet& dest) const { + for ( int i = 0; i < elementCount; i++ ) dest.add(elements[i]); +} //-- copyInto + +/** + * Compares the specified object with this NodeSet for equality. + * Returns true if and only if the specified Object is a NodeSet + * that is the same size as this NodeSet and all of its associated + * Nodes are contained within this NodeSet. + * @return true if and only if the specified Object is a NodeSet + * that is the same size as this NodeSet and all of its associated + * Nodes are contained within this NodeSet. +**/ +MBool NodeSet::equals(NodeSet* nodeSet) { + if (!nodeSet) return MB_FALSE; + if (nodeSet->size() != size()) return MB_FALSE; + + for (int i = 0; i < size(); i++) { + if (!nodeSet->contains(get(i))) return MB_FALSE; + } + return MB_TRUE; +} //-- equals + +/** + * Returns the Node at the specified position in this NodeSet. + * @param index the position of the Node to return +**/ +Node* NodeSet::get(int index) { + if ((index < 0) || index >= elementCount) return 0; + return elements[index]; +} //-- get + + +/** + * Returns the index of the specified Node, + * or -1 if the Node is not contained in the NodeSet + * @param node the Node to get the index for +**/ +int NodeSet::indexOf(Node* node) { + for (int i = 0; i < elementCount; i++) + if (node == elements[i]) return i; + return -1; +} //-- indexOf + +/** + * Returns true if there are no Nodes in the NodeSet. + * @return true if there are no Nodes in the NodeSet. +**/ +MBool NodeSet::isEmpty() { + return (elementCount == 0) ? MB_TRUE : MB_FALSE; +} //-- isEmpty + +/** + * Removes the Node at the specified index from the NodeSet + * @param index the position in the NodeSet to remove the Node from + * @return the Node that was removed from the list +**/ +Node* NodeSet::remove(int index) { + + if ((index < 0) || (index >= elementCount)) return 0; + + Node* node = elements[index]; + shiftDown(index+1); + --elementCount; + return node; +} //-- remove + +/** + * Removes the the specified Node from the NodeSet + * @param node the Node to remove from the NodeSet + * @return true if the Node was removed from the list +**/ +MBool NodeSet::remove(Node* node) { + int index = indexOf(node); + + if (index > -1) { + remove(index); + } + else return MB_FALSE; + + return MB_TRUE; +} //-- remove + + +/** + * Returns the number of elements in the NodeSet + * @return the number of elements in the NodeSet +**/ +int NodeSet::size() const{ + return elementCount; +} //-- size + +/** + * Creates a String representation of this NodeSet + * @param str the destination string to append the String representation to. +**/ +void NodeSet::toString(String& str) { + str.append("#NodeSet"); +} //-- toString + + //-------------------/ + //- Private Methods -/ +//-------------------/ + +/** + * increase the NodeSet capacity by a factor of its initial size +**/ +void NodeSet::increaseSize() { + + bufferSize += bufferSize; + Node** tmpNodes = elements; + elements = new Node*[bufferSize]; + int i=0; + for (i=0;i < elementCount; i++) elements[i] = tmpNodes[i]; + for (;i elementCount)) return; + + //-- from Java + //-- System.arraycopy(elements, index, elements, index - 1, elementCount - index); + for (int i = index; i < elementCount; i++) { + elements[i-1] = elements[i]; + } + + elements[elementCount-1] = 0; +} //-- shiftDown + +/** + * Shifts all elements at the specified index up by 1 +**/ +void NodeSet::shiftUp(int index) { + if (index == elementCount) return; + if (elementCount == bufferSize) increaseSize(); + + //-- from Java + //-- System.arraycopy(elements, index, elements, index + 1, elementCount - index); + for (int i = elementCount; i > index; i--) { + elements[i] = elements[i-1]; + } +} //-- shiftUp + + //------------------------------------/ + //- Virtual Methods from: ExprResult -/ +//------------------------------------/ + +/** + * Returns the type of ExprResult represented + * @return the type of ExprResult represented +**/ +short NodeSet::getResultType() { + return ExprResult::NODESET; +} //-- getResultType + +/** + * Converts this ExprResult to a Boolean (MBool) value + * @return the Boolean value +**/ +MBool NodeSet::booleanValue() { + return (MBool) (size() > 0); +} //- booleanValue + +/** + * Converts this ExprResult to a Number (double) value + * @return the Number value +**/ +double NodeSet::numberValue() { + return 0.0; +} //-- numberValue + +/** + * Creates a String representation of this ExprResult + * @param str the destination string to append the String representation to. +**/ +void NodeSet::stringValue(String& str) { + if ( size()>0) { + XMLDOMUtils::getNodeValue(get(0), &str); + } +} //-- stringValue + diff --git a/mozilla/extensions/transformiix/source/xsl/util/NodeSet.h b/mozilla/extensions/transformiix/source/xsl/util/NodeSet.h new file mode 100644 index 00000000000..f4959beb71d --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/util/NodeSet.h @@ -0,0 +1,239 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +/** + * NodeSet + * @author Keith Visco + *
+ *
+ * Modifications:
+ * 19990806: Larry Fitzpatrick
+ *   - moved initialization of DEFAULT_SIZE to NodeSet.cpp
+ * 
+ * +**/ + +#ifndef MITREXSL_NODESET_H +#define MITREXSL_NODESET_H + +#include "MITREObject.h" +#include "DOM.h" +#include "ExprResult.h" +#include "XMLDOMUtils.h" + +class NodeSet : public ExprResult { + + +public: + + //----------------/ + //- Constructors -/ + //----------------/ + + /** + * Creates a new NodeSet with the default Size + **/ + NodeSet(); + + /** + * Creates a new NodeSet with the specified Size + **/ + NodeSet(int size); + + /** + * Creates a new NodeSet using the given NodeSet + **/ + NodeSet(const NodeSet& source); + + /** + * Destructor for NodeSet, will not delete Node References + **/ + virtual ~NodeSet(); + + /** + * Adds the specified Node to this NodeSet if it is not already + * contained within in this NodeSet. + * @param node the Node to add to the NodeSet + * @return true if the Node is added to the NodeSet + **/ + MBool add(Node* node); + + /** + * Adds the specified Node to the NodeSet at the specified index, + * as long as the Node is not already contained within the set + * @param node the Node to add to the NodeSet + * @return true if the Node is added to the NodeSet + * @exception IndexOutOfBoundsException + **/ + MBool add(int index, Node* node); + + /** + * Removes all elements from the list + **/ + void clear(); + + /** + * Returns true if the specified Node is contained in the set. + * if the specfied Node is null, then if the NodeSet contains a null + * value, true will be returned. + * @param node the element to search the NodeSet for + * @return true if specified Node is contained in the NodeSet + **/ + MBool contains(Node* node); + + /** + * Copies the elements of this NodeSet, into the destination NodeSet + **/ + void copyInto(NodeSet& dest) const; + + /** + * Compares the specified object with this NodeSet for equality. + * Returns true if and only if the specified Object is a NodeSet + * that is the same size as this NodeSet and all of its associated + * Nodes are contained within this NodeSet. + * @return true if and only if the specified Object is a NodeSet + * that is the same size as this NodeSet and all of its associated + * Nodes are contained within this NodeSet. + **/ + MBool equals(NodeSet* nodeSet); + + /** + * Returns the Node at the specified position in this NodeSet. + * @param index the position of the Node to return + * @exception IndexOutOfBoundsException + **/ + Node* get(int index); + + + /** + * Returns the index of the specified Node, + * or -1 if the Node is not contained in the NodeSet + * @param node the Node to get the index for + **/ + int indexOf(Node* node); + + /** + * Returns true if there are no Nodes in the NodeSet. + * @return true if there are no Nodes in the NodeSet. + **/ + MBool isEmpty(); + + /** + * Removes the Node at the specified index from the NodeSet + * @param index the position in the NodeSet to remove the Node from + * @return the Node that was removed from the list + **/ + Node* remove(int index); + + /** + * Removes the the specified Node from the NodeSet + * @param node the Node to remove from the NodeSet + * @return true if the Node was removed from the list + **/ + MBool remove(Node* node); + + + /** + * Returns the number of elements in the NodeSet + * @return the number of elements in the NodeSet + **/ + int size() const; + + /** + * Creates a String representation of this NodeSet + * @param str the destination string to append the String representation to. + **/ + void toString(String& str); + + //------------------------------------/ + //- Virtual Methods from: ExprResult -/ + //------------------------------------/ + + /** + * Returns the type of ExprResult represented + * @return the type of ExprResult represented + **/ + virtual short getResultType(); + + /** + * Converts this ExprResult to a Boolean (MBool) value + * @return the Boolean value + **/ + virtual MBool booleanValue(); + + /** + * Converts this ExprResult to a Number (double) value + * @return the Number value + **/ + virtual double numberValue(); + + /** + * Creates a String representation of this ExprResult + * @param str the destination string to append the String representation to. + **/ + virtual void stringValue(String& str); + +private: + + + //-------------------/ + //- Private Members -/ + //-------------------/ + + static const int DEFAULT_SIZE; + + Node** elements; + + int initialSize; + int bufferSize; + + /** + * The next available location in the elements array + **/ + int elementCount; + + //-------------------/ + //- Private Methods -/ + //-------------------/ + + /** + * Helper method for constructors + **/ + void initialize(int size); + + /** + * increase the NodeSet capacity by a factor of its initial size + **/ + void increaseSize(); + + /** + * Shifts all elements at the specified index to down by 1 + **/ + void shiftDown(int index); + + /** + * Shifts all elements at the specified index up by 1 + **/ + void shiftUp(int index); + +}; //-- NodeSet + +#endif diff --git a/mozilla/extensions/transformiix/source/xsl/util/NodeStack.cpp b/mozilla/extensions/transformiix/source/xsl/util/NodeStack.cpp new file mode 100644 index 00000000000..667524ea0d8 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/util/NodeStack.cpp @@ -0,0 +1,267 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + +#include "NodeStack.h" +#include +/** + * @author Keith Visco + *
+ *
+ * Modifications:
+ * 19990806: Larry Fitzpatrick
+ *   - moved initialization of DEFAULT_SIZE from NodeStack.h to here
+ * 
+ * +**/ + + + //-------------/ + //- Constants -/ +//-------------/ +const int NodeStack::DEFAULT_SIZE = 25; + + //----------------/ + //- Constructors -/ +//----------------/ + +/** + * Creates a new NodeStack with the default Size +**/ +NodeStack::NodeStack() { + initialize(DEFAULT_SIZE); +} //-- NodeStack + +/** + * Creates a new NodeStack with the specified size +**/ +NodeStack::NodeStack(int size) { + initialize(size); +} //-- NodeStack + +/** + * Helper method for Constructors +**/ +void NodeStack::initialize(int size) { + elements = new Node*[size]; + elementCount = 0; + bufferSize = size; + initialSize = size; +} //-- initialize + +/** + * Destructor for NodeSet +**/ +NodeStack::~NodeStack() { + delete [] elements; +} //-- ~NodeStack + +/** + * Returns the specified Node from the top of this Stack, + * without removing it from the stack. + * @param node the Node to add to the top of the Stack + * @return a pointer to the Node that is the top of this Stack +**/ +Node* NodeStack::peek() { + return get(size()-1); +} //-- peek + +/** + * Removes the specified Node from the top of this Stack. + * @param node the Node to add to the top of the Stack + * @return a pointer to the Node that was the top of this Stack +**/ +Node* NodeStack::pop() { + return remove(size()-1); +} //-- pop + +/** + * Adds the specified Node to the top of this Stack. + * @param node the Node to add to the top of the Stack +**/ +void NodeStack::push(Node* node) { + if (elementCount == bufferSize) increaseSize(); + elements[elementCount++] = node; +} //-- push + + +/** + * Removes all elements from the Stack +**/ +void NodeStack::clear() { + for (int i = 0; i < elementCount; i++) { + elements[i] = 0; + } + elementCount = 0; +} //-- clear + +/** + * Returns true if the specified Node is contained in the Stack. + * if the specfied Node is null, then if the NodeStack contains a null + * value, true will be returned. + * @param node the element to search the NodeStack for + * @return true if specified Node is contained in the NodeStack +**/ +MBool NodeStack::contains(Node* node) { + cout << "NodeStack#contains [enter]\n"; + MBool retVal = (indexOf(node) >= 0) ? MB_TRUE : MB_FALSE; + cout << "NodeStack#contains [exit]\n"; + return retVal; + +} //-- contains + +/** + * Compares the specified NodeStack with this NodeStack for equality. + * Returns true if and only if the specified NodeStack is the same + * size as this NodeSet and all of its associated + * Nodes are contained within this NodeStack in the same order. + * @return true if and only if the specified NodeStack is the + * same size as this NodeStack and all of its associated + * Nodes are contained within this NodeStack in the same order. +**/ +MBool NodeStack::equals(NodeStack* nodeStack) { + if (!nodeStack) return MB_FALSE; + if (nodeStack->size() != size()) return MB_FALSE; + + for (int i = 0; i < size(); i++) { + if (nodeStack->get(i) != get(i)) return MB_FALSE; + } + return MB_TRUE; +} //-- equals + +/** + * Returns the Node at the specified position in this NodeStack. + * @param index the position of the Node to return +**/ +Node* NodeStack::get(int index) { + if ((index < 0) || index >= elementCount) return 0; + return elements[index]; +} //-- get + + +/** + * Returns the index of the specified Node, + * or -1 if the Node is not contained in the NodeStack + * @param node the Node to get the index for +**/ +int NodeStack::indexOf(Node* node) { + + for (int i = 0; i < elementCount; i++) { + if (node == elements[i]) { + return i; + } + } + return -1; +} //-- indexOf + +/** + * Returns true if there are no Nodes in the NodeStack. + * @return true if there are no Nodes in the NodeStack. +**/ +MBool NodeStack::isEmpty() { + return (elementCount == 0) ? MB_TRUE : MB_FALSE; +} //-- isEmpty + +/** + * Removes the Node at the specified index from the NodeStack + * @param index the position in the NodeStack to remove the Node from + * @return the Node that was removed from the NodeStack +**/ +Node* NodeStack::remove(int index) { + + if ((index < 0) || (index > elementCount)) return 0; + Node* node = elements[index]; + shiftDown(index+1); + --elementCount; + return node; +} //-- remove + +/** + * Removes the the specified Node from the NodeStack + * @param node the Node to remove from the NodeStack + * @return true if the Node was removed from the list +**/ +MBool NodeStack::remove(Node* node) { + int index = indexOf(node); + + if (index > -1) { + remove(index); + } + else return MB_FALSE; + + return MB_TRUE; +} //-- remove + + +/** + * Returns the number of elements in the NodeStack + * @return the number of elements in the NodeStack +**/ +int NodeStack::size() { + return elementCount; +} //-- size + + //-------------------/ + //- Private Methods -/ +//-------------------/ + +/** + * increase the NodeStack capacity by a factor of its initial size +**/ +void NodeStack::increaseSize() { + + bufferSize += bufferSize; + Node** tmpNodes = elements; + elements = new Node*[bufferSize]; + for (int i=0;i < elementCount; i++) { + elements[i] = tmpNodes[i]; + } + delete [] tmpNodes; + +} //-- increaseSize + +/** + * Shifts all elements at the specified index to down by 1 +**/ +void NodeStack::shiftDown(int index) { + if ((index <= 0) || (index >= elementCount)) return; + + //-- from Java + //-- System.arraycopy(elements, index, elements, index - 1, elementCount - index); + for (int i = index; i < elementCount; i++) { + elements[index-1] = elements[index]; + } + + elements[elementCount-1] = 0; +} //-- shiftDown + +/** + * Shifts all elements at the specified index up by 1 +**/ +void NodeStack::shiftUp(int index) { + if (index == elementCount) return; + if (elementCount == bufferSize) increaseSize(); + + //-- from Java + //-- System.arraycopy(elements, index, elements, index + 1, elementCount - index); + for (int i = elementCount; i > index; i--) { + elements[i] = elements[i-1]; + } +} //-- shiftUp diff --git a/mozilla/extensions/transformiix/source/xsl/util/NodeStack.h b/mozilla/extensions/transformiix/source/xsl/util/NodeStack.h new file mode 100644 index 00000000000..837b552cc37 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/util/NodeStack.h @@ -0,0 +1,194 @@ +/* + * (C) Copyright The MITRE Corporation 1999 All rights reserved. + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * The program provided "as is" without any warranty express or + * implied, including the warranty of non-infringement and the implied + * warranties of merchantibility and fitness for a particular purpose. + * The Copyright owner will not be liable for any damages suffered by + * you as a result of using the Program. In no event will the Copyright + * owner be liable for any special, indirect or consequential damages or + * lost profits even if the Copyright owner has been advised of the + * possibility of their occurrence. + * + * Please see release.txt distributed with this file for more information. + * + */ + + +/** + * NodeStack + * @author Keith Visco +*
+ *
+ * Modifications:
+ * 19990806: Larry Fitzpatrick
+ *   - moved initialization of DEFAULT_SIZE to NodeStack.cpp
+ * 
+**/ +#include "dom.h" +#include "baseutils.h" + +#ifndef NODESTACK_H +#define NODESTACK_H + +class NodeStack { + + +public: + + //----------------/ + //- Constructors -/ + //----------------/ + + /** + * Creates a new NodeStack with the default Size + **/ + NodeStack(); + + /** + * Creates a new NodeStack with the specified Size + **/ + NodeStack(int size); + + /** + * Destructor for NodeStack, will not delete Node References + **/ + ~NodeStack(); + + /** + * Returns the specified Node from the top of this Stack, + * without removing it from the stack. + * @param node the Node to add to the top of the Stack + * @return a pointer to the Node that is the top of this Stack + **/ + Node* peek(); + void push(Node* node); + Node* pop(); + + /** + * Adds the specified Node to the NodeSet at the specified index, + * as long as the Node is not already contained within the set + * @param node the Node to add to the NodeSet + * @return true if the Node is added to the NodeSet + * @exception IndexOutOfBoundsException + **/ + MBool add(int index, Node* node); + + /** + * Removes all elements from the list + **/ + void clear(); + + /** + * Returns true if the specified Node is contained in the set. + * if the specfied Node is null, then if the NodeSet contains a null + * value, true will be returned. + * @param node the element to search the NodeSet for + * @return true if specified Node is contained in the NodeSet + **/ + MBool contains(Node* node); + + /** + * Compares the specified object with this NodeSet for equality. + * Returns true if and only if the specified Object is a NodeSet + * that is the same size as this NodeSet and all of its associated + * Nodes are contained within this NodeSet. + * @return true if and only if the specified Object is a NodeSet + * that is the same size as this NodeSet and all of its associated + * Nodes are contained within this NodeSet. + **/ + MBool equals(NodeStack* nodeStack); + + /** + * Returns the Node at the specified position in this NodeSet. + * @param index the position of the Node to return + * @exception IndexOutOfBoundsException + **/ + Node* get(int index); + + + /** + * Returns the index of the specified Node, + * or -1 if the Node is not contained in the NodeSet + * @param node the Node to get the index for + **/ + int indexOf(Node* node); + + /** + * Returns true if there are no Nodes in the NodeSet. + * @return true if there are no Nodes in the NodeSet. + **/ + MBool isEmpty(); + + /** + * Removes the Node at the specified index from the NodeSet + * @param index the position in the NodeSet to remove the Node from + * @return the Node that was removed from the list + **/ + Node* remove(int index); + + /** + * Removes the the specified Node from the NodeSet + * @param node the Node to remove from the NodeSet + * @return true if the Node was removed from the list + **/ + MBool remove(Node* node); + + + /** + * Returns the number of elements in the NodeSet + * @return the number of elements in the NodeSet + **/ + int size(); + +private: + + + //-------------------/ + //- Private Members -/ + //-------------------/ + + static const int DEFAULT_SIZE; + + Node** elements; + + int initialSize; + int bufferSize; + + /** + * The next available location in the elements array + **/ + int elementCount; + + //-------------------/ + //- Private Methods -/ + //-------------------/ + + /** + * Helper method for constructors + **/ + void initialize(int size); + + /** + * increase the NodeSet capacity by a factor of its initial size + **/ + void increaseSize(); + + /** + * Shifts all elements at the specified index to down by 1 + **/ + void shiftDown(int index); + + /** + * Shifts all elements at the specified index up by 1 + **/ + void shiftUp(int index); + +}; //-- NodeSet + +#endif diff --git a/mozilla/extensions/transformiix/source/xsl/util/makefile.win b/mozilla/extensions/transformiix/source/xsl/util/makefile.win new file mode 100644 index 00000000000..ea2323cf562 --- /dev/null +++ b/mozilla/extensions/transformiix/source/xsl/util/makefile.win @@ -0,0 +1,51 @@ +#!nmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH=..\..\..\..\..\.. + +LIBRARY_NAME=transformix_xsl_util +MODULE=transformix +REQUIRES=xpcom raptor + +CPPSRCS= \ + NodeSet.cpp \ + NodeStack.cpp \ + $(NULL) + +CPP_OBJS= \ + .\$(OBJDIR)\NodeSet.obj \ + .\$(OBJDIR)\NodeStack.obj \ + $(NULL) + +EXPORTS = \ + $(NULL) + +LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor -I..\..\base -I..\..\xml\dom \ + -I..\expr -I..\..\xml + +LCFLAGS = \ + $(LCFLAGS) \ + $(DEFINES) \ + $(NULL) + +include <$(DEPTH)\config\rules.mak> + +libs:: $(LIBRARY) + $(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib + +clobber:: + rm -f $(DIST)\lib\$(LIBRARY_NAME).lib