LCOV - code coverage report
Current view: top level - libreoffice/forms/source/xforms/xpathlib - xpathlib.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 309 0.0 %
Date: 2012-12-27 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 = (char *)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 :     ::rtl::OUString aString((char*)pString, strlen((char*)pString), RTL_TEXTENCODING_UTF8);
      96           0 :     if (aString.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("true")) ||
      97           0 :         aString.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("1")))
      98           0 :         xmlXPathReturnTrue(ctxt);
      99           0 :     else if (aString.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("false")) ||
     100           0 :              aString.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("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 :     double nNumber = 0;
     157           0 :     for (int i = 0; i <  xmlXPathNodeSetGetLength(pNodeSet); i++)
     158             :     {
     159           0 :         nNumber = xmlXPathCastNodeToNumber(xmlXPathNodeSetItem(pNodeSet, i));
     160           0 :         if (xmlXPathIsNaN(nNumber))
     161             :         {
     162           0 :             xmlXPathReturnNumber(ctxt, xmlXPathNAN);
     163           0 :             return;
     164             :         }
     165           0 :         if (i == 0)
     166           0 :             nMinimum = nNumber;
     167           0 :         else if (nNumber < nMinimum)
     168           0 :             nMinimum = nNumber;
     169             :     }
     170           0 :     xmlXPathReturnNumber(ctxt, nMinimum);
     171             : }
     172             : 
     173           0 : void xforms_maxFunction(xmlXPathParserContextPtr ctxt, int nargs)
     174             : {
     175           0 :     if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
     176           0 :     xmlNodeSetPtr pNodeSet = xmlXPathPopNodeSet(ctxt);
     177           0 :     if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
     178           0 :     double nMaximum = 0;
     179           0 :     double nNumber = 0;
     180           0 :     for (int i = 0; i <  xmlXPathNodeSetGetLength(pNodeSet); i++)
     181             :     {
     182           0 :         nNumber = xmlXPathCastNodeToNumber(xmlXPathNodeSetItem(pNodeSet, i));
     183           0 :         if (xmlXPathIsNaN(nNumber))
     184             :         {
     185           0 :             xmlXPathReturnNumber(ctxt, xmlXPathNAN);
     186           0 :             return;
     187             :         }
     188           0 :         if (i == 0)
     189           0 :             nMaximum = nNumber;
     190           0 :         else if (nNumber > nMaximum)
     191           0 :             nMaximum = nNumber;
     192             :     }
     193           0 :     xmlXPathReturnNumber(ctxt, nMaximum);
     194             : }
     195           0 : void xforms_countNonEmptyFunction(xmlXPathParserContextPtr ctxt, int nargs)
     196             : {
     197           0 :     if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
     198           0 :     xmlNodeSetPtr pNodeSet = xmlXPathPopNodeSet(ctxt);
     199           0 :     if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
     200             :     xmlChar *aString;
     201           0 :     sal_Int32 nNotEmpty = 0;
     202           0 :     for (int i = 0; i <  xmlXPathNodeSetGetLength(pNodeSet); i++)
     203             :     {
     204           0 :         aString = xmlXPathCastNodeToString(xmlXPathNodeSetItem(pNodeSet, i));
     205           0 :         if (*aString != 0) nNotEmpty++;
     206             :     }
     207           0 :     xmlXPathReturnNumber(ctxt, nNotEmpty);
     208             : }
     209           0 : void xforms_indexFunction(xmlXPathParserContextPtr /*ctxt*/, int /*nargs*/)
     210             : {
     211             :     // function index takes a string argument that is the IDREF of a
     212             :     // 'repeat' and returns the current 1-based position of the repeat
     213             :     // index of the identified repeat -- see xforms/9.3.1
     214             : 
     215             :     // doc.getElementByID
     216             :     // (...)
     217           0 : }
     218             : 
     219             : // String Functions
     220             : static const char* _version = "1.0";
     221             : static const char* _conformance = "conformance";
     222           0 : void xforms_propertyFunction(xmlXPathParserContextPtr ctxt, int nargs)
     223             : {
     224           0 :     if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
     225           0 :     xmlChar* pString = xmlXPathPopString(ctxt);
     226           0 :     if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
     227           0 :     ::rtl::OUString aString((char*)pString, strlen((char*)pString), RTL_TEXTENCODING_UTF8);
     228           0 :     if (aString.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("version")))
     229           0 :         xmlXPathReturnString(ctxt, (xmlChar*)_version);
     230           0 :     else if (aString.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("conformance-level")))
     231           0 :         xmlXPathReturnString(ctxt, (xmlChar*)_conformance);
     232             :     else
     233           0 :         xmlXPathReturnEmptyString(ctxt);
     234             : }
     235             : 
     236             : // Date and Time Functions
     237             : 
     238           0 : static ::rtl::OString makeDateTimeString (const DateTime& aDateTime, sal_Bool bUTC = sal_True)
     239             : {
     240           0 :     ::rtl::OStringBuffer aDateTimeString;
     241           0 :     aDateTimeString.append((sal_Int32)aDateTime.GetYear());
     242           0 :     aDateTimeString.append("-");
     243           0 :     if (aDateTime.GetMonth()<10) aDateTimeString.append("0");
     244           0 :     aDateTimeString.append((sal_Int32)aDateTime.GetMonth());
     245           0 :     aDateTimeString.append("-");
     246           0 :     if (aDateTime.GetDay()<10) aDateTimeString.append("0");
     247           0 :     aDateTimeString.append((sal_Int32)aDateTime.GetDay());
     248           0 :     aDateTimeString.append("T");
     249           0 :     if (aDateTime.GetHour()<10) aDateTimeString.append("0");
     250           0 :     aDateTimeString.append((sal_Int32)aDateTime.GetHour());
     251           0 :     aDateTimeString.append(":");
     252           0 :     if (aDateTime.GetMin()<10) aDateTimeString.append("0");
     253           0 :     aDateTimeString.append((sal_Int32)aDateTime.GetMin());
     254           0 :     aDateTimeString.append(":");
     255           0 :     if (aDateTime.GetSec()<10) aDateTimeString.append("0");
     256           0 :     aDateTimeString.append((sal_Int32)aDateTime.GetSec());
     257           0 :     if (bUTC) aDateTimeString.append("Z");
     258             : 
     259           0 :     return aDateTimeString.makeStringAndClear();
     260             : }
     261             : 
     262             : // returns current system date and time in canonical xsd:dateTime
     263             : // format
     264           0 : void xforms_nowFunction(xmlXPathParserContextPtr ctxt, int /*nargs*/)
     265             : {
     266             :     /*
     267             :     A single lexical representation, which is a subset of the lexical representations
     268             :     allowed by [ISO 8601], is allowed for dateTime. This lexical representation is the
     269             :     [ISO 8601] extended format CCYY-MM-DDThh:mm:ss where "CC" represents the century,
     270             :     "YY" the year, "MM" the month and "DD" the day, preceded by an optional leading "-"
     271             :     sign to indicate a negative number. If the sign is omitted, "+" is assumed. The letter
     272             :     "T" is the date/time separator and "hh", "mm", "ss" represent hour, minute and second
     273             :     respectively.
     274             :     */
     275             : 
     276             :     /*
     277             :     3.2.7.2 Canonical representation
     278             :     The canonical representation for dateTime is defined by prohibiting certain options
     279             :     from the Lexical representation (par.3.2.7.1). Specifically, either the time zone must
     280             :     be omitted or, if present, the time zone must be Coordinated Universal Time (UTC)
     281             :     indicated by a "Z".
     282             :     */
     283           0 :     DateTime aDateTime( DateTime::SYSTEM );
     284           0 :     ::rtl::OString aDateTimeString = makeDateTimeString(aDateTime);
     285           0 :     xmlChar *pString = static_cast<xmlChar*>(xmlMalloc(aDateTimeString.getLength()+1));
     286           0 :     strncpy((char*)pString, (char*)aDateTimeString.getStr(), aDateTimeString.getLength());
     287           0 :     pString[aDateTimeString.getLength()] = 0;
     288           0 :     xmlXPathReturnString(ctxt, pString);
     289           0 : }
     290             : 
     291           0 : static sal_Bool parseDateTime(const ::rtl::OUString& aString, DateTime& aDateTime)
     292             : {
     293             :     // take apart a canonical literal xsd:dateTime string
     294             :     //CCYY-MM-DDThh:mm:ss(Z)
     295             : 
     296           0 :     ::rtl::OUString aDateTimeString = aString.trim();
     297             : 
     298             :     // check length
     299           0 :     if (aDateTimeString.getLength() < 19 || aDateTimeString.getLength() > 20)
     300           0 :         return sal_False;
     301             : 
     302           0 :     sal_Int32 nDateLength = 10;
     303           0 :     sal_Int32 nTimeLength = 8;
     304             : 
     305           0 :     ::rtl::OUString aUTCString(RTL_CONSTASCII_USTRINGPARAM("Z"));
     306             : 
     307           0 :     ::rtl::OUString aDateString = aDateTimeString.copy(0, nDateLength);
     308           0 :     ::rtl::OUString aTimeString = aDateTimeString.copy(nDateLength+1, nTimeLength);
     309             : 
     310           0 :     sal_Int32 nIndex = 0;
     311           0 :     sal_Int32 nYear = aDateString.getToken(0, '-', nIndex).toInt32();
     312           0 :     sal_Int32 nMonth = aDateString.getToken(0, '-', nIndex).toInt32();
     313           0 :     sal_Int32 nDay = aDateString.getToken(0, '-', nIndex).toInt32();
     314           0 :     nIndex = 0;
     315           0 :     sal_Int32 nHour = aTimeString.getToken(0, ':', nIndex).toInt32();
     316           0 :     sal_Int32 nMinute = aTimeString.getToken(0, ':', nIndex).toInt32();
     317           0 :     sal_Int32 nSecond = aTimeString.getToken(0, ':', nIndex).toInt32();
     318             : 
     319           0 :     Date tmpDate((sal_uInt16)nDay, (sal_uInt16)nMonth, (sal_uInt16)nYear);
     320           0 :     Time tmpTime(nHour, nMinute, nSecond);
     321           0 :     DateTime tmpDateTime(tmpDate, tmpTime);
     322           0 :     if (aString.indexOf(aUTCString) < 0)
     323           0 :         tmpDateTime.ConvertToUTC();
     324             : 
     325           0 :     aDateTime = tmpDateTime;
     326             : 
     327           0 :     return sal_True;
     328             : }
     329             : 
     330             : 
     331           0 : void xforms_daysFromDateFunction(xmlXPathParserContextPtr ctxt, int nargs)
     332             : {
     333             :     // number of days from 1970-01-01 to supplied xsd:date(Time)
     334             : 
     335           0 :     if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
     336           0 :     xmlChar* pString = xmlXPathPopString(ctxt);
     337           0 :     if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
     338           0 :     ::rtl::OUString aString((char*)pString, strlen((char*)pString), RTL_TEXTENCODING_UTF8);
     339             : 
     340           0 :     DateTime aDateTime( DateTime::EMPTY );
     341           0 :     if (parseDateTime(aString, aDateTime))
     342             :     {
     343           0 :         Date aReferenceDate(1, 1, 1970);
     344           0 :         sal_Int32 nDays = aDateTime - aReferenceDate;
     345           0 :         xmlXPathReturnNumber(ctxt, nDays);
     346             :     }
     347             :     else
     348           0 :         xmlXPathReturnNumber(ctxt, xmlXPathNAN);
     349             : 
     350             : 
     351             : }
     352             : 
     353             : 
     354           0 : void xforms_secondsFromDateTimeFunction(xmlXPathParserContextPtr ctxt, int nargs)
     355             : {
     356             :     // number of seconds from 1970-01-01T00:00:00Z to supplied xsd:date(Time)
     357             : 
     358           0 :     if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
     359           0 :     xmlChar* pString = xmlXPathPopString(ctxt);
     360           0 :     if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
     361           0 :     ::rtl::OUString aString((char*)pString, strlen((char*)pString), RTL_TEXTENCODING_UTF8);
     362             : 
     363           0 :     DateTime aDateTime( DateTime::EMPTY );
     364             : 
     365           0 :     if (parseDateTime(aString, aDateTime))
     366             :     {
     367           0 :         Date aReferenceDate(1, 1, 1970);
     368           0 :         Time aReferenceTime(0, 0, 0);
     369           0 :         sal_Int32 nDays = aDateTime - aReferenceDate;
     370           0 :         sal_Int32 nSeconds = nDays * 24 * 60 * 60;
     371           0 :         nSeconds += aDateTime.GetHour() * 60 * 60;
     372           0 :         nSeconds += aDateTime.GetMin() * 60;
     373           0 :         nSeconds += aDateTime.GetSec();
     374           0 :         xmlXPathReturnNumber(ctxt, nSeconds);
     375             :     }
     376             :     else
     377           0 :         xmlXPathReturnNumber(ctxt, xmlXPathNAN);
     378             : 
     379             : }
     380             : 
     381           0 : static sal_Bool parseDuration(const xmlChar* aString, sal_Bool& bNegative, sal_Int32& nYears, sal_Int32& nMonth, sal_Int32& nDays,
     382             :                               sal_Int32& nHours, sal_Int32& nMinutes, sal_Int32& nSeconds)
     383             : {
     384           0 :     sal_Bool bTime = sal_False; // in part after T
     385           0 :     sal_Int32 nLength = strlen((char*)aString)+1;
     386           0 :     char *pString = (char*)rtl_allocateMemory(nLength);
     387           0 :     char *pString0 = pString;
     388           0 :     strncpy(pString, (char*)aString, nLength);
     389             : 
     390           0 :     if (pString[0] == '-') {
     391           0 :         bNegative = sal_True;
     392           0 :         pString++;
     393             :     }
     394             : 
     395           0 :     if (pString[0] != 'P')
     396           0 :         return sal_False;
     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 = sal_True;
     432           0 :             pString = ++pToken;
     433           0 :             break;
     434             :         default:
     435           0 :             pToken++;
     436             :         }
     437             :     }
     438           0 :     rtl_freeMemory(pString0);
     439           0 :     return sal_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 :     sal_Bool bNegative = sal_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 :     sal_Bool bNegative = sal_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 :     ::rtl::OUString aString((char*)pString, strlen((char*)pString), RTL_TEXTENCODING_UTF8);
     508             : 
     509           0 :     Reference< XModel > aModel = ((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 = ((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.10