dbertoni 2002/09/24 23:51:44
Modified: c/src/XPath XPathFunctionTable.cpp XPathFunctionTable.hpp
Log:
New table implementation.
Revision Changes Path
1.21 +374 -2 xml-xalan/c/src/XPath/XPathFunctionTable.cpp
Index: XPathFunctionTable.cpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XPath/XPathFunctionTable.cpp,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- XPathFunctionTable.cpp 9 Sep 2002 17:26:58 -0000 1.20
+++ XPathFunctionTable.cpp 25 Sep 2002 06:51:44 -0000 1.21
@@ -59,6 +59,10 @@
+#include <cstring>
+
+
+
#include <PlatformSupport/DOMStringHelper.hpp>
@@ -95,8 +99,18 @@
XPathFunctionTable::XPathFunctionTable(bool fCreateTable) :
m_FunctionCollection(),
- m_FunctionNameIndex()
+ m_FunctionNameIndex(),
+ m_functionTable(),
+ m_functionTableEnd(m_functionTable + (sizeof(m_functionTable) /
sizeof(m_functionTable[0])) - 1)
{
+ assert(int(s_functionNamesSize) == eTableSize);
+
+#if defined(XALAN_STRICT_ANSI_HEADERS)
+ std::memset(m_functionTable, 0, sizeof(m_functionTable));
+#else
+ memset(m_functionTable, 0, sizeof(m_functionTable));
+#endif
+
if (fCreateTable == true)
{
CreateTable();
@@ -271,7 +285,7 @@
{
try
{
- m_FunctionCollection.reserve(eDefaultTableSize);
+ m_FunctionCollection.reserve(eTableSize);
// Start with the longest function name, so we only have
// one allocation for this string.
@@ -438,6 +452,7 @@
InstallFunction(
theFunctionName,
FunctionRound());
+
#if 0
std::ofstream theSourceStream("\\foo.cpp");
std::ofstream theHeaderStream("\\foo.hpp");
@@ -479,6 +494,44 @@
+int
+XPathFunctionTable::getFunctionIndex(const XalanDOMString& theName)
+{
+ // Do a binary search...
+ const FunctionNameTableEntry* theFirst = s_functionNames;
+ const FunctionNameTableEntry* theLast = s_lastFunctionName;
+
+ while(theFirst <= theLast)
+ {
+ const FunctionNameTableEntry* const theCurrent =
+ theFirst + (theLast - theFirst) / 2;
+ assert(theCurrent->m_size == length(theCurrent->m_name));
+
+ const int theResult = compare(
+ theName.c_str(),
+ theName.length(),
+ theCurrent->m_name,
+ theCurrent->m_size);
+
+ if (theResult < 0)
+ {
+ theLast = theCurrent - 1;
+ }
+ else if (theResult > 0)
+ {
+ theFirst = theCurrent + 1;
+ }
+ else
+ {
+ return theCurrent - s_functionNames;
+ }
+ }
+
+ return InvalidFunctionNumberID;
+}
+
+
+
XPathExceptionFunctionNotAvailable::XPathExceptionFunctionNotAvailable(int
theFunctionNumber) :
XalanXPathException(TranscodeFromLocalCodePage("The specified function
number is not available: ") + LongToDOMString(theFunctionNumber))
{
@@ -528,6 +581,14 @@
0
};
+const XalanDOMChar XPathFunctionTable::s_key[] =
+{
+ XalanUnicode::charLetter_k,
+ XalanUnicode::charLetter_e,
+ XalanUnicode::charLetter_y,
+ 0
+};
+
const XalanDOMChar XPathFunctionTable::s_not[] =
{
XalanUnicode::charLetter_n,
@@ -677,6 +738,18 @@
0
};
+const XalanDOMChar XPathFunctionTable::s_current[] =
+{
+ XalanUnicode::charLetter_c,
+ XalanUnicode::charLetter_u,
+ XalanUnicode::charLetter_r,
+ XalanUnicode::charLetter_r,
+ XalanUnicode::charLetter_e,
+ XalanUnicode::charLetter_n,
+ XalanUnicode::charLetter_t,
+ 0
+};
+
const XalanDOMChar XPathFunctionTable::s_contains[] =
{
XalanUnicode::charLetter_c,
@@ -690,6 +763,19 @@
0
};
+const XalanDOMChar XPathFunctionTable::s_document[] =
+{
+ XalanUnicode::charLetter_d,
+ XalanUnicode::charLetter_o,
+ XalanUnicode::charLetter_c,
+ XalanUnicode::charLetter_u,
+ XalanUnicode::charLetter_m,
+ XalanUnicode::charLetter_e,
+ XalanUnicode::charLetter_n,
+ XalanUnicode::charLetter_t,
+ 0
+};
+
const XalanDOMChar XPathFunctionTable::s_position[] =
{
XalanUnicode::charLetter_p,
@@ -746,6 +832,22 @@
0
};
+const XalanDOMChar XPathFunctionTable::s_generateId[] =
+{
+ XalanUnicode::charLetter_g,
+ XalanUnicode::charLetter_e,
+ XalanUnicode::charLetter_n,
+ XalanUnicode::charLetter_e,
+ XalanUnicode::charLetter_r,
+ XalanUnicode::charLetter_a,
+ XalanUnicode::charLetter_t,
+ XalanUnicode::charLetter_e,
+ XalanUnicode::charHyphenMinus,
+ XalanUnicode::charLetter_i,
+ XalanUnicode::charLetter_d,
+ 0
+};
+
const XalanDOMChar XPathFunctionTable::s_startsWith[] =
{
XalanUnicode::charLetter_s,
@@ -762,6 +864,24 @@
0
};
+const XalanDOMChar XPathFunctionTable::s_formatNumber[] =
+{
+ XalanUnicode::charLetter_f,
+ XalanUnicode::charLetter_o,
+ XalanUnicode::charLetter_r,
+ XalanUnicode::charLetter_m,
+ XalanUnicode::charLetter_a,
+ XalanUnicode::charLetter_t,
+ XalanUnicode::charHyphenMinus,
+ XalanUnicode::charLetter_n,
+ XalanUnicode::charLetter_u,
+ XalanUnicode::charLetter_m,
+ XalanUnicode::charLetter_b,
+ XalanUnicode::charLetter_e,
+ XalanUnicode::charLetter_r,
+ 0
+};
+
const XalanDOMChar XPathFunctionTable::s_namespaceUri[] =
{
XalanUnicode::charLetter_n,
@@ -838,6 +958,26 @@
0
};
+const XalanDOMChar XPathFunctionTable::s_systemProperty[] =
+{
+ XalanUnicode::charLetter_s,
+ XalanUnicode::charLetter_y,
+ XalanUnicode::charLetter_s,
+ XalanUnicode::charLetter_t,
+ XalanUnicode::charLetter_e,
+ XalanUnicode::charLetter_m,
+ XalanUnicode::charHyphenMinus,
+ XalanUnicode::charLetter_p,
+ XalanUnicode::charLetter_r,
+ XalanUnicode::charLetter_o,
+ XalanUnicode::charLetter_p,
+ XalanUnicode::charLetter_e,
+ XalanUnicode::charLetter_r,
+ XalanUnicode::charLetter_t,
+ XalanUnicode::charLetter_y,
+ 0
+};
+
const XalanDOMChar XPathFunctionTable::s_substringBefore[] =
{
XalanUnicode::charLetter_s,
@@ -858,3 +998,235 @@
XalanUnicode::charLetter_e,
0
};
+
+const XalanDOMChar XPathFunctionTable::s_elementAvailable[] =
+{
+ XalanUnicode::charLetter_e,
+ XalanUnicode::charLetter_l,
+ XalanUnicode::charLetter_e,
+ XalanUnicode::charLetter_m,
+ XalanUnicode::charLetter_e,
+ XalanUnicode::charLetter_n,
+ XalanUnicode::charLetter_t,
+ XalanUnicode::charHyphenMinus,
+ XalanUnicode::charLetter_a,
+ XalanUnicode::charLetter_v,
+ XalanUnicode::charLetter_a,
+ XalanUnicode::charLetter_i,
+ XalanUnicode::charLetter_l,
+ XalanUnicode::charLetter_a,
+ XalanUnicode::charLetter_b,
+ XalanUnicode::charLetter_l,
+ XalanUnicode::charLetter_e,
+ 0
+};
+
+const XalanDOMChar XPathFunctionTable::s_functionAvailable[] =
+{
+ XalanUnicode::charLetter_f,
+ XalanUnicode::charLetter_u,
+ XalanUnicode::charLetter_n,
+ XalanUnicode::charLetter_c,
+ XalanUnicode::charLetter_t,
+ XalanUnicode::charLetter_i,
+ XalanUnicode::charLetter_o,
+ XalanUnicode::charLetter_n,
+ XalanUnicode::charHyphenMinus,
+ XalanUnicode::charLetter_a,
+ XalanUnicode::charLetter_v,
+ XalanUnicode::charLetter_a,
+ XalanUnicode::charLetter_i,
+ XalanUnicode::charLetter_l,
+ XalanUnicode::charLetter_a,
+ XalanUnicode::charLetter_b,
+ XalanUnicode::charLetter_l,
+ XalanUnicode::charLetter_e,
+ 0
+};
+
+const XalanDOMChar XPathFunctionTable::s_unparsedEntityUri[] =
+{
+ XalanUnicode::charLetter_u,
+ XalanUnicode::charLetter_n,
+ XalanUnicode::charLetter_p,
+ XalanUnicode::charLetter_a,
+ XalanUnicode::charLetter_r,
+ XalanUnicode::charLetter_s,
+ XalanUnicode::charLetter_e,
+ XalanUnicode::charLetter_d,
+ XalanUnicode::charHyphenMinus,
+ XalanUnicode::charLetter_e,
+ XalanUnicode::charLetter_n,
+ XalanUnicode::charLetter_t,
+ XalanUnicode::charLetter_i,
+ XalanUnicode::charLetter_t,
+ XalanUnicode::charLetter_y,
+ XalanUnicode::charHyphenMinus,
+ XalanUnicode::charLetter_u,
+ XalanUnicode::charLetter_r,
+ XalanUnicode::charLetter_i,
+ 0
+};
+
+
+typedef XPathFunctionTable::SizeType SizeType;
+typedef XPathFunctionTable::FunctionNameTableEntry FunctionNameTableEntry;
+
+#define XFTBL_SIZE(str) ((sizeof(str) / sizeof(str[0]) - 1))
+
+
+const FunctionNameTableEntry XPathFunctionTable::s_functionNames[] =
+{
+ {
+ s_id,
+ XFTBL_SIZE(s_id)
+ },
+ {
+ s_key,
+ XFTBL_SIZE(s_key)
+ },
+ {
+ s_not,
+ XFTBL_SIZE(s_not)
+ },
+ {
+ s_sum,
+ XFTBL_SIZE(s_sum)
+ },
+ {
+ s_lang,
+ XFTBL_SIZE(s_lang)
+ },
+ {
+ s_last,
+ XFTBL_SIZE(s_last)
+ },
+ {
+ s_name,
+ XFTBL_SIZE(s_name)
+ },
+ {
+ s_true,
+ XFTBL_SIZE(s_true)
+ },
+ {
+ s_count,
+ XFTBL_SIZE(s_count)
+ },
+ {
+ s_false,
+ XFTBL_SIZE(s_false)
+ },
+ {
+ s_floor,
+ XFTBL_SIZE(s_floor)
+ },
+ {
+ s_round,
+ XFTBL_SIZE(s_round)
+ },
+ {
+ s_concat,
+ XFTBL_SIZE(s_concat)
+ },
+ {
+ s_number,
+ XFTBL_SIZE(s_number)
+ },
+ {
+ s_string,
+ XFTBL_SIZE(s_string)
+ },
+ {
+ s_boolean,
+ XFTBL_SIZE(s_boolean)
+ },
+ {
+ s_ceiling,
+ XFTBL_SIZE(s_ceiling)
+ },
+ {
+ s_current,
+ XFTBL_SIZE(s_current)
+ },
+ {
+ s_contains,
+ XFTBL_SIZE(s_contains)
+ },
+ {
+ s_document,
+ XFTBL_SIZE(s_document)
+ },
+ {
+ s_position,
+ XFTBL_SIZE(s_position)
+ },
+ {
+ s_substring,
+ XFTBL_SIZE(s_substring)
+ },
+ {
+ s_translate,
+ XFTBL_SIZE(s_translate)
+ },
+ {
+ s_localName,
+ XFTBL_SIZE(s_localName)
+ },
+ {
+ s_generateId,
+ XFTBL_SIZE(s_generateId)
+ },
+ {
+ s_startsWith,
+ XFTBL_SIZE(s_startsWith)
+ },
+ {
+ s_formatNumber,
+ XFTBL_SIZE(s_formatNumber)
+ },
+ {
+ s_namespaceUri,
+ XFTBL_SIZE(s_namespaceUri)
+ },
+ {
+ s_stringLength,
+ XFTBL_SIZE(s_stringLength)
+ },
+ {
+ s_normalizeSpace,
+ XFTBL_SIZE(s_normalizeSpace)
+ },
+ {
+ s_substringAfter,
+ XFTBL_SIZE(s_substringAfter)
+ },
+ {
+ s_systemProperty,
+ XFTBL_SIZE(s_systemProperty)
+ },
+ {
+ s_substringBefore,
+ XFTBL_SIZE(s_substringBefore)
+ },
+ {
+ s_elementAvailable,
+ XFTBL_SIZE(s_elementAvailable)
+ },
+ {
+ s_functionAvailable,
+ XFTBL_SIZE(s_functionAvailable)
+ },
+ {
+ s_unparsedEntityUri,
+ XFTBL_SIZE(s_unparsedEntityUri)
+ }
+};
+
+
+const FunctionNameTableEntry* const
XPathFunctionTable::s_lastFunctionName =
+ &s_functionNames[sizeof(s_functionNames) / sizeof(s_functionNames[0]) -
1];
+
+
+const SizeType XPathFunctionTable::s_functionNamesSize =
+ sizeof(s_functionNames) / sizeof(s_functionNames[0]);
\ No newline at end of file
1.19 +129 -3 xml-xalan/c/src/XPath/XPathFunctionTable.hpp
Index: XPathFunctionTable.hpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XPath/XPathFunctionTable.hpp,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- XPathFunctionTable.hpp 9 Sep 2002 07:09:19 -0000 1.18
+++ XPathFunctionTable.hpp 25 Sep 2002 06:51:44 -0000 1.19
@@ -65,7 +65,9 @@
#include <algorithm>
+#if !defined(XPATH_FUNCTION_TABLE_NEW)
#include <map>
+#endif
@@ -117,6 +119,7 @@
{
public:
+#if !defined(XPATH_FUNCTION_TABLE_NEW)
#if defined(XALAN_NO_NAMESPACES)
typedef vector<const Function*> CollectionType;
typedef map<XalanDOMString,
@@ -126,9 +129,12 @@
typedef std::vector<const Function*> CollectionType;
typedef std::map<XalanDOMString, int> FunctionNameIndexMapType;
#endif
+#endif
- enum { eDefaultTableSize = 36 };
+ enum { InvalidFunctionNumberID = -1, eTableSize = 36 };
+ typedef size_t SizeType;
+ typedef XalanDOMString::size_type StringSizeType;
typedef DeleteFunctor<Function> DeleteFunctorType;
/**
@@ -161,6 +167,15 @@
const Function&
operator[](const XalanDOMString& theFunctionName) const
{
+#if defined(XPATH_FUNCTION_TABLE_NEW)
+ const int theFunctionID =
+ getFunctionIndex(theFunctionName);
+
+ if (theFunctionID != InvalidFunctionNumberID)
+ {
+ return *m_functionTable[theFunctionID];
+ }
+#else
FunctionNameIndexMapType::const_iterator i =
m_FunctionNameIndex.find(theFunctionName);
@@ -168,6 +183,7 @@
{
return *m_FunctionCollection[(*i).second];
}
+#endif
else
{
throw
XPathExceptionFunctionNotAvailable(theFunctionName);
@@ -183,14 +199,18 @@
const Function&
operator[](int theFunctionID) const
{
+#if defined(XPATH_FUNCTION_TABLE_NEW)
+ assert(theFunctionID >= 0 && theFunction < eTableSize);
+
+ return *m_functionTable[theFunctionID];
+#else
assert(theFunctionID >= 0 &&
CollectionType::size_type(theFunctionID) <
m_FunctionCollection.size());
return *m_FunctionCollection[theFunctionID];
+#endif
}
- enum { InvalidFunctionNumberID = -1 };
-
/**
* Map a function ID to the corresponding name.
*
@@ -202,6 +222,12 @@
{
XalanDOMString theName;
+#if defined(XPATH_FUNCTION_TABLE_NEW)
+ if (theFunctionID >= 0 && theFunction < eTableSize)
+ {
+ theName = s_functionNames[theFunctionID];
+ }
+#else
if (theFunctionID >= 0 &&
CollectionType::size_type(theFunctionID) <
m_FunctionCollection.size())
{
@@ -218,6 +244,7 @@
}
}
}
+#endif
return theName;
}
@@ -231,6 +258,9 @@
int
nameToID(const XalanDOMString& theName) const
{
+#if defined(XPATH_FUNCTION_TABLE_NEW)
+ return getFunctionIndex(theName);
+#else
const FunctionNameIndexMapType::const_iterator i =
m_FunctionNameIndex.find(theName);
@@ -242,6 +272,7 @@
{
return InvalidFunctionNumberID;
}
+#endif
}
/**
@@ -273,7 +304,11 @@
bool
isInstalledFunction(const XalanDOMString& theFunctionName) const
{
+#if defined(XPATH_FUNCTION_TABLE_NEW)
+ if (getFunctionIndex(theFunctionName) !=
InvalidFunctionNumberID)
+#else
if (m_FunctionNameIndex.find(theFunctionName) !=
m_FunctionNameIndex.end())
+#endif
{
return true;
}
@@ -299,6 +334,21 @@
void
getInstalledFunctionNames(InstalledFunctionNameVectorType&
theVector) const
{
+#if defined(XPATH_FUNCTION_TABLE_NEW)
+ XalanDOMString theString;
+
+ for (int i = 0; i < TableSize; ++i)
+ {
+ if (m_functionTable[i] != 0)
+ {
+ theString.assign(
+ s_functionNames[i].m_name,
+ s_functionNames[i].size);
+
+ theVector.push_back(theString);
+ }
+ }
+#else
FunctionNameIndexMapType::const_iterator i =
m_FunctionNameIndex.begin();
@@ -309,7 +359,9 @@
++i;
}
}
+#endif
#else
+
/**
* Add a list of the names of installed functions to a vector of names.
*
@@ -319,6 +371,23 @@
void
getInstalledFunctionNames(OutputIteratorType theIterator) const
{
+#if defined(XPATH_FUNCTION_TABLE_NEW)
+ XalanDOMString theString;
+
+ for (int i = 0; i < TableSize; ++i)
+ {
+ if (m_functionTable[i] != 0)
+ {
+ theString.assign(
+ s_functionNames[i].m_name,
+ s_functionNames[i].size);
+
+ *theIterator = theString;
+
+ ++theIterator;
+ }
+ }
+#else
FunctionNameIndexMapType::const_iterator i =
m_FunctionNameIndex.begin();
@@ -329,18 +398,42 @@
++i;
++theIterator;
}
+#endif
}
#endif
+ struct FunctionNameTableEntry
+ {
+ const XalanDOMChar* m_name;
+
+ StringSizeType m_size;
+ };
+
private:
+ static int
+ getFunctionIndex(const XalanDOMString& theName);
+
+#if !defined(XPATH_FUNCTION_TABLE_NEW)
CollectionType m_FunctionCollection;
FunctionNameIndexMapType m_FunctionNameIndex;
+#endif
+
+ const Function* m_functionTable[eTableSize];
+
+ const Function** const m_functionTableEnd;
+
+ // These are static strings for the functions supported.
+ // Note that the XSLT functions are also here, since it's
+ // just easier to do it this way.
// The string "id"
static const XalanDOMChar s_id[];
+ // The string "key"
+ static const XalanDOMChar s_key[];
+
// The string "not"
static const XalanDOMChar s_not[];
@@ -386,9 +479,15 @@
// The string "ceiling"
static const XalanDOMChar s_ceiling[];
+ // The string "current"
+ static const XalanDOMChar s_current[];
+
// The string "contains"
static const XalanDOMChar s_contains[];
+ // The string "document"
+ static const XalanDOMChar s_document[];
+
// The string "position"
static const XalanDOMChar s_position[];
@@ -401,9 +500,15 @@
// The string "local-name"
static const XalanDOMChar s_localName[];
+ // The string "generate-id"
+ static const XalanDOMChar s_generateId[];
+
// The string "starts-with"
static const XalanDOMChar s_startsWith[];
+ // The string "format-number"
+ static const XalanDOMChar s_formatNumber[];
+
// The string "namespace-uri"
static const XalanDOMChar s_namespaceUri[];
@@ -416,8 +521,29 @@
// The string "substring-after"
static const XalanDOMChar s_substringAfter[];
+ // The string "system-property"
+ static const XalanDOMChar s_systemProperty[];
+
// The string "substring-before"
static const XalanDOMChar s_substringBefore[];
+
+ // The string "element-available"
+ static const XalanDOMChar s_elementAvailable[];
+
+ // The string "function-available"
+ static const XalanDOMChar s_functionAvailable[];
+
+ // The string "unparsed-entity-uri"
+ static const XalanDOMChar s_unparsedEntityUri[];
+
+ // A table of function names.
+ static const FunctionNameTableEntry
s_functionNames[];
+
+ // The last one in the table of function names.
+ static const FunctionNameTableEntry* const s_lastFunctionName;
+
+ // The size of the table.
+ static const SizeType
s_functionNamesSize;
};
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]