26#include <rtl/ustring.hxx>
27#include <rtl/string.hxx>
28#include <rtl/strbuf.hxx>
31#include <tools/datetime.hxx>
33#include <com/sun/star/uno/Reference.hxx>
34#include <com/sun/star/uno/Sequence.hxx>
35#include <com/sun/star/xforms/XModel.hpp>
36#include <com/sun/star/xml/dom/XNode.hpp>
37#include <com/sun/star/xml/dom/XDocument.hpp>
38#include <com/sun/star/lang/XUnoTunnel.hpp>
40#include <boost/lexical_cast.hpp>
41#include <libxml/xpathInternals.h>
56 const char *
name =
reinterpret_cast<char const *
>(xname);
57 if (strcmp(
"boolean-from-string",
name)==0)
59 else if ((strcmp(
"if",
name))==0)
61 else if ((strcmp(
"avg",
name))==0)
63 else if ((strcmp(
"min",
name))==0)
65 else if ((strcmp(
"max",
name))==0)
67 else if ((strcmp(
"count-non-empty",
name))==0)
69 else if ((strcmp(
"index",
name))==0)
71 else if ((strcmp(
"property",
name))==0)
73 else if ((strcmp(
"now",
name))==0)
75 else if ((strcmp(
"days-from-date",
name))==0)
77 else if ((strcmp(
"seconds-from-dateTime",
name))==0)
79 else if ((strcmp(
"seconds",
name))==0)
81 else if ((strcmp(
"months",
name))==0)
83 else if ((strcmp(
"instance",
name))==0)
85 else if ((strcmp(
"current",
name))==0)
94 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
95 xmlChar *pString = xmlXPathPopString(ctxt);
96 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
97 OUString aString(
reinterpret_cast<char*
>(pString), strlen(
reinterpret_cast<char*
>(pString)), RTL_TEXTENCODING_UTF8);
98 if (aString.equalsIgnoreAsciiCase(
"true") ||
99 aString.equalsIgnoreAsciiCase(
"1"))
100 xmlXPathReturnTrue(ctxt);
101 else if (aString.equalsIgnoreAsciiCase(
"false") ||
102 aString.equalsIgnoreAsciiCase(
"0"))
103 xmlXPathReturnFalse(ctxt);
105 XP_ERROR(XPATH_NUMBER_ERROR);
110 if (nargs != 3) XP_ERROR(XPATH_INVALID_ARITY);
111 xmlChar *s2 = xmlXPathPopString(ctxt);
113 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
114 xmlChar *s1 = xmlXPathPopString(ctxt);
115 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
116 bool aBool = xmlXPathPopBoolean(ctxt);
117 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
120 xmlXPathReturnString(ctxt, s1);
122 xmlXPathReturnString(ctxt, s2);
130 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
133 xmlXPathObjectPtr
pObject = valuePop(ctxt);
134 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
136 valuePush(ctxt, xmlXPathObjectCopy(
pObject));
138 xmlXPathSumFunction(ctxt, 1);
139 double nSum = xmlXPathPopNumber(ctxt);
141 valuePush(ctxt, xmlXPathObjectCopy(
pObject));
142 xmlXPathCountFunction(ctxt, 1);
143 double nCount = xmlXPathPopNumber(ctxt);
145 xmlXPathReturnNumber(ctxt, nSum);
146 xmlXPathReturnNumber(ctxt,
nCount);
147 xmlXPathDivValues(ctxt);
154 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
155 xmlNodeSetPtr pNodeSet = xmlXPathPopNodeSet(ctxt);
156 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
158 for (
int i = 0;
i < xmlXPathNodeSetGetLength(pNodeSet);
i++)
160 double nNumber = xmlXPathCastNodeToNumber(xmlXPathNodeSetItem(pNodeSet,
i));
161 if (xmlXPathIsNaN(nNumber))
163 xmlXPathReturnNumber(ctxt, xmlXPathNAN);
168 else if (nNumber < nMinimum)
171 xmlXPathReturnNumber(ctxt, nMinimum);
176 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
177 xmlNodeSetPtr pNodeSet = xmlXPathPopNodeSet(ctxt);
178 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
180 for (
int i = 0;
i < xmlXPathNodeSetGetLength(pNodeSet);
i++)
182 double nNumber = xmlXPathCastNodeToNumber(xmlXPathNodeSetItem(pNodeSet,
i));
183 if (xmlXPathIsNaN(nNumber))
185 xmlXPathReturnNumber(ctxt, xmlXPathNAN);
190 else if (nNumber > nMaximum)
193 xmlXPathReturnNumber(ctxt, nMaximum);
197 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
198 xmlNodeSetPtr pNodeSet = xmlXPathPopNodeSet(ctxt);
199 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
200 sal_Int32 nNotEmpty = 0;
201 for (
int i = 0;
i < xmlXPathNodeSetGetLength(pNodeSet);
i++)
203 const xmlChar *aString = xmlXPathCastNodeToString(xmlXPathNodeSetItem(pNodeSet,
i));
204 if (*aString != 0) nNotEmpty++;
206 xmlXPathReturnNumber(ctxt, nNotEmpty);
221 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
222 xmlChar* pString = xmlXPathPopString(ctxt);
223 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
224 OUString aString(
reinterpret_cast<char*
>(pString), strlen(
reinterpret_cast<char*
>(pString)), RTL_TEXTENCODING_UTF8);
225 if (aString.equalsIgnoreAsciiCase(
"version"))
226 xmlXPathReturnString(ctxt,
reinterpret_cast<xmlChar *
>(
const_cast<char *
>(
"1.0")));
227 else if (aString.equalsIgnoreAsciiCase(
"conformance-level"))
228 xmlXPathReturnString(ctxt,
reinterpret_cast<xmlChar *
>(
const_cast<char *
>(
"conformance")));
230 xmlXPathReturnEmptyString(ctxt);
237 OStringBuffer aDateTimeString;
238 aDateTimeString.append(
static_cast<sal_Int32
>(aDateTime.
GetYear()));
239 aDateTimeString.append(
'-');
240 if (aDateTime.
GetMonth()<10) aDateTimeString.append(
'0');
241 aDateTimeString.append(
static_cast<sal_Int32
>(aDateTime.
GetMonth()));
242 aDateTimeString.append(
'-');
243 if (aDateTime.
GetDay()<10) aDateTimeString.append(
'0');
244 aDateTimeString.append(
static_cast<sal_Int32
>(aDateTime.
GetDay()));
245 aDateTimeString.append(
'T');
246 if (aDateTime.
GetHour()<10) aDateTimeString.append(
'0');
247 aDateTimeString.append(
static_cast<sal_Int32
>(aDateTime.
GetHour()));
248 aDateTimeString.append(
':');
249 if (aDateTime.
GetMin()<10) aDateTimeString.append(
'0');
250 aDateTimeString.append(
static_cast<sal_Int32
>(aDateTime.
GetMin()));
251 aDateTimeString.append(
':');
252 if (aDateTime.
GetSec()<10) aDateTimeString.append(
'0');
253 aDateTimeString.append(
static_cast<sal_Int32
>(aDateTime.
GetSec()));
254 aDateTimeString.append(
'Z');
256 return aDateTimeString.makeStringAndClear();
280 OString aDateTimeString;
281 if (std::getenv(
"STABLE_FIELDS_HACK"))
285 xmlChar *pString =
static_cast<xmlChar*
>(xmlMalloc(aDateTimeString.getLength()+1));
286 strncpy(
reinterpret_cast<char*
>(pString), aDateTimeString.getStr(), aDateTimeString.getLength());
287 pString[aDateTimeString.getLength()] = 0;
288 xmlXPathReturnString(ctxt, pString);
296 OUString aDateTimeString(
o3tl::trim(aString) );
299 if (aDateTimeString.getLength() < 19 || aDateTimeString.getLength() > 20)
310 Date tmpDate(
static_cast<sal_uInt16
>(nDay),
static_cast<sal_uInt16
>(nMonth),
static_cast<sal_uInt16
>(nYear));
312 DateTime tmpDateTime(tmpDate, tmpTime);
313 if (aString.rfind(
'Z') == std::u16string_view::npos)
316 aDateTime = tmpDateTime;
326 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
327 xmlChar* pString = xmlXPathPopString(ctxt);
328 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
329 OUString aString(
reinterpret_cast<char*
>(pString), strlen(
reinterpret_cast<char*
>(pString)), RTL_TEXTENCODING_UTF8);
334 Date aReferenceDate(1, 1, 1970);
335 sal_Int32 nDays = aDateTime - aReferenceDate;
336 xmlXPathReturnNumber(ctxt, nDays);
339 xmlXPathReturnNumber(ctxt, xmlXPathNAN);
349 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
350 xmlChar* pString = xmlXPathPopString(ctxt);
351 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
352 OUString aString(
reinterpret_cast<char*
>(pString), strlen(
reinterpret_cast<char*
>(pString)), RTL_TEXTENCODING_UTF8);
358 Date aReferenceDate(1, 1, 1970);
359 sal_Int32 nDays = aDateTime - aReferenceDate;
360 sal_Int32 nSeconds = nDays * 24 * 60 * 60;
361 nSeconds += aDateTime.
GetHour() * 60 * 60;
362 nSeconds += aDateTime.
GetMin() * 60;
363 nSeconds += aDateTime.
GetSec();
364 xmlXPathReturnNumber(ctxt, nSeconds);
367 xmlXPathReturnNumber(ctxt, xmlXPathNAN);
371static bool parseDuration(
const xmlChar* aString,
bool& bNegative, sal_Int32& nYears, sal_Int32& nMonth, sal_Int32& nDays,
372 sal_Int32& nHours, sal_Int32& nMinutes, sal_Int32& nSeconds)
375 const xmlChar *pString = aString;
377 if (pString[0] ==
'-') {
382 if (pString[0] !=
'P')
388 const xmlChar* pToken = pString;
389 while(pToken[0] != 0)
393 nYears = boost::lexical_cast<sal_Int32>(pString, pString-pToken);
398 nMonth = boost::lexical_cast<sal_Int32>(pString, pString-pToken);
400 nMinutes = boost::lexical_cast<sal_Int32>(pString, pString-pToken);
404 nDays = boost::lexical_cast<sal_Int32>(pString, pString-pToken);
408 nHours = boost::lexical_cast<sal_Int32>(pString, pString-pToken);
412 nSeconds = boost::lexical_cast<sal_Int32>(pString, pString-pToken);
430 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
431 xmlChar* pString = xmlXPathPopString(ctxt);
432 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
434 bool bNegative =
false;
435 sal_Int32 nYears = 0;
436 sal_Int32 nMonths = 0;
438 sal_Int32 nHours = 0;
439 sal_Int32 nMinutes = 0;
440 sal_Int32 nSeconds = 0;
442 if (
parseDuration(pString, bNegative, nYears, nMonths, nDays, nHours, nMinutes, nSeconds))
444 nSeconds += nMinutes*60;
445 nSeconds += nHours*60*60;
446 nSeconds += nDays*24*60*60;
449 nSeconds = 0 - nSeconds;
450 xmlXPathReturnNumber(ctxt, nSeconds);
453 xmlXPathReturnNumber(ctxt, xmlXPathNAN);
460 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
461 xmlChar* pString = xmlXPathPopString(ctxt);
462 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
464 bool bNegative =
false;
465 sal_Int32 nYears = 0;
466 sal_Int32 nMonths = 0;
468 sal_Int32 nHours = 0;
469 sal_Int32 nMinutes = 0;
470 sal_Int32 nSeconds = 0;
472 if (
parseDuration(pString, bNegative, nYears, nMonths, nDays, nHours, nMinutes, nSeconds))
474 nMonths += nYears*12;
477 nMonths = 0 - nMonths;
478 xmlXPathReturnNumber(ctxt, nMonths);
481 xmlXPathReturnNumber(ctxt, xmlXPathNAN);
488 if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
489 xmlChar *pString = xmlXPathPopString(ctxt);
490 if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
491 OUString aString(
reinterpret_cast<char*
>(pString), strlen(
reinterpret_cast<char*
>(pString)), RTL_TEXTENCODING_UTF8);
502 xmlNodePtr pNode = comphelper::getSomething_cast<xmlNode>(aTunnel->getSomething(
Sequence<sal_Int8>()));
503 xmlXPathObjectPtr
pObject = xmlXPathNewNodeSet(pNode);
504 xmlXPathReturnNodeSet(ctxt,
pObject->nodesetval);
505 }
catch (
const RuntimeException&)
507 xmlXPathReturnEmptyNodeSet(ctxt);
511 xmlXPathReturnEmptyNodeSet(ctxt);
514 xmlXPathReturnEmptyNodeSet(ctxt);
521 if (nargs != 0) XP_ERROR(XPATH_INVALID_ARITY);
529 xmlNodePtr pNode = comphelper::getSomething_cast<xmlNode>(aTunnel->getSomething(
Sequence<sal_Int8>()));
530 xmlXPathObjectPtr
pObject = xmlXPathNewNodeSet(pNode);
531 xmlXPathReturnNodeSet(ctxt,
pObject->nodesetval);
533 catch (
const RuntimeException&)
535 xmlXPathReturnEmptyNodeSet(ctxt);
539 xmlXPathReturnEmptyNodeSet(ctxt);
sal_Int16 GetYear() const
sal_uInt16 GetDay() const
sal_uInt16 GetMonth() const
EmbeddedObjectRef * pObject
std::basic_string_view< charT, traits > trim(std::basic_string_view< charT, traits > str)
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
static OString makeDateTimeString(const DateTime &aDateTime)
void xforms_booleanFromStringFunction(xmlXPathParserContextPtr ctxt, int nargs)
xmlXPathParserContext:
void xforms_instanceFunction(xmlXPathParserContextPtr ctxt, int nargs)
void xforms_avgFunction(xmlXPathParserContextPtr ctxt, int nargs)
void xforms_daysFromDateFunction(xmlXPathParserContextPtr ctxt, int nargs)
void xforms_nowFunction(xmlXPathParserContextPtr ctxt, int)
void xforms_currentFunction(xmlXPathParserContextPtr ctxt, int nargs)
void xforms_secondsFunction(xmlXPathParserContextPtr ctxt, int nargs)
void xforms_secondsFromDateTimeFunction(xmlXPathParserContextPtr ctxt, int nargs)
static bool parseDuration(const xmlChar *aString, bool &bNegative, sal_Int32 &nYears, sal_Int32 &nMonth, sal_Int32 &nDays, sal_Int32 &nHours, sal_Int32 &nMinutes, sal_Int32 &nSeconds)
void xforms_maxFunction(xmlXPathParserContextPtr ctxt, int nargs)
void xforms_ifFunction(xmlXPathParserContextPtr ctxt, int nargs)
void xforms_minFunction(xmlXPathParserContextPtr ctxt, int nargs)
xmlXPathFunction xforms_lookupFunc(void *, const xmlChar *xname, const xmlChar *)
void xforms_monthsFunction(xmlXPathParserContextPtr ctxt, int nargs)
void xforms_indexFunction(xmlXPathParserContextPtr, int)
void xforms_countNonEmptyFunction(xmlXPathParserContextPtr ctxt, int nargs)
void xforms_propertyFunction(xmlXPathParserContextPtr ctxt, int nargs)
static bool parseDateTime(std::u16string_view aString, DateTime &aDateTime)