LCOV - code coverage report
Current view: top level - forms/source/xforms/xpathlib - xpathlib.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 0 309 0.0 %
Date: 2014-04-11 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 :     OUString aString((char*)pString, strlen((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 :     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 :     OUString aString((char*)pString, strlen((char*)pString), RTL_TEXTENCODING_UTF8);
     228           0 :     if (aString.equalsIgnoreAsciiCase("version"))
     229           0 :         xmlXPathReturnString(ctxt, (xmlChar*)_version);
     230           0 :     else if (aString.equalsIgnoreAsciiCase("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 OString makeDateTimeString (const DateTime& aDateTime, sal_Bool bUTC = sal_True)
     239             : {
     240           0 :     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 :     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 OUString& aString, DateTime& aDateTime)
     292             : {
     293             :     // take apart a canonical literal xsd:dateTime string
     294             :     //CCYY-MM-DDThh:mm:ss(Z)
     295             : 
     296           0 :     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 :     OUString aUTCString("Z");
     306             : 
     307           0 :     OUString aDateString = aDateTimeString.copy(0, nDateLength);
     308           0 :     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 :     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 :     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 :         sal_Int32 nDays = aDateTime - aReferenceDate;
     369           0 :         sal_Int32 nSeconds = nDays * 24 * 60 * 60;
     370           0 :         nSeconds += aDateTime.GetHour() * 60 * 60;
     371           0 :         nSeconds += aDateTime.GetMin() * 60;
     372           0 :         nSeconds += aDateTime.GetSec();
     373           0 :         xmlXPathReturnNumber(ctxt, nSeconds);
     374             :     }
     375             :     else
     376           0 :         xmlXPathReturnNumber(ctxt, xmlXPathNAN);
     377             : 
     378             : }
     379             : 
     380           0 : static sal_Bool parseDuration(const xmlChar* aString, sal_Bool& bNegative, sal_Int32& nYears, sal_Int32& nMonth, sal_Int32& nDays,
     381             :                               sal_Int32& nHours, sal_Int32& nMinutes, sal_Int32& nSeconds)
     382             : {
     383           0 :     sal_Bool bTime = sal_False; // in part after T
     384           0 :     sal_Int32 nLength = strlen((char*)aString)+1;
     385           0 :     char *pString = (char*)rtl_allocateMemory(nLength);
     386           0 :     char *pString0 = pString;
     387           0 :     strncpy(pString, (char*)aString, nLength);
     388             : 
     389           0 :     if (pString[0] == '-') {
     390           0 :         bNegative = sal_True;
     391           0 :         pString++;
     392             :     }
     393             : 
     394           0 :     if (pString[0] != 'P')
     395             :     {
     396           0 :         rtl_freeMemory(pString0);
     397           0 :         return sal_False;
     398             :     }
     399             : 
     400           0 :     pString++;
     401           0 :     char* pToken = pString;
     402           0 :     while(pToken[0] != 0)
     403             :     {
     404           0 :         switch(pToken[0]) {
     405             :         case 'Y':
     406           0 :             pToken[0] = 0;
     407           0 :             nYears = atoi(pString);
     408           0 :             pString = ++pToken;
     409           0 :             break;
     410             :         case 'M':
     411           0 :             pToken[0] = 0;
     412           0 :             if (!bTime)
     413           0 :                 nMonth = atoi(pString);
     414             :             else
     415           0 :                 nMinutes = atoi(pString);
     416           0 :             pString = ++pToken;
     417           0 :             break;
     418             :         case 'D':
     419           0 :             pToken[0] = 0;
     420           0 :             nDays = atoi(pString);
     421           0 :             pString = ++pToken;
     422           0 :             break;
     423             :         case 'H':
     424           0 :             pToken[0] = 0;
     425           0 :             nHours = atoi(pString);
     426           0 :             pString = ++pToken;
     427           0 :             break;
     428             :         case 'S':
     429           0 :             pToken[0] = 0;
     430           0 :             nSeconds = atoi(pString);
     431           0 :             pString = ++pToken;
     432           0 :             break;
     433             :         case 'T':
     434           0 :             bTime = sal_True;
     435           0 :             pString = ++pToken;
     436           0 :             break;
     437             :         default:
     438           0 :             pToken++;
     439             :         }
     440             :     }
     441           0 :     rtl_freeMemory(pString0);
     442           0 :     return sal_True;
     443             : }
     444             : 
     445           0 : void xforms_secondsFuction(xmlXPathParserContextPtr ctxt, int nargs)
     446             : {
     447             :     // convert a xsd:duration to seconds
     448             :     // (-)PnYnMnDTnHnMnS
     449           0 :     if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
     450           0 :     xmlChar* pString = xmlXPathPopString(ctxt);
     451           0 :     if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
     452             : 
     453           0 :     sal_Bool bNegative = sal_False;
     454           0 :     sal_Int32 nYears = 0;
     455           0 :     sal_Int32 nMonths = 0;
     456           0 :     sal_Int32 nDays = 0;
     457           0 :     sal_Int32 nHours = 0;
     458           0 :     sal_Int32 nMinutes = 0;
     459           0 :     sal_Int32 nSeconds = 0;
     460             : 
     461           0 :     if (parseDuration(pString, bNegative, nYears, nMonths, nDays, nHours, nMinutes, nSeconds))
     462             :     {
     463           0 :         nSeconds += nMinutes*60;
     464           0 :         nSeconds += nHours*60*60;
     465           0 :         nSeconds += nDays*24*60*60;
     466             :         // year and month are ignored according to spec
     467           0 :         if (bNegative)
     468           0 :             nSeconds = 0 - nSeconds;
     469           0 :         xmlXPathReturnNumber(ctxt, nSeconds);
     470             :     }
     471             :     else
     472           0 :         xmlXPathReturnNumber(ctxt, xmlXPathNAN);
     473             : }
     474             : 
     475           0 : void xforms_monthsFuction(xmlXPathParserContextPtr ctxt, int nargs)
     476             : {
     477             :     // convert a xsd:duration to seconds
     478             :     // (-)PnYnMnDTnHnMnS
     479           0 :     if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
     480           0 :     xmlChar* pString = xmlXPathPopString(ctxt);
     481           0 :     if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
     482             : 
     483           0 :     sal_Bool bNegative = sal_False;
     484           0 :     sal_Int32 nYears = 0;
     485           0 :     sal_Int32 nMonths = 0;
     486           0 :     sal_Int32 nDays = 0;
     487           0 :     sal_Int32 nHours = 0;
     488           0 :     sal_Int32 nMinutes = 0;
     489           0 :     sal_Int32 nSeconds = 0;
     490             : 
     491           0 :     if (parseDuration(pString, bNegative, nYears, nMonths, nDays, nHours, nMinutes, nSeconds))
     492             :     {
     493           0 :         nMonths += nYears*12;
     494             :         // Days, Houres, Minutes and seconds are ignored, see spec
     495           0 :         if (bNegative)
     496           0 :             nMonths = 0 - nMonths;
     497           0 :         xmlXPathReturnNumber(ctxt, nMonths);
     498             :     }
     499             :     else
     500           0 :         xmlXPathReturnNumber(ctxt, xmlXPathNAN);
     501             : 
     502             : }
     503             : 
     504             : // Node-set Functions
     505           0 : void xforms_instanceFuction(xmlXPathParserContextPtr ctxt, int nargs)
     506             : {
     507           0 :     if (nargs != 1) XP_ERROR(XPATH_INVALID_ARITY);
     508           0 :     xmlChar *pString = xmlXPathPopString(ctxt);
     509           0 :     if (xmlXPathCheckError(ctxt)) XP_ERROR(XPATH_INVALID_TYPE);
     510           0 :     OUString aString((char*)pString, strlen((char*)pString), RTL_TEXTENCODING_UTF8);
     511             : 
     512           0 :     Reference< XModel > aModel = ((CLibxml2XFormsExtension*)ctxt->context->funcLookupData)->getModel();
     513           0 :     if (aModel.is())
     514             :     {
     515           0 :         Reference< XDocument > aInstance = aModel->getInstanceDocument(aString);
     516           0 :         if (aInstance.is())
     517             :         {
     518             :             try {
     519             :                 // xmlXPathObjectPtr xmlXPathNewNodeSet        (xmlNodePtr val);
     520           0 :                 Reference< XUnoTunnel > aTunnel(aInstance, UNO_QUERY_THROW);
     521           0 :                 xmlNodePtr pNode = reinterpret_cast< xmlNodePtr >( aTunnel->getSomething(Sequence< sal_Int8 >()) );
     522           0 :                 xmlXPathObjectPtr pObject = xmlXPathNewNodeSet(pNode);
     523           0 :                 xmlXPathReturnNodeSet(ctxt, pObject->nodesetval);
     524           0 :             } catch (const RuntimeException&)
     525             :             {
     526           0 :                 xmlXPathReturnEmptyNodeSet(ctxt);
     527             :             }
     528             :         }
     529             :         else
     530           0 :             xmlXPathReturnEmptyNodeSet(ctxt);
     531             :     }
     532             :     else
     533           0 :         xmlXPathReturnEmptyNodeSet(ctxt);
     534             : 
     535             : }
     536             : 
     537             : // Node-set Functions, XForms 1.1
     538           0 : void xforms_currentFunction(xmlXPathParserContextPtr ctxt, int nargs)
     539             : {
     540           0 :     if (nargs != 0) XP_ERROR(XPATH_INVALID_ARITY);
     541             : 
     542           0 :     Reference< XNode > aNode = ((CLibxml2XFormsExtension*)ctxt->context->funcLookupData)->getContextNode();
     543             : 
     544           0 :     if (aNode.is())
     545             :     {
     546             :         try {
     547           0 :             Reference< XUnoTunnel > aTunnel(aNode, UNO_QUERY_THROW);
     548           0 :             xmlNodePtr pNode = reinterpret_cast< xmlNodePtr >( aTunnel->getSomething(Sequence< sal_Int8 >()) );
     549           0 :             xmlXPathObjectPtr pObject = xmlXPathNewNodeSet(pNode);
     550           0 :             xmlXPathReturnNodeSet(ctxt, pObject->nodesetval);
     551             :         }
     552           0 :         catch (const RuntimeException&)
     553             :         {
     554           0 :             xmlXPathReturnEmptyNodeSet(ctxt);
     555             :         }
     556             :     }
     557             :     else
     558           0 :         xmlXPathReturnEmptyNodeSet(ctxt);
     559             : }
     560             : 
     561             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10