LCOV - code coverage report
Current view: top level - forms/source/xforms/xpathlib - xpathlib.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 0 307 0.0 %
Date: 2015-06-13 12:38:46 Functions: 0 19 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include <string.h>
      22             : #include <sal/types.h>
      23             : #include <rtl/alloc.h>
      24             : #include <rtl/ustring.hxx>
      25             : #include <rtl/string.hxx>
      26             : #include <rtl/ustrbuf.hxx>
      27             : #include <rtl/strbuf.hxx>
      28             : #include <tools/date.hxx>
      29             : #include <tools/time.hxx>
      30             : #include <tools/datetime.hxx>
      31             : 
      32             : #include <com/sun/star/uno/Reference.hxx>
      33             : #include <com/sun/star/uno/Sequence.hxx>
      34             : #include <com/sun/star/uno/Any.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>
      39             : 
      40             : #include "xpathlib.hxx"
      41             : 
      42             : #include "extension.hxx"
      43             : 
      44             : // C interface
      45             : 
      46             : using namespace com::sun::star::uno;
      47             : using namespace com::sun::star::xml::dom;
      48             : using namespace com::sun::star::xforms;
      49             : using namespace com::sun::star::lang;
      50             : 
      51           0 : xmlXPathFunction xforms_lookupFunc(void *, const xmlChar *xname, const xmlChar *)
      52             : {
      53             : 
      54           0 :     const char *name = reinterpret_cast<char const *>(xname);
      55           0 :     if (strcmp("boolean-from-string", name)==0)
      56           0 :         return xforms_booleanFromStringFunction;
      57           0 :     else if ((strcmp("if", name))==0)
      58           0 :         return xforms_ifFunction;
      59           0 :     else if ((strcmp("avg", name))==0)
      60           0 :         return xforms_avgFunction;
      61           0 :     else if ((strcmp("min", name))==0)
      62           0 :         return xforms_minFunction;
      63           0 :     else if ((strcmp("max", name))==0)
      64           0 :         return xforms_maxFunction;
      65           0 :     else if ((strcmp("count-non-empty", name))==0)
      66           0 :         return xforms_countNonEmptyFunction;
      67           0 :     else if ((strcmp("index", name))==0)
      68           0 :         return xforms_indexFunction;
      69           0 :     else if ((strcmp("property", name))==0)
      70           0 :         return xforms_propertyFunction;
      71           0 :     else if ((strcmp("now", name))==0)
      72           0 :         return xforms_nowFunction;
      73           0 :     else if ((strcmp("days-from-date", name))==0)
      74           0 :         return xforms_daysFromDateFunction;
      75           0 :     else if ((strcmp("seconds-from-dateTime", name))==0)
      76           0 :         return xforms_secondsFromDateTimeFunction;
      77           0 :     else if ((strcmp("seconds", name))==0)
      78           0 :         return xforms_secondsFuction;
      79           0 :     else if ((strcmp("months", name))==0)
      80           0 :         return xforms_monthsFuction;
      81           0 :     else if ((strcmp("instance", name))==0)
      82           0 :         return xforms_instanceFuction;
      83           0 :     else if ((strcmp("current", name))==0)
      84           0 :         return xforms_currentFunction;
      85             :     else
      86           0 :         return NULL;
      87             : }
      88             : 
      89             : // boolean functions
      90           0 : void xforms_booleanFromStringFunction(xmlXPathParserContextPtr ctxt, int nargs)
      91             : {
      92           0 :     if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
      93           0 :     xmlChar *pString = xmlXPathPopString(ctxt);
      94           0 :     if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
      95           0 :     OUString aString(reinterpret_cast<char*>(pString), strlen(reinterpret_cast<char*>(pString)), RTL_TEXTENCODING_UTF8);
      96           0 :     if (aString.equalsIgnoreAsciiCase("true") ||
      97           0 :         aString.equalsIgnoreAsciiCase("1"))
      98           0 :         xmlXPathReturnTrue(ctxt);
      99           0 :     else if (aString.equalsIgnoreAsciiCase("false") ||
     100           0 :              aString.equalsIgnoreAsciiCase("0"))
     101           0 :         xmlXPathReturnFalse(ctxt);
     102             :     else
     103           0 :         XP_ERROR(XPATH_NUMBER_ERROR);
     104             : }
     105             : 
     106           0 : void xforms_ifFunction(xmlXPathParserContextPtr ctxt, int nargs)
     107             : {
     108           0 :     if (nargs != 3) XP_ERROR(XPATH_INVALID_ARITY);
     109           0 :     xmlChar *s2 = xmlXPathPopString(ctxt);
     110             : 
     111           0 :     if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
     112           0 :     xmlChar *s1 = xmlXPathPopString(ctxt);
     113           0 :     if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
     114           0 :     bool aBool = xmlXPathPopBoolean(ctxt);
     115           0 :     if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
     116             : 
     117           0 :     if (aBool)
     118           0 :         xmlXPathReturnString(ctxt, s1);
     119             :     else
     120           0 :         xmlXPathReturnString(ctxt, s2);
     121             : 
     122             : }
     123             : 
     124             : // Number Functions
     125           0 : void xforms_avgFunction(xmlXPathParserContextPtr ctxt, int nargs)
     126             : {
     127             :     // use sum(), div() and count()
     128           0 :     if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
     129             : 
     130             :     // save nodeset
     131           0 :     xmlXPathObjectPtr pObject = valuePop(ctxt);
     132           0 :     if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
     133             :     //push back a copy
     134           0 :     valuePush(ctxt, xmlXPathObjectCopy(pObject));
     135             :     // get the Sum
     136           0 :     xmlXPathSumFunction(ctxt, 1);
     137           0 :     double nSum = xmlXPathPopNumber(ctxt);
     138             :     // push a copy once more
     139           0 :     valuePush(ctxt, xmlXPathObjectCopy(pObject));
     140           0 :     xmlXPathCountFunction(ctxt, 1);
     141           0 :     double nCount = xmlXPathPopNumber(ctxt);
     142             :     // push args for div()
     143           0 :     xmlXPathReturnNumber(ctxt, nSum);
     144           0 :     xmlXPathReturnNumber(ctxt, nCount);
     145           0 :     xmlXPathDivValues(ctxt);
     146             :     // the result is now on the ctxt stack
     147           0 :     xmlXPathFreeObject(pObject);
     148             : }
     149             : 
     150           0 : void xforms_minFunction(xmlXPathParserContextPtr ctxt, int nargs)
     151             : {
     152           0 :     if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
     153           0 :     xmlNodeSetPtr pNodeSet = xmlXPathPopNodeSet(ctxt);
     154           0 :     if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
     155           0 :     double nMinimum = 0;
     156           0 :     for (int i = 0; i <  xmlXPathNodeSetGetLength(pNodeSet); i++)
     157             :     {
     158           0 :         double nNumber = xmlXPathCastNodeToNumber(xmlXPathNodeSetItem(pNodeSet, i));
     159           0 :         if (xmlXPathIsNaN(nNumber))
     160             :         {
     161           0 :             xmlXPathReturnNumber(ctxt, xmlXPathNAN);
     162           0 :             return;
     163             :         }
     164           0 :         if (i == 0)
     165           0 :             nMinimum = nNumber;
     166           0 :         else if (nNumber < nMinimum)
     167           0 :             nMinimum = nNumber;
     168             :     }
     169           0 :     xmlXPathReturnNumber(ctxt, nMinimum);
     170             : }
     171             : 
     172           0 : void xforms_maxFunction(xmlXPathParserContextPtr ctxt, int nargs)
     173             : {
     174           0 :     if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
     175           0 :     xmlNodeSetPtr pNodeSet = xmlXPathPopNodeSet(ctxt);
     176           0 :     if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
     177           0 :     double nMaximum = 0;
     178           0 :     for (int i = 0; i <  xmlXPathNodeSetGetLength(pNodeSet); i++)
     179             :     {
     180           0 :         double nNumber = xmlXPathCastNodeToNumber(xmlXPathNodeSetItem(pNodeSet, i));
     181           0 :         if (xmlXPathIsNaN(nNumber))
     182             :         {
     183           0 :             xmlXPathReturnNumber(ctxt, xmlXPathNAN);
     184           0 :             return;
     185             :         }
     186           0 :         if (i == 0)
     187           0 :             nMaximum = nNumber;
     188           0 :         else if (nNumber > nMaximum)
     189           0 :             nMaximum = nNumber;
     190             :     }
     191           0 :     xmlXPathReturnNumber(ctxt, nMaximum);
     192             : }
     193           0 : void xforms_countNonEmptyFunction(xmlXPathParserContextPtr ctxt, int nargs)
     194             : {
     195           0 :     if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
     196           0 :     xmlNodeSetPtr pNodeSet = xmlXPathPopNodeSet(ctxt);
     197           0 :     if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
     198           0 :     sal_Int32 nNotEmpty = 0;
     199           0 :     for (int i = 0; i <  xmlXPathNodeSetGetLength(pNodeSet); i++)
     200             :     {
     201           0 :         const xmlChar *aString = xmlXPathCastNodeToString(xmlXPathNodeSetItem(pNodeSet, i));
     202           0 :         if (*aString != 0) nNotEmpty++;
     203             :     }
     204           0 :     xmlXPathReturnNumber(ctxt, nNotEmpty);
     205             : }
     206           0 : void xforms_indexFunction(xmlXPathParserContextPtr /*ctxt*/, int /*nargs*/)
     207             : {
     208             :     // function index takes a string argument that is the IDREF of a
     209             :     // 'repeat' and returns the current 1-based position of the repeat
     210             :     // index of the identified repeat -- see xforms/9.3.1
     211             : 
     212             :     // doc.getElementByID
     213             :     // (...)
     214           0 : }
     215             : 
     216             : // String Functions
     217             : static const char* _version = "1.0";
     218             : static const char* _conformance = "conformance";
     219           0 : void xforms_propertyFunction(xmlXPathParserContextPtr ctxt, int nargs)
     220             : {
     221           0 :     if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
     222           0 :     xmlChar* pString = xmlXPathPopString(ctxt);
     223           0 :     if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
     224           0 :     OUString aString(reinterpret_cast<char*>(pString), strlen(reinterpret_cast<char*>(pString)), RTL_TEXTENCODING_UTF8);
     225           0 :     if (aString.equalsIgnoreAsciiCase("version"))
     226           0 :         xmlXPathReturnString(ctxt, reinterpret_cast<xmlChar *>(const_cast<char *>(_version)));
     227           0 :     else if (aString.equalsIgnoreAsciiCase("conformance-level"))
     228           0 :         xmlXPathReturnString(ctxt, reinterpret_cast<xmlChar *>(const_cast<char *>(_conformance)));
     229             :     else
     230           0 :         xmlXPathReturnEmptyString(ctxt);
     231             : }
     232             : 
     233             : // Date and Time Functions
     234             : 
     235           0 : static OString makeDateTimeString (const DateTime& aDateTime, bool bUTC = true)
     236             : {
     237           0 :     OStringBuffer aDateTimeString;
     238           0 :     aDateTimeString.append((sal_Int32)aDateTime.GetYear());
     239           0 :     aDateTimeString.append("-");
     240           0 :     if (aDateTime.GetMonth()<10) aDateTimeString.append("0");
     241           0 :     aDateTimeString.append((sal_Int32)aDateTime.GetMonth());
     242           0 :     aDateTimeString.append("-");
     243           0 :     if (aDateTime.GetDay()<10) aDateTimeString.append("0");
     244           0 :     aDateTimeString.append((sal_Int32)aDateTime.GetDay());
     245           0 :     aDateTimeString.append("T");
     246           0 :     if (aDateTime.GetHour()<10) aDateTimeString.append("0");
     247           0 :     aDateTimeString.append((sal_Int32)aDateTime.GetHour());
     248           0 :     aDateTimeString.append(":");
     249           0 :     if (aDateTime.GetMin()<10) aDateTimeString.append("0");
     250           0 :     aDateTimeString.append((sal_Int32)aDateTime.GetMin());
     251           0 :     aDateTimeString.append(":");
     252           0 :     if (aDateTime.GetSec()<10) aDateTimeString.append("0");
     253           0 :     aDateTimeString.append((sal_Int32)aDateTime.GetSec());
     254           0 :     if (bUTC) aDateTimeString.append("Z");
     255             : 
     256           0 :     return aDateTimeString.makeStringAndClear();
     257             : }
     258             : 
     259             : // returns current system date and time in canonical xsd:dateTime
     260             : // format
     261           0 : void xforms_nowFunction(xmlXPathParserContextPtr ctxt, int /*nargs*/)
     262             : {
     263             :     /*
     264             :     A single lexical representation, which is a subset of the lexical representations
     265             :     allowed by [ISO 8601], is allowed for dateTime. This lexical representation is the
     266             :     [ISO 8601] extended format CCYY-MM-DDThh:mm:ss where "CC" represents the century,
     267             :     "YY" the year, "MM" the month and "DD" the day, preceded by an optional leading "-"
     268             :     sign to indicate a negative number. If the sign is omitted, "+" is assumed. The letter
     269             :     "T" is the date/time separator and "hh", "mm", "ss" represent hour, minute and second
     270             :     respectively.
     271             :     */
     272             : 
     273             :     /*
     274             :     3.2.7.2 Canonical representation
     275             :     The canonical representation for dateTime is defined by prohibiting certain options
     276             :     from the Lexical representation (par.3.2.7.1). Specifically, either the time zone must
     277             :     be omitted or, if present, the time zone must be Coordinated Universal tools::Time (UTC)
     278             :     indicated by a "Z".
     279             :     */
     280           0 :     DateTime aDateTime( DateTime::SYSTEM );
     281           0 :     OString aDateTimeString = makeDateTimeString(aDateTime);
     282           0 :     xmlChar *pString = static_cast<xmlChar*>(xmlMalloc(aDateTimeString.getLength()+1));
     283           0 :     strncpy(reinterpret_cast<char*>(pString), aDateTimeString.getStr(), aDateTimeString.getLength());
     284           0 :     pString[aDateTimeString.getLength()] = 0;
     285           0 :     xmlXPathReturnString(ctxt, pString);
     286           0 : }
     287             : 
     288           0 : static bool parseDateTime(const OUString& aString, DateTime& aDateTime)
     289             : {
     290             :     // take apart a canonical literal xsd:dateTime string
     291             :     //CCYY-MM-DDThh:mm:ss(Z)
     292             : 
     293           0 :     OUString aDateTimeString = aString.trim();
     294             : 
     295             :     // check length
     296           0 :     if (aDateTimeString.getLength() < 19 || aDateTimeString.getLength() > 20)
     297           0 :         return false;
     298             : 
     299           0 :     sal_Int32 nDateLength = 10;
     300           0 :     sal_Int32 nTimeLength = 8;
     301             : 
     302           0 :     OUString aUTCString("Z");
     303             : 
     304           0 :     OUString aDateString = aDateTimeString.copy(0, nDateLength);
     305           0 :     OUString aTimeString = aDateTimeString.copy(nDateLength+1, nTimeLength);
     306             : 
     307           0 :     sal_Int32 nIndex = 0;
     308           0 :     sal_Int32 nYear = aDateString.getToken(0, '-', nIndex).toInt32();
     309           0 :     sal_Int32 nMonth = aDateString.getToken(0, '-', nIndex).toInt32();
     310           0 :     sal_Int32 nDay = aDateString.getToken(0, '-', nIndex).toInt32();
     311           0 :     nIndex = 0;
     312           0 :     sal_Int32 nHour = aTimeString.getToken(0, ':', nIndex).toInt32();
     313           0 :     sal_Int32 nMinute = aTimeString.getToken(0, ':', nIndex).toInt32();
     314           0 :     sal_Int32 nSecond = aTimeString.getToken(0, ':', nIndex).toInt32();
     315             : 
     316           0 :     Date tmpDate((sal_uInt16)nDay, (sal_uInt16)nMonth, (sal_uInt16)nYear);
     317           0 :     tools::Time tmpTime(nHour, nMinute, nSecond);
     318           0 :     DateTime tmpDateTime(tmpDate, tmpTime);
     319           0 :     if (aString.indexOf(aUTCString) < 0)
     320           0 :         tmpDateTime.ConvertToUTC();
     321             : 
     322           0 :     aDateTime = tmpDateTime;
     323             : 
     324           0 :     return true;
     325             : }
     326             : 
     327             : 
     328           0 : void xforms_daysFromDateFunction(xmlXPathParserContextPtr ctxt, int nargs)
     329             : {
     330             :     // number of days from 1970-01-01 to supplied xsd:date(Time)
     331             : 
     332           0 :     if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
     333           0 :     xmlChar* pString = xmlXPathPopString(ctxt);
     334           0 :     if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
     335           0 :     OUString aString(reinterpret_cast<char*>(pString), strlen(reinterpret_cast<char*>(pString)), RTL_TEXTENCODING_UTF8);
     336             : 
     337           0 :     DateTime aDateTime( DateTime::EMPTY );
     338           0 :     if (parseDateTime(aString, aDateTime))
     339             :     {
     340           0 :         Date aReferenceDate(1, 1, 1970);
     341           0 :         sal_Int32 nDays = aDateTime - aReferenceDate;
     342           0 :         xmlXPathReturnNumber(ctxt, nDays);
     343             :     }
     344             :     else
     345           0 :         xmlXPathReturnNumber(ctxt, xmlXPathNAN);
     346             : 
     347             : 
     348             : }
     349             : 
     350             : 
     351           0 : void xforms_secondsFromDateTimeFunction(xmlXPathParserContextPtr ctxt, int nargs)
     352             : {
     353             :     // number of seconds from 1970-01-01T00:00:00Z to supplied xsd:date(Time)
     354             : 
     355           0 :     if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
     356           0 :     xmlChar* pString = xmlXPathPopString(ctxt);
     357           0 :     if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
     358           0 :     OUString aString(reinterpret_cast<char*>(pString), strlen(reinterpret_cast<char*>(pString)), RTL_TEXTENCODING_UTF8);
     359             : 
     360           0 :     DateTime aDateTime( DateTime::EMPTY );
     361             : 
     362           0 :     if (parseDateTime(aString, aDateTime))
     363             :     {
     364           0 :         Date aReferenceDate(1, 1, 1970);
     365           0 :         sal_Int32 nDays = aDateTime - aReferenceDate;
     366           0 :         sal_Int32 nSeconds = nDays * 24 * 60 * 60;
     367           0 :         nSeconds += aDateTime.GetHour() * 60 * 60;
     368           0 :         nSeconds += aDateTime.GetMin() * 60;
     369           0 :         nSeconds += aDateTime.GetSec();
     370           0 :         xmlXPathReturnNumber(ctxt, nSeconds);
     371             :     }
     372             :     else
     373           0 :         xmlXPathReturnNumber(ctxt, xmlXPathNAN);
     374             : 
     375             : }
     376             : 
     377           0 : static bool parseDuration(const xmlChar* aString, bool& bNegative, sal_Int32& nYears, sal_Int32& nMonth, sal_Int32& nDays,
     378             :                               sal_Int32& nHours, sal_Int32& nMinutes, sal_Int32& nSeconds)
     379             : {
     380           0 :     bool bTime = false; // in part after T
     381           0 :     sal_Int32 nLength = strlen(reinterpret_cast<char const *>(aString))+1;
     382           0 :     char *pString = static_cast<char*>(rtl_allocateMemory(nLength));
     383           0 :     char *pString0 = pString;
     384           0 :     strncpy(pString, reinterpret_cast<char const *>(aString), nLength);
     385             : 
     386           0 :     if (pString[0] == '-') {
     387           0 :         bNegative = true;
     388           0 :         pString++;
     389             :     }
     390             : 
     391           0 :     if (pString[0] != 'P')
     392             :     {
     393           0 :         rtl_freeMemory(pString0);
     394           0 :         return false;
     395             :     }
     396             : 
     397           0 :     pString++;
     398           0 :     char* pToken = pString;
     399           0 :     while(pToken[0] != 0)
     400             :     {
     401           0 :         switch(pToken[0]) {
     402             :         case 'Y':
     403           0 :             pToken[0] = 0;
     404           0 :             nYears = atoi(pString);
     405           0 :             pString = ++pToken;
     406           0 :             break;
     407             :         case 'M':
     408           0 :             pToken[0] = 0;
     409           0 :             if (!bTime)
     410           0 :                 nMonth = atoi(pString);
     411             :             else
     412           0 :                 nMinutes = atoi(pString);
     413           0 :             pString = ++pToken;
     414           0 :             break;
     415             :         case 'D':
     416           0 :             pToken[0] = 0;
     417           0 :             nDays = atoi(pString);
     418           0 :             pString = ++pToken;
     419           0 :             break;
     420             :         case 'H':
     421           0 :             pToken[0] = 0;
     422           0 :             nHours = atoi(pString);
     423           0 :             pString = ++pToken;
     424           0 :             break;
     425             :         case 'S':
     426           0 :             pToken[0] = 0;
     427           0 :             nSeconds = atoi(pString);
     428           0 :             pString = ++pToken;
     429           0 :             break;
     430             :         case 'T':
     431           0 :             bTime = true;
     432           0 :             pString = ++pToken;
     433           0 :             break;
     434             :         default:
     435           0 :             pToken++;
     436             :         }
     437             :     }
     438           0 :     rtl_freeMemory(pString0);
     439           0 :     return true;
     440             : }
     441             : 
     442           0 : void xforms_secondsFuction(xmlXPathParserContextPtr ctxt, int nargs)
     443             : {
     444             :     // convert a xsd:duration to seconds
     445             :     // (-)PnYnMnDTnHnMnS
     446           0 :     if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
     447           0 :     xmlChar* pString = xmlXPathPopString(ctxt);
     448           0 :     if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
     449             : 
     450           0 :     bool bNegative = false;
     451           0 :     sal_Int32 nYears = 0;
     452           0 :     sal_Int32 nMonths = 0;
     453           0 :     sal_Int32 nDays = 0;
     454           0 :     sal_Int32 nHours = 0;
     455           0 :     sal_Int32 nMinutes = 0;
     456           0 :     sal_Int32 nSeconds = 0;
     457             : 
     458           0 :     if (parseDuration(pString, bNegative, nYears, nMonths, nDays, nHours, nMinutes, nSeconds))
     459             :     {
     460           0 :         nSeconds += nMinutes*60;
     461           0 :         nSeconds += nHours*60*60;
     462           0 :         nSeconds += nDays*24*60*60;
     463             :         // year and month are ignored according to spec
     464           0 :         if (bNegative)
     465           0 :             nSeconds = 0 - nSeconds;
     466           0 :         xmlXPathReturnNumber(ctxt, nSeconds);
     467             :     }
     468             :     else
     469           0 :         xmlXPathReturnNumber(ctxt, xmlXPathNAN);
     470             : }
     471             : 
     472           0 : void xforms_monthsFuction(xmlXPathParserContextPtr ctxt, int nargs)
     473             : {
     474             :     // convert a xsd:duration to seconds
     475             :     // (-)PnYnMnDTnHnMnS
     476           0 :     if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
     477           0 :     xmlChar* pString = xmlXPathPopString(ctxt);
     478           0 :     if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
     479             : 
     480           0 :     bool bNegative = false;
     481           0 :     sal_Int32 nYears = 0;
     482           0 :     sal_Int32 nMonths = 0;
     483           0 :     sal_Int32 nDays = 0;
     484           0 :     sal_Int32 nHours = 0;
     485           0 :     sal_Int32 nMinutes = 0;
     486           0 :     sal_Int32 nSeconds = 0;
     487             : 
     488           0 :     if (parseDuration(pString, bNegative, nYears, nMonths, nDays, nHours, nMinutes, nSeconds))
     489             :     {
     490           0 :         nMonths += nYears*12;
     491             :         // Days, Houres, Minutes and seconds are ignored, see spec
     492           0 :         if (bNegative)
     493           0 :             nMonths = 0 - nMonths;
     494           0 :         xmlXPathReturnNumber(ctxt, nMonths);
     495             :     }
     496             :     else
     497           0 :         xmlXPathReturnNumber(ctxt, xmlXPathNAN);
     498             : 
     499             : }
     500             : 
     501             : // Node-set Functions
     502           0 : void xforms_instanceFuction(xmlXPathParserContextPtr ctxt, int nargs)
     503             : {
     504           0 :     if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
     505           0 :     xmlChar *pString = xmlXPathPopString(ctxt);
     506           0 :     if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
     507           0 :     OUString aString(reinterpret_cast<char*>(pString), strlen(reinterpret_cast<char*>(pString)), RTL_TEXTENCODING_UTF8);
     508             : 
     509           0 :     Reference< XModel > aModel = static_cast<CLibxml2XFormsExtension*>(ctxt->context->funcLookupData)->getModel();
     510           0 :     if (aModel.is())
     511             :     {
     512           0 :         Reference< XDocument > aInstance = aModel->getInstanceDocument(aString);
     513           0 :         if (aInstance.is())
     514             :         {
     515             :             try {
     516             :                 // xmlXPathObjectPtr xmlXPathNewNodeSet        (xmlNodePtr val);
     517           0 :                 Reference< XUnoTunnel > aTunnel(aInstance, UNO_QUERY_THROW);
     518           0 :                 xmlNodePtr pNode = reinterpret_cast< xmlNodePtr >( aTunnel->getSomething(Sequence< sal_Int8 >()) );
     519           0 :                 xmlXPathObjectPtr pObject = xmlXPathNewNodeSet(pNode);
     520           0 :                 xmlXPathReturnNodeSet(ctxt, pObject->nodesetval);
     521           0 :             } catch (const RuntimeException&)
     522             :             {
     523           0 :                 xmlXPathReturnEmptyNodeSet(ctxt);
     524             :             }
     525             :         }
     526             :         else
     527           0 :             xmlXPathReturnEmptyNodeSet(ctxt);
     528             :     }
     529             :     else
     530           0 :         xmlXPathReturnEmptyNodeSet(ctxt);
     531             : 
     532             : }
     533             : 
     534             : // Node-set Functions, XForms 1.1
     535           0 : void xforms_currentFunction(xmlXPathParserContextPtr ctxt, int nargs)
     536             : {
     537           0 :     if (nargs != 0) XP_ERROR(XPATH_INVALID_ARITY);
     538             : 
     539           0 :     Reference< XNode > aNode = static_cast<CLibxml2XFormsExtension*>(ctxt->context->funcLookupData)->getContextNode();
     540             : 
     541           0 :     if (aNode.is())
     542             :     {
     543             :         try {
     544           0 :             Reference< XUnoTunnel > aTunnel(aNode, UNO_QUERY_THROW);
     545           0 :             xmlNodePtr pNode = reinterpret_cast< xmlNodePtr >( aTunnel->getSomething(Sequence< sal_Int8 >()) );
     546           0 :             xmlXPathObjectPtr pObject = xmlXPathNewNodeSet(pNode);
     547           0 :             xmlXPathReturnNodeSet(ctxt, pObject->nodesetval);
     548             :         }
     549           0 :         catch (const RuntimeException&)
     550             :         {
     551           0 :             xmlXPathReturnEmptyNodeSet(ctxt);
     552             :         }
     553             :     }
     554             :     else
     555           0 :         xmlXPathReturnEmptyNodeSet(ctxt);
     556             : }
     557             : 
     558             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11