LCOV - code coverage report
Current view: top level - forms/source/xforms/xpathlib - xpathlib.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 309 0.0 %
Date: 2012-08-25 Functions: 0 19 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 441 0.0 %

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

Generated by: LCOV version 1.10