From e1b2c9deb5943faae2b29be6a5c006f75bb73f06 Mon Sep 17 00:00:00 2001 From: Qt by Nokia Date: Wed, 27 Apr 2011 12:05:43 +0200 Subject: Initial import from the monolithic Qt. This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12 --- src/xmlpatterns/.gitignore | 1 + src/xmlpatterns/Doxyfile | 1196 +++ src/xmlpatterns/Mainpage.dox | 96 + src/xmlpatterns/acceltree/acceltree.pri | 10 + src/xmlpatterns/acceltree/qacceliterators.cpp | 181 + src/xmlpatterns/acceltree/qacceliterators_p.h | 413 + src/xmlpatterns/acceltree/qacceltree.cpp | 749 ++ src/xmlpatterns/acceltree/qacceltree_p.h | 404 + src/xmlpatterns/acceltree/qacceltreebuilder.cpp | 440 ++ src/xmlpatterns/acceltree/qacceltreebuilder_p.h | 204 + .../acceltree/qacceltreeresourceloader.cpp | 441 ++ .../acceltree/qacceltreeresourceloader_p.h | 210 + .../acceltree/qcompressedwhitespace.cpp | 197 + .../acceltree/qcompressedwhitespace_p.h | 186 + src/xmlpatterns/api/api.pri | 57 + src/xmlpatterns/api/qabstractmessagehandler.cpp | 149 + src/xmlpatterns/api/qabstractmessagehandler.h | 81 + src/xmlpatterns/api/qabstracturiresolver.cpp | 111 + src/xmlpatterns/api/qabstracturiresolver.h | 74 + .../api/qabstractxmlforwarditerator.cpp | 269 + .../api/qabstractxmlforwarditerator_p.h | 341 + src/xmlpatterns/api/qabstractxmlnodemodel.cpp | 1683 ++++ src/xmlpatterns/api/qabstractxmlnodemodel.h | 429 ++ src/xmlpatterns/api/qabstractxmlnodemodel_p.h | 81 + src/xmlpatterns/api/qabstractxmlpullprovider.cpp | 177 + src/xmlpatterns/api/qabstractxmlpullprovider_p.h | 113 + src/xmlpatterns/api/qabstractxmlreceiver.cpp | 475 ++ src/xmlpatterns/api/qabstractxmlreceiver.h | 107 + src/xmlpatterns/api/qabstractxmlreceiver_p.h | 71 + src/xmlpatterns/api/qcoloringmessagehandler.cpp | 198 + src/xmlpatterns/api/qcoloringmessagehandler_p.h | 98 + src/xmlpatterns/api/qcoloroutput.cpp | 377 + src/xmlpatterns/api/qcoloroutput_p.h | 133 + src/xmlpatterns/api/qdeviceresourceloader_p.h | 88 + src/xmlpatterns/api/qiodevicedelegate.cpp | 166 + src/xmlpatterns/api/qiodevicedelegate_p.h | 108 + src/xmlpatterns/api/qnetworkaccessdelegator.cpp | 80 + src/xmlpatterns/api/qnetworkaccessdelegator_p.h | 106 + src/xmlpatterns/api/qpullbridge.cpp | 232 + src/xmlpatterns/api/qpullbridge_p.h | 103 + src/xmlpatterns/api/qreferencecountedvalue_p.h | 106 + src/xmlpatterns/api/qresourcedelegator.cpp | 103 + src/xmlpatterns/api/qresourcedelegator_p.h | 119 + src/xmlpatterns/api/qsimplexmlnodemodel.cpp | 184 + src/xmlpatterns/api/qsimplexmlnodemodel.h | 77 + src/xmlpatterns/api/qsourcelocation.cpp | 240 + src/xmlpatterns/api/qsourcelocation.h | 101 + src/xmlpatterns/api/quriloader.cpp | 84 + src/xmlpatterns/api/quriloader_p.h | 86 + src/xmlpatterns/api/qvariableloader.cpp | 264 + src/xmlpatterns/api/qvariableloader_p.h | 118 + src/xmlpatterns/api/qxmlformatter.cpp | 338 + src/xmlpatterns/api/qxmlformatter.h | 94 + src/xmlpatterns/api/qxmlname.cpp | 511 ++ src/xmlpatterns/api/qxmlname.h | 142 + src/xmlpatterns/api/qxmlnamepool.cpp | 113 + src/xmlpatterns/api/qxmlnamepool.h | 95 + src/xmlpatterns/api/qxmlpatternistcli_p.h | 74 + src/xmlpatterns/api/qxmlquery.cpp | 1209 +++ src/xmlpatterns/api/qxmlquery.h | 155 + src/xmlpatterns/api/qxmlquery_p.h | 328 + src/xmlpatterns/api/qxmlresultitems.cpp | 152 + src/xmlpatterns/api/qxmlresultitems.h | 77 + src/xmlpatterns/api/qxmlresultitems_p.h | 87 + src/xmlpatterns/api/qxmlschema.cpp | 304 + src/xmlpatterns/api/qxmlschema.h | 97 + src/xmlpatterns/api/qxmlschema_p.cpp | 203 + src/xmlpatterns/api/qxmlschema_p.h | 109 + src/xmlpatterns/api/qxmlschemavalidator.cpp | 349 + src/xmlpatterns/api/qxmlschemavalidator.h | 97 + src/xmlpatterns/api/qxmlschemavalidator_p.h | 131 + src/xmlpatterns/api/qxmlserializer.cpp | 653 ++ src/xmlpatterns/api/qxmlserializer.h | 158 + src/xmlpatterns/api/qxmlserializer_p.h | 130 + src/xmlpatterns/common.pri | 18 + src/xmlpatterns/data/data.pri | 82 + src/xmlpatterns/data/qabstractdatetime.cpp | 400 + src/xmlpatterns/data/qabstractdatetime_p.h | 261 + src/xmlpatterns/data/qabstractduration.cpp | 235 + src/xmlpatterns/data/qabstractduration_p.h | 192 + src/xmlpatterns/data/qabstractfloat.cpp | 321 + src/xmlpatterns/data/qabstractfloat_p.h | 174 + src/xmlpatterns/data/qabstractfloatcasters.cpp | 74 + src/xmlpatterns/data/qabstractfloatcasters_p.h | 175 + .../data/qabstractfloatmathematician.cpp | 97 + .../data/qabstractfloatmathematician_p.h | 104 + src/xmlpatterns/data/qanyuri.cpp | 104 + src/xmlpatterns/data/qanyuri_p.h | 212 + src/xmlpatterns/data/qatomiccaster.cpp | 56 + src/xmlpatterns/data/qatomiccaster_p.h | 94 + src/xmlpatterns/data/qatomiccasters.cpp | 336 + src/xmlpatterns/data/qatomiccasters_p.h | 705 ++ src/xmlpatterns/data/qatomiccomparator.cpp | 118 + src/xmlpatterns/data/qatomiccomparator_p.h | 223 + src/xmlpatterns/data/qatomiccomparators.cpp | 386 + src/xmlpatterns/data/qatomiccomparators_p.h | 298 + src/xmlpatterns/data/qatomicmathematician.cpp | 73 + src/xmlpatterns/data/qatomicmathematician_p.h | 136 + src/xmlpatterns/data/qatomicmathematicians.cpp | 352 + src/xmlpatterns/data/qatomicmathematicians_p.h | 249 + src/xmlpatterns/data/qatomicstring.cpp | 74 + src/xmlpatterns/data/qatomicstring_p.h | 123 + src/xmlpatterns/data/qatomicvalue.cpp | 238 + src/xmlpatterns/data/qbase64binary.cpp | 216 + src/xmlpatterns/data/qbase64binary_p.h | 118 + src/xmlpatterns/data/qboolean.cpp | 137 + src/xmlpatterns/data/qboolean_p.h | 126 + src/xmlpatterns/data/qcommonvalues.cpp | 123 + src/xmlpatterns/data/qcommonvalues_p.h | 228 + src/xmlpatterns/data/qcomparisonfactory.cpp | 154 + src/xmlpatterns/data/qcomparisonfactory_p.h | 121 + src/xmlpatterns/data/qdate.cpp | 115 + src/xmlpatterns/data/qdate_p.h | 95 + src/xmlpatterns/data/qdaytimeduration.cpp | 242 + src/xmlpatterns/data/qdaytimeduration_p.h | 154 + src/xmlpatterns/data/qdecimal.cpp | 234 + src/xmlpatterns/data/qdecimal_p.h | 156 + src/xmlpatterns/data/qderivedinteger_p.h | 624 ++ src/xmlpatterns/data/qderivedstring_p.h | 341 + src/xmlpatterns/data/qduration.cpp | 244 + src/xmlpatterns/data/qduration_p.h | 136 + src/xmlpatterns/data/qgday.cpp | 96 + src/xmlpatterns/data/qgday_p.h | 94 + src/xmlpatterns/data/qgmonth.cpp | 95 + src/xmlpatterns/data/qgmonth_p.h | 94 + src/xmlpatterns/data/qgmonthday.cpp | 98 + src/xmlpatterns/data/qgmonthday_p.h | 95 + src/xmlpatterns/data/qgyear.cpp | 101 + src/xmlpatterns/data/qgyear_p.h | 94 + src/xmlpatterns/data/qgyearmonth.cpp | 103 + src/xmlpatterns/data/qgyearmonth_p.h | 94 + src/xmlpatterns/data/qhexbinary.cpp | 151 + src/xmlpatterns/data/qhexbinary_p.h | 109 + src/xmlpatterns/data/qinteger.cpp | 164 + src/xmlpatterns/data/qinteger_p.h | 141 + src/xmlpatterns/data/qitem.cpp | 58 + src/xmlpatterns/data/qitem_p.h | 546 ++ src/xmlpatterns/data/qnodebuilder.cpp | 48 + src/xmlpatterns/data/qnodebuilder_p.h | 111 + src/xmlpatterns/data/qnodemodel.cpp | 52 + src/xmlpatterns/data/qqnamevalue.cpp | 75 + src/xmlpatterns/data/qqnamevalue_p.h | 113 + src/xmlpatterns/data/qresourceloader.cpp | 134 + src/xmlpatterns/data/qresourceloader_p.h | 320 + src/xmlpatterns/data/qschemadatetime.cpp | 117 + src/xmlpatterns/data/qschemadatetime_p.h | 101 + src/xmlpatterns/data/qschemanumeric.cpp | 91 + src/xmlpatterns/data/qschemanumeric_p.h | 235 + src/xmlpatterns/data/qschematime.cpp | 121 + src/xmlpatterns/data/qschematime_p.h | 98 + src/xmlpatterns/data/qsequencereceiver.cpp | 126 + src/xmlpatterns/data/qsequencereceiver_p.h | 192 + src/xmlpatterns/data/qsorttuple.cpp | 89 + src/xmlpatterns/data/qsorttuple_p.h | 148 + src/xmlpatterns/data/quntypedatomic.cpp | 64 + src/xmlpatterns/data/quntypedatomic_p.h | 97 + src/xmlpatterns/data/qvalidationerror.cpp | 90 + src/xmlpatterns/data/qvalidationerror_p.h | 123 + src/xmlpatterns/data/qvaluefactory.cpp | 106 + src/xmlpatterns/data/qvaluefactory_p.h | 98 + src/xmlpatterns/data/qyearmonthduration.cpp | 186 + src/xmlpatterns/data/qyearmonthduration_p.h | 151 + src/xmlpatterns/documentationGroups.dox | 150 + src/xmlpatterns/environment/createReportContext.sh | 53 + .../environment/createReportContext.xsl | 559 ++ src/xmlpatterns/environment/environment.pri | 32 + .../environment/qcurrentitemcontext.cpp | 62 + .../environment/qcurrentitemcontext_p.h | 93 + .../environment/qdelegatingdynamiccontext.cpp | 212 + .../environment/qdelegatingdynamiccontext_p.h | 130 + .../environment/qdelegatingstaticcontext.cpp | 261 + .../environment/qdelegatingstaticcontext_p.h | 147 + src/xmlpatterns/environment/qdynamiccontext.cpp | 68 + src/xmlpatterns/environment/qdynamiccontext_p.h | 231 + src/xmlpatterns/environment/qfocus.cpp | 107 + src/xmlpatterns/environment/qfocus_p.h | 103 + .../environment/qgenericdynamiccontext.cpp | 205 + .../environment/qgenericdynamiccontext_p.h | 155 + .../environment/qgenericstaticcontext.cpp | 338 + .../environment/qgenericstaticcontext_p.h | 199 + .../environment/qreceiverdynamiccontext.cpp | 61 + .../environment/qreceiverdynamiccontext_p.h | 89 + src/xmlpatterns/environment/qreportcontext.cpp | 479 ++ src/xmlpatterns/environment/qreportcontext_p.h | 2464 ++++++ src/xmlpatterns/environment/qstackcontextbase.cpp | 153 + src/xmlpatterns/environment/qstackcontextbase_p.h | 136 + .../environment/qstaticbaseuricontext.cpp | 62 + .../environment/qstaticbaseuricontext_p.h | 91 + .../environment/qstaticcompatibilitycontext.cpp | 57 + .../environment/qstaticcompatibilitycontext_p.h | 84 + src/xmlpatterns/environment/qstaticcontext.cpp | 61 + src/xmlpatterns/environment/qstaticcontext_p.h | 299 + .../environment/qstaticcurrentcontext.cpp | 60 + .../environment/qstaticcurrentcontext_p.h | 90 + .../environment/qstaticfocuscontext.cpp | 59 + .../environment/qstaticfocuscontext_p.h | 91 + .../environment/qstaticnamespacecontext.cpp | 60 + .../environment/qstaticnamespacecontext_p.h | 89 + src/xmlpatterns/expr/expr.pri | 173 + src/xmlpatterns/expr/qandexpression.cpp | 97 + src/xmlpatterns/expr/qandexpression_p.h | 98 + src/xmlpatterns/expr/qapplytemplate.cpp | 210 + src/xmlpatterns/expr/qapplytemplate_p.h | 144 + src/xmlpatterns/expr/qargumentreference.cpp | 86 + src/xmlpatterns/expr/qargumentreference_p.h | 94 + src/xmlpatterns/expr/qarithmeticexpression.cpp | 363 + src/xmlpatterns/expr/qarithmeticexpression_p.h | 133 + src/xmlpatterns/expr/qattributeconstructor.cpp | 127 + src/xmlpatterns/expr/qattributeconstructor_p.h | 108 + src/xmlpatterns/expr/qattributenamevalidator.cpp | 109 + src/xmlpatterns/expr/qattributenamevalidator_p.h | 99 + src/xmlpatterns/expr/qaxisstep.cpp | 247 + src/xmlpatterns/expr/qaxisstep_p.h | 168 + src/xmlpatterns/expr/qcachecells_p.h | 157 + src/xmlpatterns/expr/qcallsite.cpp | 68 + src/xmlpatterns/expr/qcallsite_p.h | 111 + src/xmlpatterns/expr/qcalltargetdescription.cpp | 107 + src/xmlpatterns/expr/qcalltargetdescription_p.h | 120 + src/xmlpatterns/expr/qcalltemplate.cpp | 153 + src/xmlpatterns/expr/qcalltemplate_p.h | 117 + src/xmlpatterns/expr/qcastableas.cpp | 157 + src/xmlpatterns/expr/qcastableas_p.h | 111 + src/xmlpatterns/expr/qcastas.cpp | 204 + src/xmlpatterns/expr/qcastas_p.h | 148 + src/xmlpatterns/expr/qcastingplatform.cpp | 221 + src/xmlpatterns/expr/qcastingplatform_p.h | 206 + src/xmlpatterns/expr/qcollationchecker.cpp | 79 + src/xmlpatterns/expr/qcollationchecker_p.h | 99 + src/xmlpatterns/expr/qcombinenodes.cpp | 172 + src/xmlpatterns/expr/qcombinenodes_p.h | 116 + src/xmlpatterns/expr/qcommentconstructor.cpp | 124 + src/xmlpatterns/expr/qcommentconstructor_p.h | 100 + src/xmlpatterns/expr/qcomparisonplatform.cpp | 199 + src/xmlpatterns/expr/qcomparisonplatform_p.h | 208 + .../expr/qcomputednamespaceconstructor.cpp | 136 + .../expr/qcomputednamespaceconstructor_p.h | 102 + src/xmlpatterns/expr/qcontextitem.cpp | 114 + src/xmlpatterns/expr/qcontextitem_p.h | 128 + src/xmlpatterns/expr/qcopyof.cpp | 134 + src/xmlpatterns/expr/qcopyof_p.h | 121 + src/xmlpatterns/expr/qcurrentitemstore.cpp | 139 + src/xmlpatterns/expr/qcurrentitemstore_p.h | 104 + src/xmlpatterns/expr/qdocumentconstructor.cpp | 116 + src/xmlpatterns/expr/qdocumentconstructor_p.h | 103 + src/xmlpatterns/expr/qdocumentcontentvalidator.cpp | 148 + src/xmlpatterns/expr/qdocumentcontentvalidator_p.h | 117 + src/xmlpatterns/expr/qdynamiccontextstore.cpp | 96 + src/xmlpatterns/expr/qdynamiccontextstore_p.h | 97 + src/xmlpatterns/expr/qelementconstructor.cpp | 160 + src/xmlpatterns/expr/qelementconstructor_p.h | 107 + src/xmlpatterns/expr/qemptycontainer.cpp | 69 + src/xmlpatterns/expr/qemptycontainer_p.h | 101 + src/xmlpatterns/expr/qemptysequence.cpp | 112 + src/xmlpatterns/expr/qemptysequence_p.h | 136 + src/xmlpatterns/expr/qevaluationcache.cpp | 274 + src/xmlpatterns/expr/qevaluationcache_p.h | 146 + src/xmlpatterns/expr/qexpression.cpp | 414 + src/xmlpatterns/expr/qexpression_p.h | 909 +++ src/xmlpatterns/expr/qexpressiondispatch_p.h | 241 + src/xmlpatterns/expr/qexpressionfactory.cpp | 473 ++ src/xmlpatterns/expr/qexpressionfactory_p.h | 187 + src/xmlpatterns/expr/qexpressionsequence.cpp | 206 + src/xmlpatterns/expr/qexpressionsequence_p.h | 127 + .../expr/qexpressionvariablereference.cpp | 93 + .../expr/qexpressionvariablereference_p.h | 114 + src/xmlpatterns/expr/qexternalvariableloader.cpp | 94 + src/xmlpatterns/expr/qexternalvariableloader_p.h | 139 + .../expr/qexternalvariablereference.cpp | 88 + .../expr/qexternalvariablereference_p.h | 103 + src/xmlpatterns/expr/qfirstitempredicate.cpp | 97 + src/xmlpatterns/expr/qfirstitempredicate_p.h | 114 + src/xmlpatterns/expr/qforclause.cpp | 200 + src/xmlpatterns/expr/qforclause_p.h | 122 + src/xmlpatterns/expr/qgeneralcomparison.cpp | 297 + src/xmlpatterns/expr/qgeneralcomparison_p.h | 136 + src/xmlpatterns/expr/qgenericpredicate.cpp | 218 + src/xmlpatterns/expr/qgenericpredicate_p.h | 148 + src/xmlpatterns/expr/qifthenclause.cpp | 152 + src/xmlpatterns/expr/qifthenclause_p.h | 101 + src/xmlpatterns/expr/qinstanceof.cpp | 129 + src/xmlpatterns/expr/qinstanceof_p.h | 101 + src/xmlpatterns/expr/qletclause.cpp | 142 + src/xmlpatterns/expr/qletclause_p.h | 109 + src/xmlpatterns/expr/qliteral.cpp | 114 + src/xmlpatterns/expr/qliteral_p.h | 148 + src/xmlpatterns/expr/qliteralsequence.cpp | 92 + src/xmlpatterns/expr/qliteralsequence_p.h | 104 + src/xmlpatterns/expr/qnamespaceconstructor.cpp | 87 + src/xmlpatterns/expr/qnamespaceconstructor_p.h | 109 + src/xmlpatterns/expr/qncnameconstructor.cpp | 96 + src/xmlpatterns/expr/qncnameconstructor_p.h | 154 + src/xmlpatterns/expr/qnodecomparison.cpp | 184 + src/xmlpatterns/expr/qnodecomparison_p.h | 127 + src/xmlpatterns/expr/qnodesort.cpp | 142 + src/xmlpatterns/expr/qnodesort_p.h | 98 + src/xmlpatterns/expr/qoperandsiterator_p.h | 193 + src/xmlpatterns/expr/qoptimizationpasses.cpp | 182 + src/xmlpatterns/expr/qoptimizationpasses_p.h | 143 + src/xmlpatterns/expr/qoptimizerblocks.cpp | 179 + src/xmlpatterns/expr/qoptimizerblocks_p.h | 226 + src/xmlpatterns/expr/qoptimizerframework.cpp | 71 + src/xmlpatterns/expr/qoptimizerframework_p.h | 294 + src/xmlpatterns/expr/qorderby.cpp | 261 + src/xmlpatterns/expr/qorderby_p.h | 183 + src/xmlpatterns/expr/qorexpression.cpp | 83 + src/xmlpatterns/expr/qorexpression_p.h | 88 + src/xmlpatterns/expr/qpaircontainer.cpp | 85 + src/xmlpatterns/expr/qpaircontainer_p.h | 89 + src/xmlpatterns/expr/qparentnodeaxis.cpp | 77 + src/xmlpatterns/expr/qparentnodeaxis_p.h | 103 + src/xmlpatterns/expr/qpath.cpp | 271 + src/xmlpatterns/expr/qpath_p.h | 176 + .../expr/qpositionalvariablereference.cpp | 84 + .../expr/qpositionalvariablereference_p.h | 100 + .../expr/qprocessinginstructionconstructor.cpp | 144 + .../expr/qprocessinginstructionconstructor_p.h | 109 + src/xmlpatterns/expr/qqnameconstructor.cpp | 114 + src/xmlpatterns/expr/qqnameconstructor_p.h | 182 + src/xmlpatterns/expr/qquantifiedexpression.cpp | 140 + src/xmlpatterns/expr/qquantifiedexpression_p.h | 114 + src/xmlpatterns/expr/qrangeexpression.cpp | 170 + src/xmlpatterns/expr/qrangeexpression_p.h | 112 + src/xmlpatterns/expr/qrangevariablereference.cpp | 92 + src/xmlpatterns/expr/qrangevariablereference_p.h | 100 + src/xmlpatterns/expr/qreturnorderby.cpp | 133 + src/xmlpatterns/expr/qreturnorderby_p.h | 136 + src/xmlpatterns/expr/qsimplecontentconstructor.cpp | 114 + src/xmlpatterns/expr/qsimplecontentconstructor_p.h | 96 + src/xmlpatterns/expr/qsinglecontainer.cpp | 76 + src/xmlpatterns/expr/qsinglecontainer_p.h | 88 + src/xmlpatterns/expr/qsourcelocationreflection.cpp | 65 + src/xmlpatterns/expr/qsourcelocationreflection_p.h | 131 + src/xmlpatterns/expr/qstaticbaseuristore.cpp | 82 + src/xmlpatterns/expr/qstaticbaseuristore_p.h | 96 + src/xmlpatterns/expr/qstaticcompatibilitystore.cpp | 79 + src/xmlpatterns/expr/qstaticcompatibilitystore_p.h | 92 + src/xmlpatterns/expr/qtemplate.cpp | 232 + src/xmlpatterns/expr/qtemplate_p.h | 146 + src/xmlpatterns/expr/qtemplateinvoker.cpp | 106 + src/xmlpatterns/expr/qtemplateinvoker_p.h | 119 + src/xmlpatterns/expr/qtemplatemode.cpp | 61 + src/xmlpatterns/expr/qtemplatemode_p.h | 128 + .../expr/qtemplateparameterreference.cpp | 91 + .../expr/qtemplateparameterreference_p.h | 105 + src/xmlpatterns/expr/qtemplatepattern_p.h | 161 + src/xmlpatterns/expr/qtextnodeconstructor.cpp | 115 + src/xmlpatterns/expr/qtextnodeconstructor_p.h | 97 + src/xmlpatterns/expr/qtreatas.cpp | 92 + src/xmlpatterns/expr/qtreatas_p.h | 122 + src/xmlpatterns/expr/qtriplecontainer.cpp | 87 + src/xmlpatterns/expr/qtriplecontainer_p.h | 92 + src/xmlpatterns/expr/qtruthpredicate.cpp | 71 + src/xmlpatterns/expr/qtruthpredicate_p.h | 112 + src/xmlpatterns/expr/qunaryexpression.cpp | 79 + src/xmlpatterns/expr/qunaryexpression_p.h | 114 + src/xmlpatterns/expr/qunlimitedcontainer.cpp | 79 + src/xmlpatterns/expr/qunlimitedcontainer_p.h | 149 + .../expr/qunresolvedvariablereference.cpp | 91 + .../expr/qunresolvedvariablereference_p.h | 111 + src/xmlpatterns/expr/quserfunction.cpp | 62 + src/xmlpatterns/expr/quserfunction_p.h | 135 + src/xmlpatterns/expr/quserfunctioncallsite.cpp | 245 + src/xmlpatterns/expr/quserfunctioncallsite_p.h | 182 + src/xmlpatterns/expr/qvalidate.cpp | 77 + src/xmlpatterns/expr/qvalidate_p.h | 106 + src/xmlpatterns/expr/qvaluecomparison.cpp | 163 + src/xmlpatterns/expr/qvaluecomparison_p.h | 138 + src/xmlpatterns/expr/qvariabledeclaration.cpp | 63 + src/xmlpatterns/expr/qvariabledeclaration_p.h | 203 + src/xmlpatterns/expr/qvariablereference.cpp | 58 + src/xmlpatterns/expr/qvariablereference_p.h | 121 + src/xmlpatterns/expr/qwithparam_p.h | 123 + .../expr/qxsltsimplecontentconstructor.cpp | 158 + .../expr/qxsltsimplecontentconstructor_p.h | 89 + src/xmlpatterns/functions/functions.pri | 96 + .../functions/qabstractfunctionfactory.cpp | 103 + .../functions/qabstractfunctionfactory_p.h | 157 + src/xmlpatterns/functions/qaccessorfns.cpp | 159 + src/xmlpatterns/functions/qaccessorfns_p.h | 138 + src/xmlpatterns/functions/qaggregatefns.cpp | 316 + src/xmlpatterns/functions/qaggregatefns_p.h | 156 + src/xmlpatterns/functions/qaggregator.cpp | 69 + src/xmlpatterns/functions/qaggregator_p.h | 94 + src/xmlpatterns/functions/qassemblestringfns.cpp | 115 + src/xmlpatterns/functions/qassemblestringfns_p.h | 103 + src/xmlpatterns/functions/qbooleanfns.cpp | 71 + src/xmlpatterns/functions/qbooleanfns_p.h | 119 + src/xmlpatterns/functions/qcomparescaseaware.cpp | 71 + src/xmlpatterns/functions/qcomparescaseaware_p.h | 98 + src/xmlpatterns/functions/qcomparestringfns.cpp | 102 + src/xmlpatterns/functions/qcomparestringfns_p.h | 102 + src/xmlpatterns/functions/qcomparingaggregator.cpp | 212 + src/xmlpatterns/functions/qcomparingaggregator_p.h | 146 + .../functions/qconstructorfunctionsfactory.cpp | 114 + .../functions/qconstructorfunctionsfactory_p.h | 95 + src/xmlpatterns/functions/qcontextfns.cpp | 102 + src/xmlpatterns/functions/qcontextfns_p.h | 195 + src/xmlpatterns/functions/qcontextnodechecker.cpp | 63 + src/xmlpatterns/functions/qcontextnodechecker_p.h | 85 + src/xmlpatterns/functions/qcurrentfn.cpp | 75 + src/xmlpatterns/functions/qcurrentfn_p.h | 89 + src/xmlpatterns/functions/qdatetimefn.cpp | 96 + src/xmlpatterns/functions/qdatetimefn_p.h | 82 + src/xmlpatterns/functions/qdatetimefns.cpp | 145 + src/xmlpatterns/functions/qdatetimefns_p.h | 305 + src/xmlpatterns/functions/qdeepequalfn.cpp | 162 + src/xmlpatterns/functions/qdeepequalfn_p.h | 94 + src/xmlpatterns/functions/qdocumentfn.cpp | 115 + src/xmlpatterns/functions/qdocumentfn_p.h | 124 + src/xmlpatterns/functions/qelementavailablefn.cpp | 120 + src/xmlpatterns/functions/qelementavailablefn_p.h | 87 + src/xmlpatterns/functions/qerrorfn.cpp | 113 + src/xmlpatterns/functions/qerrorfn_p.h | 91 + src/xmlpatterns/functions/qfunctionargument.cpp | 66 + src/xmlpatterns/functions/qfunctionargument_p.h | 98 + src/xmlpatterns/functions/qfunctionavailablefn.cpp | 91 + src/xmlpatterns/functions/qfunctionavailablefn_p.h | 92 + src/xmlpatterns/functions/qfunctioncall.cpp | 160 + src/xmlpatterns/functions/qfunctioncall_p.h | 102 + src/xmlpatterns/functions/qfunctionfactory.cpp | 79 + src/xmlpatterns/functions/qfunctionfactory_p.h | 168 + .../functions/qfunctionfactorycollection.cpp | 138 + .../functions/qfunctionfactorycollection_p.h | 118 + src/xmlpatterns/functions/qfunctionsignature.cpp | 158 + src/xmlpatterns/functions/qfunctionsignature_p.h | 213 + src/xmlpatterns/functions/qgenerateidfn.cpp | 63 + src/xmlpatterns/functions/qgenerateidfn_p.h | 83 + src/xmlpatterns/functions/qnodefns.cpp | 209 + src/xmlpatterns/functions/qnodefns_p.h | 176 + src/xmlpatterns/functions/qnumericfns.cpp | 107 + src/xmlpatterns/functions/qnumericfns_p.h | 140 + src/xmlpatterns/functions/qpatternmatchingfns.cpp | 230 + src/xmlpatterns/functions/qpatternmatchingfns_p.h | 139 + src/xmlpatterns/functions/qpatternplatform.cpp | 301 + src/xmlpatterns/functions/qpatternplatform_p.h | 195 + src/xmlpatterns/functions/qqnamefns.cpp | 189 + src/xmlpatterns/functions/qqnamefns_p.h | 162 + src/xmlpatterns/functions/qresolveurifn.cpp | 87 + src/xmlpatterns/functions/qresolveurifn_p.h | 82 + src/xmlpatterns/functions/qsequencefns.cpp | 352 + src/xmlpatterns/functions/qsequencefns_p.h | 344 + .../functions/qsequencegeneratingfns.cpp | 291 + .../functions/qsequencegeneratingfns_p.h | 167 + .../functions/qstaticbaseuricontainer_p.h | 107 + .../functions/qstaticnamespacescontainer.cpp | 57 + .../functions/qstaticnamespacescontainer_p.h | 115 + src/xmlpatterns/functions/qstringvaluefns.cpp | 373 + src/xmlpatterns/functions/qstringvaluefns_p.h | 293 + src/xmlpatterns/functions/qsubstringfns.cpp | 173 + src/xmlpatterns/functions/qsubstringfns_p.h | 136 + src/xmlpatterns/functions/qsystempropertyfn.cpp | 101 + src/xmlpatterns/functions/qsystempropertyfn_p.h | 92 + src/xmlpatterns/functions/qtimezonefns.cpp | 166 + src/xmlpatterns/functions/qtimezonefns_p.h | 136 + src/xmlpatterns/functions/qtracefn.cpp | 140 + src/xmlpatterns/functions/qtracefn_p.h | 94 + src/xmlpatterns/functions/qtypeavailablefn.cpp | 74 + src/xmlpatterns/functions/qtypeavailablefn_p.h | 92 + .../functions/qunparsedentitypublicidfn.cpp | 56 + .../functions/qunparsedentitypublicidfn_p.h | 82 + src/xmlpatterns/functions/qunparsedentityurifn.cpp | 56 + src/xmlpatterns/functions/qunparsedentityurifn_p.h | 82 + .../functions/qunparsedtextavailablefn.cpp | 85 + .../functions/qunparsedtextavailablefn_p.h | 83 + src/xmlpatterns/functions/qunparsedtextfn.cpp | 82 + src/xmlpatterns/functions/qunparsedtextfn_p.h | 83 + .../functions/qxpath10corefunctions.cpp | 300 + .../functions/qxpath10corefunctions_p.h | 93 + .../functions/qxpath20corefunctions.cpp | 748 ++ .../functions/qxpath20corefunctions_p.h | 96 + src/xmlpatterns/functions/qxslt20corefunctions.cpp | 175 + src/xmlpatterns/functions/qxslt20corefunctions_p.h | 94 + src/xmlpatterns/iterators/iterators.pri | 29 + src/xmlpatterns/iterators/qcachingiterator.cpp | 130 + src/xmlpatterns/iterators/qcachingiterator_p.h | 129 + src/xmlpatterns/iterators/qdeduplicateiterator.cpp | 95 + src/xmlpatterns/iterators/qdeduplicateiterator_p.h | 103 + src/xmlpatterns/iterators/qdistinctiterator.cpp | 112 + src/xmlpatterns/iterators/qdistinctiterator_p.h | 128 + src/xmlpatterns/iterators/qemptyiterator_p.h | 146 + src/xmlpatterns/iterators/qexceptiterator.cpp | 122 + src/xmlpatterns/iterators/qexceptiterator_p.h | 101 + src/xmlpatterns/iterators/qindexofiterator.cpp | 115 + src/xmlpatterns/iterators/qindexofiterator_p.h | 129 + src/xmlpatterns/iterators/qinsertioniterator.cpp | 128 + src/xmlpatterns/iterators/qinsertioniterator_p.h | 120 + src/xmlpatterns/iterators/qintersectiterator.cpp | 115 + src/xmlpatterns/iterators/qintersectiterator_p.h | 107 + src/xmlpatterns/iterators/qitemmappingiterator_p.h | 190 + src/xmlpatterns/iterators/qrangeiterator.cpp | 126 + src/xmlpatterns/iterators/qrangeiterator_p.h | 141 + src/xmlpatterns/iterators/qremovaliterator.cpp | 109 + src/xmlpatterns/iterators/qremovaliterator_p.h | 122 + .../iterators/qsequencemappingiterator_p.h | 237 + src/xmlpatterns/iterators/qsingletoniterator_p.h | 177 + src/xmlpatterns/iterators/qsubsequenceiterator.cpp | 110 + src/xmlpatterns/iterators/qsubsequenceiterator_p.h | 118 + .../iterators/qtocodepointsiterator.cpp | 95 + .../iterators/qtocodepointsiterator_p.h | 103 + src/xmlpatterns/iterators/qunioniterator.cpp | 131 + src/xmlpatterns/iterators/qunioniterator_p.h | 107 + src/xmlpatterns/janitors/janitors.pri | 13 + src/xmlpatterns/janitors/qargumentconverter.cpp | 104 + src/xmlpatterns/janitors/qargumentconverter_p.h | 103 + src/xmlpatterns/janitors/qatomizer.cpp | 125 + src/xmlpatterns/janitors/qatomizer_p.h | 110 + src/xmlpatterns/janitors/qcardinalityverifier.cpp | 224 + src/xmlpatterns/janitors/qcardinalityverifier_p.h | 128 + src/xmlpatterns/janitors/qebvextractor.cpp | 90 + src/xmlpatterns/janitors/qebvextractor_p.h | 109 + src/xmlpatterns/janitors/qitemverifier.cpp | 122 + src/xmlpatterns/janitors/qitemverifier_p.h | 103 + .../janitors/quntypedatomicconverter.cpp | 113 + .../janitors/quntypedatomicconverter_p.h | 127 + src/xmlpatterns/parser/.gitattributes | 4 + src/xmlpatterns/parser/.gitignore | 1 + src/xmlpatterns/parser/TokenLookup.gperf | 223 + src/xmlpatterns/parser/createParser.sh | 55 + src/xmlpatterns/parser/createTokenLookup.sh | 91 + src/xmlpatterns/parser/createXSLTTokenLookup.sh | 44 + src/xmlpatterns/parser/parser.pri | 19 + src/xmlpatterns/parser/qmaintainingreader.cpp | 274 + src/xmlpatterns/parser/qmaintainingreader_p.h | 234 + src/xmlpatterns/parser/qparsercontext.cpp | 100 + src/xmlpatterns/parser/qparsercontext_p.h | 433 ++ src/xmlpatterns/parser/qquerytransformparser.cpp | 8035 ++++++++++++++++++++ src/xmlpatterns/parser/qquerytransformparser_p.h | 338 + src/xmlpatterns/parser/qtokenizer_p.h | 216 + src/xmlpatterns/parser/qtokenlookup.cpp | 444 ++ src/xmlpatterns/parser/qtokenrevealer.cpp | 111 + src/xmlpatterns/parser/qtokenrevealer_p.h | 97 + src/xmlpatterns/parser/qtokensource.cpp | 53 + src/xmlpatterns/parser/qtokensource_p.h | 169 + src/xmlpatterns/parser/querytransformparser.ypp | 4680 ++++++++++++ src/xmlpatterns/parser/qxquerytokenizer.cpp | 2249 ++++++ src/xmlpatterns/parser/qxquerytokenizer_p.h | 332 + src/xmlpatterns/parser/qxslttokenizer.cpp | 2717 +++++++ src/xmlpatterns/parser/qxslttokenizer_p.h | 481 ++ src/xmlpatterns/parser/qxslttokenlookup.cpp | 3006 ++++++++ src/xmlpatterns/parser/qxslttokenlookup.xml | 167 + src/xmlpatterns/parser/qxslttokenlookup_p.h | 213 + src/xmlpatterns/parser/trolltechHeader.txt | 51 + src/xmlpatterns/parser/winCEWorkaround.sed | 32 + src/xmlpatterns/projection/projection.pri | 4 + src/xmlpatterns/projection/qdocumentprojector.cpp | 214 + src/xmlpatterns/projection/qdocumentprojector_p.h | 107 + .../projection/qprojectedexpression_p.h | 165 + src/xmlpatterns/qtokenautomaton/README | 66 + src/xmlpatterns/qtokenautomaton/exampleFile.xml | 65 + src/xmlpatterns/qtokenautomaton/qautomaton2cpp.xsl | 298 + .../qtokenautomaton/qtokenautomaton.xsd | 89 + src/xmlpatterns/query.pri | 14 + src/xmlpatterns/schema/.gitignore | 1 + src/xmlpatterns/schema/builtinschemas.qrc | 5 + src/xmlpatterns/schema/doc/All_diagram.dot | 13 + src/xmlpatterns/schema/doc/Alternative_diagram.dot | 11 + src/xmlpatterns/schema/doc/Annotation_diagram.dot | 9 + .../schema/doc/AnyAttribute_diagram.dot | 6 + src/xmlpatterns/schema/doc/Any_diagram.dot | 6 + src/xmlpatterns/schema/doc/Assert_diagram.dot | 6 + src/xmlpatterns/schema/doc/Choice_diagram.dot | 22 + .../schema/doc/ComplexContentExtension_diagram.dot | 47 + .../doc/ComplexContentRestriction_diagram.dot | 47 + .../schema/doc/ComplexContent_diagram.dot | 11 + .../schema/doc/DefaultOpenContent_diagram.dot | 9 + .../schema/doc/EnumerationFacet_diagram.dot | 6 + src/xmlpatterns/schema/doc/Field_diagram.dot | 6 + .../schema/doc/FractionDigitsFacet_diagram.dot | 6 + .../schema/doc/GlobalAttribute_diagram.dot | 9 + .../schema/doc/GlobalComplexType_diagram.dot | 52 + .../schema/doc/GlobalElement_diagram.dot | 32 + .../schema/doc/GlobalSimpleType_diagram.dot | 13 + src/xmlpatterns/schema/doc/Import_diagram.dot | 6 + src/xmlpatterns/schema/doc/Include_diagram.dot | 6 + src/xmlpatterns/schema/doc/KeyRef_diagram.dot | 12 + src/xmlpatterns/schema/doc/Key_diagram.dot | 12 + src/xmlpatterns/schema/doc/LengthFacet_diagram.dot | 6 + src/xmlpatterns/schema/doc/List_diagram.dot | 9 + src/xmlpatterns/schema/doc/LocalAll_diagram.dot | 13 + .../schema/doc/LocalAttribute_diagram.dot | 9 + src/xmlpatterns/schema/doc/LocalChoice_diagram.dot | 22 + .../schema/doc/LocalComplexType_diagram.dot | 52 + .../schema/doc/LocalElement_diagram.dot | 32 + .../schema/doc/LocalSequence_diagram.dot | 22 + .../schema/doc/LocalSimpleType_diagram.dot | 13 + .../schema/doc/MaxExclusiveFacet_diagram.dot | 6 + .../schema/doc/MaxInclusiveFacet_diagram.dot | 6 + .../schema/doc/MaxLengthFacet_diagram.dot | 6 + .../schema/doc/MinExclusiveFacet_diagram.dot | 6 + .../schema/doc/MinInclusiveFacet_diagram.dot | 6 + .../schema/doc/MinLengthFacet_diagram.dot | 6 + .../schema/doc/NamedAttributeGroup_diagram.dot | 17 + src/xmlpatterns/schema/doc/NamedGroup_diagram.dot | 13 + src/xmlpatterns/schema/doc/Notation_diagram.dot | 6 + src/xmlpatterns/schema/doc/Override_diagram.dot | 21 + .../schema/doc/PatternFacet_diagram.dot | 6 + src/xmlpatterns/schema/doc/Redefine_diagram.dot | 15 + .../schema/doc/ReferredAttributeGroup_diagram.dot | 6 + .../schema/doc/ReferredGroup_diagram.dot | 13 + src/xmlpatterns/schema/doc/Schema_diagram.dot | 66 + src/xmlpatterns/schema/doc/Selector_diagram.dot | 6 + src/xmlpatterns/schema/doc/Sequence_diagram.dot | 22 + .../schema/doc/SimpleContentExtension_diagram.dot | 23 + .../doc/SimpleContentRestriction_diagram.dot | 87 + .../schema/doc/SimpleContent_diagram.dot | 11 + .../schema/doc/SimpleRestriction_diagram.dot | 62 + .../schema/doc/TotalDigitsFacet_diagram.dot | 6 + src/xmlpatterns/schema/doc/Union_diagram.dot | 10 + src/xmlpatterns/schema/doc/Unique_diagram.dot | 12 + .../schema/doc/WhiteSpaceFacet_diagram.dot | 6 + src/xmlpatterns/schema/doc/legend.dot | 7 + src/xmlpatterns/schema/qnamespacesupport.cpp | 160 + src/xmlpatterns/schema/qnamespacesupport_p.h | 173 + src/xmlpatterns/schema/qxsdalternative.cpp | 68 + src/xmlpatterns/schema/qxsdalternative_p.h | 114 + src/xmlpatterns/schema/qxsdannotated.cpp | 63 + src/xmlpatterns/schema/qxsdannotated_p.h | 96 + src/xmlpatterns/schema/qxsdannotation.cpp | 78 + src/xmlpatterns/schema/qxsdannotation_p.h | 127 + .../schema/qxsdapplicationinformation.cpp | 68 + .../schema/qxsdapplicationinformation_p.h | 115 + src/xmlpatterns/schema/qxsdassertion.cpp | 58 + src/xmlpatterns/schema/qxsdassertion_p.h | 101 + src/xmlpatterns/schema/qxsdattribute.cpp | 130 + src/xmlpatterns/schema/qxsdattribute_p.h | 246 + src/xmlpatterns/schema/qxsdattributegroup.cpp | 73 + src/xmlpatterns/schema/qxsdattributegroup_p.h | 122 + src/xmlpatterns/schema/qxsdattributereference.cpp | 88 + src/xmlpatterns/schema/qxsdattributereference_p.h | 147 + src/xmlpatterns/schema/qxsdattributeterm.cpp | 58 + src/xmlpatterns/schema/qxsdattributeterm_p.h | 96 + src/xmlpatterns/schema/qxsdattributeuse.cpp | 136 + src/xmlpatterns/schema/qxsdattributeuse_p.h | 224 + src/xmlpatterns/schema/qxsdcomplextype.cpp | 231 + src/xmlpatterns/schema/qxsdcomplextype_p.h | 404 + src/xmlpatterns/schema/qxsddocumentation.cpp | 86 + src/xmlpatterns/schema/qxsddocumentation_p.h | 137 + src/xmlpatterns/schema/qxsdelement.cpp | 244 + src/xmlpatterns/schema/qxsdelement_p.h | 403 + src/xmlpatterns/schema/qxsdfacet.cpp | 124 + src/xmlpatterns/schema/qxsdfacet_p.h | 213 + src/xmlpatterns/schema/qxsdidcache.cpp | 66 + src/xmlpatterns/schema/qxsdidcache_p.h | 99 + src/xmlpatterns/schema/qxsdidchelper.cpp | 137 + src/xmlpatterns/schema/qxsdidchelper_p.h | 186 + src/xmlpatterns/schema/qxsdidentityconstraint.cpp | 93 + src/xmlpatterns/schema/qxsdidentityconstraint_p.h | 173 + src/xmlpatterns/schema/qxsdinstancereader.cpp | 196 + src/xmlpatterns/schema/qxsdinstancereader_p.h | 189 + src/xmlpatterns/schema/qxsdmodelgroup.cpp | 78 + src/xmlpatterns/schema/qxsdmodelgroup_p.h | 139 + src/xmlpatterns/schema/qxsdnotation.cpp | 68 + src/xmlpatterns/schema/qxsdnotation_p.h | 119 + src/xmlpatterns/schema/qxsdparticle.cpp | 95 + src/xmlpatterns/schema/qxsdparticle_p.h | 154 + src/xmlpatterns/schema/qxsdparticlechecker.cpp | 570 ++ src/xmlpatterns/schema/qxsdparticlechecker_p.h | 106 + src/xmlpatterns/schema/qxsdreference.cpp | 83 + src/xmlpatterns/schema/qxsdreference_p.h | 145 + src/xmlpatterns/schema/qxsdschema.cpp | 272 + src/xmlpatterns/schema/qxsdschema_p.h | 301 + src/xmlpatterns/schema/qxsdschemachecker.cpp | 2061 +++++ .../schema/qxsdschemachecker_helper.cpp | 306 + src/xmlpatterns/schema/qxsdschemachecker_p.h | 284 + src/xmlpatterns/schema/qxsdschemachecker_setup.cpp | 327 + src/xmlpatterns/schema/qxsdschemacontext.cpp | 528 ++ src/xmlpatterns/schema/qxsdschemacontext_p.h | 187 + src/xmlpatterns/schema/qxsdschemadebugger.cpp | 226 + src/xmlpatterns/schema/qxsdschemadebugger_p.h | 127 + src/xmlpatterns/schema/qxsdschemahelper.cpp | 821 ++ src/xmlpatterns/schema/qxsdschemahelper_p.h | 217 + src/xmlpatterns/schema/qxsdschemamerger.cpp | 157 + src/xmlpatterns/schema/qxsdschemamerger_p.h | 99 + src/xmlpatterns/schema/qxsdschemaparser.cpp | 6119 +++++++++++++++ src/xmlpatterns/schema/qxsdschemaparser_p.h | 739 ++ src/xmlpatterns/schema/qxsdschemaparser_setup.cpp | 1110 +++ src/xmlpatterns/schema/qxsdschemaparsercontext.cpp | 603 ++ src/xmlpatterns/schema/qxsdschemaparsercontext_p.h | 231 + src/xmlpatterns/schema/qxsdschemaresolver.cpp | 1743 +++++ src/xmlpatterns/schema/qxsdschemaresolver_p.h | 578 ++ src/xmlpatterns/schema/qxsdschematoken.cpp | 2981 ++++++++ src/xmlpatterns/schema/qxsdschematoken_p.h | 209 + src/xmlpatterns/schema/qxsdschematypesfactory.cpp | 126 + src/xmlpatterns/schema/qxsdschematypesfactory_p.h | 109 + src/xmlpatterns/schema/qxsdsimpletype.cpp | 148 + src/xmlpatterns/schema/qxsdsimpletype_p.h | 219 + src/xmlpatterns/schema/qxsdstatemachine.cpp | 413 + src/xmlpatterns/schema/qxsdstatemachine_p.h | 308 + src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp | 260 + src/xmlpatterns/schema/qxsdstatemachinebuilder_p.h | 141 + src/xmlpatterns/schema/qxsdterm.cpp | 68 + src/xmlpatterns/schema/qxsdterm_p.h | 114 + src/xmlpatterns/schema/qxsdtypechecker.cpp | 1339 ++++ src/xmlpatterns/schema/qxsdtypechecker_p.h | 189 + src/xmlpatterns/schema/qxsduserschematype.cpp | 75 + src/xmlpatterns/schema/qxsduserschematype_p.h | 124 + .../schema/qxsdvalidatedxmlnodemodel.cpp | 215 + .../schema/qxsdvalidatedxmlnodemodel_p.h | 179 + .../schema/qxsdvalidatinginstancereader.cpp | 1276 ++++ .../schema/qxsdvalidatinginstancereader_p.h | 296 + src/xmlpatterns/schema/qxsdwildcard.cpp | 115 + src/xmlpatterns/schema/qxsdwildcard_p.h | 199 + src/xmlpatterns/schema/qxsdxpathexpression.cpp | 88 + src/xmlpatterns/schema/qxsdxpathexpression_p.h | 143 + src/xmlpatterns/schema/schema.pri | 93 + src/xmlpatterns/schema/schemas/xml.xsd | 145 + src/xmlpatterns/schema/schemas/xml.xsd-LICENSE | 40 + src/xmlpatterns/schema/tokens.xml | 155 + src/xmlpatterns/type/qabstractnodetest.cpp | 78 + src/xmlpatterns/type/qabstractnodetest_p.h | 87 + src/xmlpatterns/type/qanyitemtype.cpp | 90 + src/xmlpatterns/type/qanyitemtype_p.h | 119 + src/xmlpatterns/type/qanynodetype.cpp | 98 + src/xmlpatterns/type/qanynodetype_p.h | 113 + src/xmlpatterns/type/qanysimpletype.cpp | 93 + src/xmlpatterns/type/qanysimpletype_p.h | 130 + src/xmlpatterns/type/qanytype.cpp | 103 + src/xmlpatterns/type/qanytype_p.h | 142 + src/xmlpatterns/type/qatomiccasterlocator.cpp | 82 + src/xmlpatterns/type/qatomiccasterlocator_p.h | 126 + src/xmlpatterns/type/qatomiccasterlocators.cpp | 252 + src/xmlpatterns/type/qatomiccasterlocators_p.h | 909 +++ src/xmlpatterns/type/qatomiccomparatorlocator.cpp | 91 + src/xmlpatterns/type/qatomiccomparatorlocator_p.h | 132 + src/xmlpatterns/type/qatomiccomparatorlocators.cpp | 232 + src/xmlpatterns/type/qatomiccomparatorlocators_p.h | 356 + .../type/qatomicmathematicianlocator.cpp | 85 + .../type/qatomicmathematicianlocator_p.h | 158 + .../type/qatomicmathematicianlocators.cpp | 168 + .../type/qatomicmathematicianlocators_p.h | 249 + src/xmlpatterns/type/qatomictype.cpp | 118 + src/xmlpatterns/type/qatomictype_p.h | 160 + src/xmlpatterns/type/qatomictypedispatch_p.h | 277 + src/xmlpatterns/type/qbasictypesfactory.cpp | 128 + src/xmlpatterns/type/qbasictypesfactory_p.h | 121 + src/xmlpatterns/type/qbuiltinatomictype.cpp | 94 + src/xmlpatterns/type/qbuiltinatomictype_p.h | 130 + src/xmlpatterns/type/qbuiltinatomictypes.cpp | 226 + src/xmlpatterns/type/qbuiltinatomictypes_p.h | 789 ++ src/xmlpatterns/type/qbuiltinnodetype.cpp | 165 + src/xmlpatterns/type/qbuiltinnodetype_p.h | 110 + src/xmlpatterns/type/qbuiltintypes.cpp | 161 + src/xmlpatterns/type/qbuiltintypes_p.h | 174 + src/xmlpatterns/type/qcardinality.cpp | 102 + src/xmlpatterns/type/qcardinality_p.h | 544 ++ src/xmlpatterns/type/qcommonsequencetypes.cpp | 132 + src/xmlpatterns/type/qcommonsequencetypes_p.h | 414 + src/xmlpatterns/type/qebvtype.cpp | 123 + src/xmlpatterns/type/qebvtype_p.h | 135 + src/xmlpatterns/type/qemptysequencetype.cpp | 101 + src/xmlpatterns/type/qemptysequencetype_p.h | 124 + src/xmlpatterns/type/qgenericsequencetype.cpp | 72 + src/xmlpatterns/type/qgenericsequencetype_p.h | 115 + src/xmlpatterns/type/qitemtype.cpp | 103 + src/xmlpatterns/type/qitemtype_p.h | 286 + src/xmlpatterns/type/qlocalnametest.cpp | 99 + src/xmlpatterns/type/qlocalnametest_p.h | 102 + src/xmlpatterns/type/qmultiitemtype.cpp | 140 + src/xmlpatterns/type/qmultiitemtype_p.h | 146 + src/xmlpatterns/type/qnamedschemacomponent.cpp | 71 + src/xmlpatterns/type/qnamedschemacomponent_p.h | 127 + src/xmlpatterns/type/qnamespacenametest.cpp | 95 + src/xmlpatterns/type/qnamespacenametest_p.h | 101 + src/xmlpatterns/type/qnonetype.cpp | 104 + src/xmlpatterns/type/qnonetype_p.h | 155 + src/xmlpatterns/type/qnumerictype.cpp | 142 + src/xmlpatterns/type/qnumerictype_p.h | 174 + src/xmlpatterns/type/qprimitives_p.h | 203 + src/xmlpatterns/type/qqnametest.cpp | 99 + src/xmlpatterns/type/qqnametest_p.h | 103 + src/xmlpatterns/type/qschemacomponent.cpp | 56 + src/xmlpatterns/type/qschemacomponent_p.h | 85 + src/xmlpatterns/type/qschematype.cpp | 80 + src/xmlpatterns/type/qschematype_p.h | 248 + src/xmlpatterns/type/qschematypefactory.cpp | 56 + src/xmlpatterns/type/qschematypefactory_p.h | 102 + src/xmlpatterns/type/qsequencetype.cpp | 65 + src/xmlpatterns/type/qsequencetype_p.h | 138 + src/xmlpatterns/type/qtypechecker.cpp | 296 + src/xmlpatterns/type/qtypechecker_p.h | 185 + src/xmlpatterns/type/quntyped.cpp | 79 + src/xmlpatterns/type/quntyped_p.h | 112 + src/xmlpatterns/type/qxsltnodetest.cpp | 72 + src/xmlpatterns/type/qxsltnodetest_p.h | 100 + src/xmlpatterns/type/type.pri | 72 + src/xmlpatterns/utils/qautoptr.cpp | 48 + src/xmlpatterns/utils/qautoptr_p.h | 175 + src/xmlpatterns/utils/qcommonnamespaces_p.h | 152 + src/xmlpatterns/utils/qcppcastinghelper_p.h | 161 + src/xmlpatterns/utils/qdebug_p.h | 107 + .../utils/qdelegatingnamespaceresolver.cpp | 92 + .../utils/qdelegatingnamespaceresolver_p.h | 96 + .../utils/qgenericnamespaceresolver.cpp | 96 + .../utils/qgenericnamespaceresolver_p.h | 113 + src/xmlpatterns/utils/qnamepool.cpp | 418 + src/xmlpatterns/utils/qnamepool_p.h | 556 ++ src/xmlpatterns/utils/qnamespacebinding_p.h | 143 + src/xmlpatterns/utils/qnamespaceresolver.cpp | 57 + src/xmlpatterns/utils/qnamespaceresolver_p.h | 119 + src/xmlpatterns/utils/qnodenamespaceresolver.cpp | 83 + src/xmlpatterns/utils/qnodenamespaceresolver_p.h | 91 + src/xmlpatterns/utils/qoutputvalidator.cpp | 162 + src/xmlpatterns/utils/qoutputvalidator_p.h | 127 + src/xmlpatterns/utils/qpatternistlocale.cpp | 91 + src/xmlpatterns/utils/qpatternistlocale_p.h | 281 + src/xmlpatterns/utils/qxpathhelper.cpp | 140 + src/xmlpatterns/utils/qxpathhelper_p.h | 179 + src/xmlpatterns/utils/utils.pri | 21 + src/xmlpatterns/xmlpatterns.pro | 37 + 809 files changed, 160137 insertions(+) create mode 100644 src/xmlpatterns/.gitignore create mode 100644 src/xmlpatterns/Doxyfile create mode 100644 src/xmlpatterns/Mainpage.dox create mode 100644 src/xmlpatterns/acceltree/acceltree.pri create mode 100644 src/xmlpatterns/acceltree/qacceliterators.cpp create mode 100644 src/xmlpatterns/acceltree/qacceliterators_p.h create mode 100644 src/xmlpatterns/acceltree/qacceltree.cpp create mode 100644 src/xmlpatterns/acceltree/qacceltree_p.h create mode 100644 src/xmlpatterns/acceltree/qacceltreebuilder.cpp create mode 100644 src/xmlpatterns/acceltree/qacceltreebuilder_p.h create mode 100644 src/xmlpatterns/acceltree/qacceltreeresourceloader.cpp create mode 100644 src/xmlpatterns/acceltree/qacceltreeresourceloader_p.h create mode 100644 src/xmlpatterns/acceltree/qcompressedwhitespace.cpp create mode 100644 src/xmlpatterns/acceltree/qcompressedwhitespace_p.h create mode 100644 src/xmlpatterns/api/api.pri create mode 100644 src/xmlpatterns/api/qabstractmessagehandler.cpp create mode 100644 src/xmlpatterns/api/qabstractmessagehandler.h create mode 100644 src/xmlpatterns/api/qabstracturiresolver.cpp create mode 100644 src/xmlpatterns/api/qabstracturiresolver.h create mode 100644 src/xmlpatterns/api/qabstractxmlforwarditerator.cpp create mode 100644 src/xmlpatterns/api/qabstractxmlforwarditerator_p.h create mode 100644 src/xmlpatterns/api/qabstractxmlnodemodel.cpp create mode 100644 src/xmlpatterns/api/qabstractxmlnodemodel.h create mode 100644 src/xmlpatterns/api/qabstractxmlnodemodel_p.h create mode 100644 src/xmlpatterns/api/qabstractxmlpullprovider.cpp create mode 100644 src/xmlpatterns/api/qabstractxmlpullprovider_p.h create mode 100644 src/xmlpatterns/api/qabstractxmlreceiver.cpp create mode 100644 src/xmlpatterns/api/qabstractxmlreceiver.h create mode 100644 src/xmlpatterns/api/qabstractxmlreceiver_p.h create mode 100644 src/xmlpatterns/api/qcoloringmessagehandler.cpp create mode 100644 src/xmlpatterns/api/qcoloringmessagehandler_p.h create mode 100644 src/xmlpatterns/api/qcoloroutput.cpp create mode 100644 src/xmlpatterns/api/qcoloroutput_p.h create mode 100644 src/xmlpatterns/api/qdeviceresourceloader_p.h create mode 100644 src/xmlpatterns/api/qiodevicedelegate.cpp create mode 100644 src/xmlpatterns/api/qiodevicedelegate_p.h create mode 100644 src/xmlpatterns/api/qnetworkaccessdelegator.cpp create mode 100644 src/xmlpatterns/api/qnetworkaccessdelegator_p.h create mode 100644 src/xmlpatterns/api/qpullbridge.cpp create mode 100644 src/xmlpatterns/api/qpullbridge_p.h create mode 100644 src/xmlpatterns/api/qreferencecountedvalue_p.h create mode 100644 src/xmlpatterns/api/qresourcedelegator.cpp create mode 100644 src/xmlpatterns/api/qresourcedelegator_p.h create mode 100644 src/xmlpatterns/api/qsimplexmlnodemodel.cpp create mode 100644 src/xmlpatterns/api/qsimplexmlnodemodel.h create mode 100644 src/xmlpatterns/api/qsourcelocation.cpp create mode 100644 src/xmlpatterns/api/qsourcelocation.h create mode 100644 src/xmlpatterns/api/quriloader.cpp create mode 100644 src/xmlpatterns/api/quriloader_p.h create mode 100644 src/xmlpatterns/api/qvariableloader.cpp create mode 100644 src/xmlpatterns/api/qvariableloader_p.h create mode 100644 src/xmlpatterns/api/qxmlformatter.cpp create mode 100644 src/xmlpatterns/api/qxmlformatter.h create mode 100644 src/xmlpatterns/api/qxmlname.cpp create mode 100644 src/xmlpatterns/api/qxmlname.h create mode 100644 src/xmlpatterns/api/qxmlnamepool.cpp create mode 100644 src/xmlpatterns/api/qxmlnamepool.h create mode 100644 src/xmlpatterns/api/qxmlpatternistcli_p.h create mode 100644 src/xmlpatterns/api/qxmlquery.cpp create mode 100644 src/xmlpatterns/api/qxmlquery.h create mode 100644 src/xmlpatterns/api/qxmlquery_p.h create mode 100644 src/xmlpatterns/api/qxmlresultitems.cpp create mode 100644 src/xmlpatterns/api/qxmlresultitems.h create mode 100644 src/xmlpatterns/api/qxmlresultitems_p.h create mode 100644 src/xmlpatterns/api/qxmlschema.cpp create mode 100644 src/xmlpatterns/api/qxmlschema.h create mode 100644 src/xmlpatterns/api/qxmlschema_p.cpp create mode 100644 src/xmlpatterns/api/qxmlschema_p.h create mode 100644 src/xmlpatterns/api/qxmlschemavalidator.cpp create mode 100644 src/xmlpatterns/api/qxmlschemavalidator.h create mode 100644 src/xmlpatterns/api/qxmlschemavalidator_p.h create mode 100644 src/xmlpatterns/api/qxmlserializer.cpp create mode 100644 src/xmlpatterns/api/qxmlserializer.h create mode 100644 src/xmlpatterns/api/qxmlserializer_p.h create mode 100644 src/xmlpatterns/common.pri create mode 100644 src/xmlpatterns/data/data.pri create mode 100644 src/xmlpatterns/data/qabstractdatetime.cpp create mode 100644 src/xmlpatterns/data/qabstractdatetime_p.h create mode 100644 src/xmlpatterns/data/qabstractduration.cpp create mode 100644 src/xmlpatterns/data/qabstractduration_p.h create mode 100644 src/xmlpatterns/data/qabstractfloat.cpp create mode 100644 src/xmlpatterns/data/qabstractfloat_p.h create mode 100644 src/xmlpatterns/data/qabstractfloatcasters.cpp create mode 100644 src/xmlpatterns/data/qabstractfloatcasters_p.h create mode 100644 src/xmlpatterns/data/qabstractfloatmathematician.cpp create mode 100644 src/xmlpatterns/data/qabstractfloatmathematician_p.h create mode 100644 src/xmlpatterns/data/qanyuri.cpp create mode 100644 src/xmlpatterns/data/qanyuri_p.h create mode 100644 src/xmlpatterns/data/qatomiccaster.cpp create mode 100644 src/xmlpatterns/data/qatomiccaster_p.h create mode 100644 src/xmlpatterns/data/qatomiccasters.cpp create mode 100644 src/xmlpatterns/data/qatomiccasters_p.h create mode 100644 src/xmlpatterns/data/qatomiccomparator.cpp create mode 100644 src/xmlpatterns/data/qatomiccomparator_p.h create mode 100644 src/xmlpatterns/data/qatomiccomparators.cpp create mode 100644 src/xmlpatterns/data/qatomiccomparators_p.h create mode 100644 src/xmlpatterns/data/qatomicmathematician.cpp create mode 100644 src/xmlpatterns/data/qatomicmathematician_p.h create mode 100644 src/xmlpatterns/data/qatomicmathematicians.cpp create mode 100644 src/xmlpatterns/data/qatomicmathematicians_p.h create mode 100644 src/xmlpatterns/data/qatomicstring.cpp create mode 100644 src/xmlpatterns/data/qatomicstring_p.h create mode 100644 src/xmlpatterns/data/qatomicvalue.cpp create mode 100644 src/xmlpatterns/data/qbase64binary.cpp create mode 100644 src/xmlpatterns/data/qbase64binary_p.h create mode 100644 src/xmlpatterns/data/qboolean.cpp create mode 100644 src/xmlpatterns/data/qboolean_p.h create mode 100644 src/xmlpatterns/data/qcommonvalues.cpp create mode 100644 src/xmlpatterns/data/qcommonvalues_p.h create mode 100644 src/xmlpatterns/data/qcomparisonfactory.cpp create mode 100644 src/xmlpatterns/data/qcomparisonfactory_p.h create mode 100644 src/xmlpatterns/data/qdate.cpp create mode 100644 src/xmlpatterns/data/qdate_p.h create mode 100644 src/xmlpatterns/data/qdaytimeduration.cpp create mode 100644 src/xmlpatterns/data/qdaytimeduration_p.h create mode 100644 src/xmlpatterns/data/qdecimal.cpp create mode 100644 src/xmlpatterns/data/qdecimal_p.h create mode 100644 src/xmlpatterns/data/qderivedinteger_p.h create mode 100644 src/xmlpatterns/data/qderivedstring_p.h create mode 100644 src/xmlpatterns/data/qduration.cpp create mode 100644 src/xmlpatterns/data/qduration_p.h create mode 100644 src/xmlpatterns/data/qgday.cpp create mode 100644 src/xmlpatterns/data/qgday_p.h create mode 100644 src/xmlpatterns/data/qgmonth.cpp create mode 100644 src/xmlpatterns/data/qgmonth_p.h create mode 100644 src/xmlpatterns/data/qgmonthday.cpp create mode 100644 src/xmlpatterns/data/qgmonthday_p.h create mode 100644 src/xmlpatterns/data/qgyear.cpp create mode 100644 src/xmlpatterns/data/qgyear_p.h create mode 100644 src/xmlpatterns/data/qgyearmonth.cpp create mode 100644 src/xmlpatterns/data/qgyearmonth_p.h create mode 100644 src/xmlpatterns/data/qhexbinary.cpp create mode 100644 src/xmlpatterns/data/qhexbinary_p.h create mode 100644 src/xmlpatterns/data/qinteger.cpp create mode 100644 src/xmlpatterns/data/qinteger_p.h create mode 100644 src/xmlpatterns/data/qitem.cpp create mode 100644 src/xmlpatterns/data/qitem_p.h create mode 100644 src/xmlpatterns/data/qnodebuilder.cpp create mode 100644 src/xmlpatterns/data/qnodebuilder_p.h create mode 100644 src/xmlpatterns/data/qnodemodel.cpp create mode 100644 src/xmlpatterns/data/qqnamevalue.cpp create mode 100644 src/xmlpatterns/data/qqnamevalue_p.h create mode 100644 src/xmlpatterns/data/qresourceloader.cpp create mode 100644 src/xmlpatterns/data/qresourceloader_p.h create mode 100644 src/xmlpatterns/data/qschemadatetime.cpp create mode 100644 src/xmlpatterns/data/qschemadatetime_p.h create mode 100644 src/xmlpatterns/data/qschemanumeric.cpp create mode 100644 src/xmlpatterns/data/qschemanumeric_p.h create mode 100644 src/xmlpatterns/data/qschematime.cpp create mode 100644 src/xmlpatterns/data/qschematime_p.h create mode 100644 src/xmlpatterns/data/qsequencereceiver.cpp create mode 100644 src/xmlpatterns/data/qsequencereceiver_p.h create mode 100644 src/xmlpatterns/data/qsorttuple.cpp create mode 100644 src/xmlpatterns/data/qsorttuple_p.h create mode 100644 src/xmlpatterns/data/quntypedatomic.cpp create mode 100644 src/xmlpatterns/data/quntypedatomic_p.h create mode 100644 src/xmlpatterns/data/qvalidationerror.cpp create mode 100644 src/xmlpatterns/data/qvalidationerror_p.h create mode 100644 src/xmlpatterns/data/qvaluefactory.cpp create mode 100644 src/xmlpatterns/data/qvaluefactory_p.h create mode 100644 src/xmlpatterns/data/qyearmonthduration.cpp create mode 100644 src/xmlpatterns/data/qyearmonthduration_p.h create mode 100644 src/xmlpatterns/documentationGroups.dox create mode 100755 src/xmlpatterns/environment/createReportContext.sh create mode 100644 src/xmlpatterns/environment/createReportContext.xsl create mode 100644 src/xmlpatterns/environment/environment.pri create mode 100644 src/xmlpatterns/environment/qcurrentitemcontext.cpp create mode 100644 src/xmlpatterns/environment/qcurrentitemcontext_p.h create mode 100644 src/xmlpatterns/environment/qdelegatingdynamiccontext.cpp create mode 100644 src/xmlpatterns/environment/qdelegatingdynamiccontext_p.h create mode 100644 src/xmlpatterns/environment/qdelegatingstaticcontext.cpp create mode 100644 src/xmlpatterns/environment/qdelegatingstaticcontext_p.h create mode 100644 src/xmlpatterns/environment/qdynamiccontext.cpp create mode 100644 src/xmlpatterns/environment/qdynamiccontext_p.h create mode 100644 src/xmlpatterns/environment/qfocus.cpp create mode 100644 src/xmlpatterns/environment/qfocus_p.h create mode 100644 src/xmlpatterns/environment/qgenericdynamiccontext.cpp create mode 100644 src/xmlpatterns/environment/qgenericdynamiccontext_p.h create mode 100644 src/xmlpatterns/environment/qgenericstaticcontext.cpp create mode 100644 src/xmlpatterns/environment/qgenericstaticcontext_p.h create mode 100644 src/xmlpatterns/environment/qreceiverdynamiccontext.cpp create mode 100644 src/xmlpatterns/environment/qreceiverdynamiccontext_p.h create mode 100644 src/xmlpatterns/environment/qreportcontext.cpp create mode 100644 src/xmlpatterns/environment/qreportcontext_p.h create mode 100644 src/xmlpatterns/environment/qstackcontextbase.cpp create mode 100644 src/xmlpatterns/environment/qstackcontextbase_p.h create mode 100644 src/xmlpatterns/environment/qstaticbaseuricontext.cpp create mode 100644 src/xmlpatterns/environment/qstaticbaseuricontext_p.h create mode 100644 src/xmlpatterns/environment/qstaticcompatibilitycontext.cpp create mode 100644 src/xmlpatterns/environment/qstaticcompatibilitycontext_p.h create mode 100644 src/xmlpatterns/environment/qstaticcontext.cpp create mode 100644 src/xmlpatterns/environment/qstaticcontext_p.h create mode 100644 src/xmlpatterns/environment/qstaticcurrentcontext.cpp create mode 100644 src/xmlpatterns/environment/qstaticcurrentcontext_p.h create mode 100644 src/xmlpatterns/environment/qstaticfocuscontext.cpp create mode 100644 src/xmlpatterns/environment/qstaticfocuscontext_p.h create mode 100644 src/xmlpatterns/environment/qstaticnamespacecontext.cpp create mode 100644 src/xmlpatterns/environment/qstaticnamespacecontext_p.h create mode 100644 src/xmlpatterns/expr/expr.pri create mode 100644 src/xmlpatterns/expr/qandexpression.cpp create mode 100644 src/xmlpatterns/expr/qandexpression_p.h create mode 100644 src/xmlpatterns/expr/qapplytemplate.cpp create mode 100644 src/xmlpatterns/expr/qapplytemplate_p.h create mode 100644 src/xmlpatterns/expr/qargumentreference.cpp create mode 100644 src/xmlpatterns/expr/qargumentreference_p.h create mode 100644 src/xmlpatterns/expr/qarithmeticexpression.cpp create mode 100644 src/xmlpatterns/expr/qarithmeticexpression_p.h create mode 100644 src/xmlpatterns/expr/qattributeconstructor.cpp create mode 100644 src/xmlpatterns/expr/qattributeconstructor_p.h create mode 100644 src/xmlpatterns/expr/qattributenamevalidator.cpp create mode 100644 src/xmlpatterns/expr/qattributenamevalidator_p.h create mode 100644 src/xmlpatterns/expr/qaxisstep.cpp create mode 100644 src/xmlpatterns/expr/qaxisstep_p.h create mode 100644 src/xmlpatterns/expr/qcachecells_p.h create mode 100644 src/xmlpatterns/expr/qcallsite.cpp create mode 100644 src/xmlpatterns/expr/qcallsite_p.h create mode 100644 src/xmlpatterns/expr/qcalltargetdescription.cpp create mode 100644 src/xmlpatterns/expr/qcalltargetdescription_p.h create mode 100644 src/xmlpatterns/expr/qcalltemplate.cpp create mode 100644 src/xmlpatterns/expr/qcalltemplate_p.h create mode 100644 src/xmlpatterns/expr/qcastableas.cpp create mode 100644 src/xmlpatterns/expr/qcastableas_p.h create mode 100644 src/xmlpatterns/expr/qcastas.cpp create mode 100644 src/xmlpatterns/expr/qcastas_p.h create mode 100644 src/xmlpatterns/expr/qcastingplatform.cpp create mode 100644 src/xmlpatterns/expr/qcastingplatform_p.h create mode 100644 src/xmlpatterns/expr/qcollationchecker.cpp create mode 100644 src/xmlpatterns/expr/qcollationchecker_p.h create mode 100644 src/xmlpatterns/expr/qcombinenodes.cpp create mode 100644 src/xmlpatterns/expr/qcombinenodes_p.h create mode 100644 src/xmlpatterns/expr/qcommentconstructor.cpp create mode 100644 src/xmlpatterns/expr/qcommentconstructor_p.h create mode 100644 src/xmlpatterns/expr/qcomparisonplatform.cpp create mode 100644 src/xmlpatterns/expr/qcomparisonplatform_p.h create mode 100644 src/xmlpatterns/expr/qcomputednamespaceconstructor.cpp create mode 100644 src/xmlpatterns/expr/qcomputednamespaceconstructor_p.h create mode 100644 src/xmlpatterns/expr/qcontextitem.cpp create mode 100644 src/xmlpatterns/expr/qcontextitem_p.h create mode 100644 src/xmlpatterns/expr/qcopyof.cpp create mode 100644 src/xmlpatterns/expr/qcopyof_p.h create mode 100644 src/xmlpatterns/expr/qcurrentitemstore.cpp create mode 100644 src/xmlpatterns/expr/qcurrentitemstore_p.h create mode 100644 src/xmlpatterns/expr/qdocumentconstructor.cpp create mode 100644 src/xmlpatterns/expr/qdocumentconstructor_p.h create mode 100644 src/xmlpatterns/expr/qdocumentcontentvalidator.cpp create mode 100644 src/xmlpatterns/expr/qdocumentcontentvalidator_p.h create mode 100644 src/xmlpatterns/expr/qdynamiccontextstore.cpp create mode 100644 src/xmlpatterns/expr/qdynamiccontextstore_p.h create mode 100644 src/xmlpatterns/expr/qelementconstructor.cpp create mode 100644 src/xmlpatterns/expr/qelementconstructor_p.h create mode 100644 src/xmlpatterns/expr/qemptycontainer.cpp create mode 100644 src/xmlpatterns/expr/qemptycontainer_p.h create mode 100644 src/xmlpatterns/expr/qemptysequence.cpp create mode 100644 src/xmlpatterns/expr/qemptysequence_p.h create mode 100644 src/xmlpatterns/expr/qevaluationcache.cpp create mode 100644 src/xmlpatterns/expr/qevaluationcache_p.h create mode 100644 src/xmlpatterns/expr/qexpression.cpp create mode 100644 src/xmlpatterns/expr/qexpression_p.h create mode 100644 src/xmlpatterns/expr/qexpressiondispatch_p.h create mode 100644 src/xmlpatterns/expr/qexpressionfactory.cpp create mode 100644 src/xmlpatterns/expr/qexpressionfactory_p.h create mode 100644 src/xmlpatterns/expr/qexpressionsequence.cpp create mode 100644 src/xmlpatterns/expr/qexpressionsequence_p.h create mode 100644 src/xmlpatterns/expr/qexpressionvariablereference.cpp create mode 100644 src/xmlpatterns/expr/qexpressionvariablereference_p.h create mode 100644 src/xmlpatterns/expr/qexternalvariableloader.cpp create mode 100644 src/xmlpatterns/expr/qexternalvariableloader_p.h create mode 100644 src/xmlpatterns/expr/qexternalvariablereference.cpp create mode 100644 src/xmlpatterns/expr/qexternalvariablereference_p.h create mode 100644 src/xmlpatterns/expr/qfirstitempredicate.cpp create mode 100644 src/xmlpatterns/expr/qfirstitempredicate_p.h create mode 100644 src/xmlpatterns/expr/qforclause.cpp create mode 100644 src/xmlpatterns/expr/qforclause_p.h create mode 100644 src/xmlpatterns/expr/qgeneralcomparison.cpp create mode 100644 src/xmlpatterns/expr/qgeneralcomparison_p.h create mode 100644 src/xmlpatterns/expr/qgenericpredicate.cpp create mode 100644 src/xmlpatterns/expr/qgenericpredicate_p.h create mode 100644 src/xmlpatterns/expr/qifthenclause.cpp create mode 100644 src/xmlpatterns/expr/qifthenclause_p.h create mode 100644 src/xmlpatterns/expr/qinstanceof.cpp create mode 100644 src/xmlpatterns/expr/qinstanceof_p.h create mode 100644 src/xmlpatterns/expr/qletclause.cpp create mode 100644 src/xmlpatterns/expr/qletclause_p.h create mode 100644 src/xmlpatterns/expr/qliteral.cpp create mode 100644 src/xmlpatterns/expr/qliteral_p.h create mode 100644 src/xmlpatterns/expr/qliteralsequence.cpp create mode 100644 src/xmlpatterns/expr/qliteralsequence_p.h create mode 100644 src/xmlpatterns/expr/qnamespaceconstructor.cpp create mode 100644 src/xmlpatterns/expr/qnamespaceconstructor_p.h create mode 100644 src/xmlpatterns/expr/qncnameconstructor.cpp create mode 100644 src/xmlpatterns/expr/qncnameconstructor_p.h create mode 100644 src/xmlpatterns/expr/qnodecomparison.cpp create mode 100644 src/xmlpatterns/expr/qnodecomparison_p.h create mode 100644 src/xmlpatterns/expr/qnodesort.cpp create mode 100644 src/xmlpatterns/expr/qnodesort_p.h create mode 100644 src/xmlpatterns/expr/qoperandsiterator_p.h create mode 100644 src/xmlpatterns/expr/qoptimizationpasses.cpp create mode 100644 src/xmlpatterns/expr/qoptimizationpasses_p.h create mode 100644 src/xmlpatterns/expr/qoptimizerblocks.cpp create mode 100644 src/xmlpatterns/expr/qoptimizerblocks_p.h create mode 100644 src/xmlpatterns/expr/qoptimizerframework.cpp create mode 100644 src/xmlpatterns/expr/qoptimizerframework_p.h create mode 100644 src/xmlpatterns/expr/qorderby.cpp create mode 100644 src/xmlpatterns/expr/qorderby_p.h create mode 100644 src/xmlpatterns/expr/qorexpression.cpp create mode 100644 src/xmlpatterns/expr/qorexpression_p.h create mode 100644 src/xmlpatterns/expr/qpaircontainer.cpp create mode 100644 src/xmlpatterns/expr/qpaircontainer_p.h create mode 100644 src/xmlpatterns/expr/qparentnodeaxis.cpp create mode 100644 src/xmlpatterns/expr/qparentnodeaxis_p.h create mode 100644 src/xmlpatterns/expr/qpath.cpp create mode 100644 src/xmlpatterns/expr/qpath_p.h create mode 100644 src/xmlpatterns/expr/qpositionalvariablereference.cpp create mode 100644 src/xmlpatterns/expr/qpositionalvariablereference_p.h create mode 100644 src/xmlpatterns/expr/qprocessinginstructionconstructor.cpp create mode 100644 src/xmlpatterns/expr/qprocessinginstructionconstructor_p.h create mode 100644 src/xmlpatterns/expr/qqnameconstructor.cpp create mode 100644 src/xmlpatterns/expr/qqnameconstructor_p.h create mode 100644 src/xmlpatterns/expr/qquantifiedexpression.cpp create mode 100644 src/xmlpatterns/expr/qquantifiedexpression_p.h create mode 100644 src/xmlpatterns/expr/qrangeexpression.cpp create mode 100644 src/xmlpatterns/expr/qrangeexpression_p.h create mode 100644 src/xmlpatterns/expr/qrangevariablereference.cpp create mode 100644 src/xmlpatterns/expr/qrangevariablereference_p.h create mode 100644 src/xmlpatterns/expr/qreturnorderby.cpp create mode 100644 src/xmlpatterns/expr/qreturnorderby_p.h create mode 100644 src/xmlpatterns/expr/qsimplecontentconstructor.cpp create mode 100644 src/xmlpatterns/expr/qsimplecontentconstructor_p.h create mode 100644 src/xmlpatterns/expr/qsinglecontainer.cpp create mode 100644 src/xmlpatterns/expr/qsinglecontainer_p.h create mode 100644 src/xmlpatterns/expr/qsourcelocationreflection.cpp create mode 100644 src/xmlpatterns/expr/qsourcelocationreflection_p.h create mode 100644 src/xmlpatterns/expr/qstaticbaseuristore.cpp create mode 100644 src/xmlpatterns/expr/qstaticbaseuristore_p.h create mode 100644 src/xmlpatterns/expr/qstaticcompatibilitystore.cpp create mode 100644 src/xmlpatterns/expr/qstaticcompatibilitystore_p.h create mode 100644 src/xmlpatterns/expr/qtemplate.cpp create mode 100644 src/xmlpatterns/expr/qtemplate_p.h create mode 100644 src/xmlpatterns/expr/qtemplateinvoker.cpp create mode 100644 src/xmlpatterns/expr/qtemplateinvoker_p.h create mode 100644 src/xmlpatterns/expr/qtemplatemode.cpp create mode 100644 src/xmlpatterns/expr/qtemplatemode_p.h create mode 100644 src/xmlpatterns/expr/qtemplateparameterreference.cpp create mode 100644 src/xmlpatterns/expr/qtemplateparameterreference_p.h create mode 100644 src/xmlpatterns/expr/qtemplatepattern_p.h create mode 100644 src/xmlpatterns/expr/qtextnodeconstructor.cpp create mode 100644 src/xmlpatterns/expr/qtextnodeconstructor_p.h create mode 100644 src/xmlpatterns/expr/qtreatas.cpp create mode 100644 src/xmlpatterns/expr/qtreatas_p.h create mode 100644 src/xmlpatterns/expr/qtriplecontainer.cpp create mode 100644 src/xmlpatterns/expr/qtriplecontainer_p.h create mode 100644 src/xmlpatterns/expr/qtruthpredicate.cpp create mode 100644 src/xmlpatterns/expr/qtruthpredicate_p.h create mode 100644 src/xmlpatterns/expr/qunaryexpression.cpp create mode 100644 src/xmlpatterns/expr/qunaryexpression_p.h create mode 100644 src/xmlpatterns/expr/qunlimitedcontainer.cpp create mode 100644 src/xmlpatterns/expr/qunlimitedcontainer_p.h create mode 100644 src/xmlpatterns/expr/qunresolvedvariablereference.cpp create mode 100644 src/xmlpatterns/expr/qunresolvedvariablereference_p.h create mode 100644 src/xmlpatterns/expr/quserfunction.cpp create mode 100644 src/xmlpatterns/expr/quserfunction_p.h create mode 100644 src/xmlpatterns/expr/quserfunctioncallsite.cpp create mode 100644 src/xmlpatterns/expr/quserfunctioncallsite_p.h create mode 100644 src/xmlpatterns/expr/qvalidate.cpp create mode 100644 src/xmlpatterns/expr/qvalidate_p.h create mode 100644 src/xmlpatterns/expr/qvaluecomparison.cpp create mode 100644 src/xmlpatterns/expr/qvaluecomparison_p.h create mode 100644 src/xmlpatterns/expr/qvariabledeclaration.cpp create mode 100644 src/xmlpatterns/expr/qvariabledeclaration_p.h create mode 100644 src/xmlpatterns/expr/qvariablereference.cpp create mode 100644 src/xmlpatterns/expr/qvariablereference_p.h create mode 100644 src/xmlpatterns/expr/qwithparam_p.h create mode 100644 src/xmlpatterns/expr/qxsltsimplecontentconstructor.cpp create mode 100644 src/xmlpatterns/expr/qxsltsimplecontentconstructor_p.h create mode 100644 src/xmlpatterns/functions/functions.pri create mode 100644 src/xmlpatterns/functions/qabstractfunctionfactory.cpp create mode 100644 src/xmlpatterns/functions/qabstractfunctionfactory_p.h create mode 100644 src/xmlpatterns/functions/qaccessorfns.cpp create mode 100644 src/xmlpatterns/functions/qaccessorfns_p.h create mode 100644 src/xmlpatterns/functions/qaggregatefns.cpp create mode 100644 src/xmlpatterns/functions/qaggregatefns_p.h create mode 100644 src/xmlpatterns/functions/qaggregator.cpp create mode 100644 src/xmlpatterns/functions/qaggregator_p.h create mode 100644 src/xmlpatterns/functions/qassemblestringfns.cpp create mode 100644 src/xmlpatterns/functions/qassemblestringfns_p.h create mode 100644 src/xmlpatterns/functions/qbooleanfns.cpp create mode 100644 src/xmlpatterns/functions/qbooleanfns_p.h create mode 100644 src/xmlpatterns/functions/qcomparescaseaware.cpp create mode 100644 src/xmlpatterns/functions/qcomparescaseaware_p.h create mode 100644 src/xmlpatterns/functions/qcomparestringfns.cpp create mode 100644 src/xmlpatterns/functions/qcomparestringfns_p.h create mode 100644 src/xmlpatterns/functions/qcomparingaggregator.cpp create mode 100644 src/xmlpatterns/functions/qcomparingaggregator_p.h create mode 100644 src/xmlpatterns/functions/qconstructorfunctionsfactory.cpp create mode 100644 src/xmlpatterns/functions/qconstructorfunctionsfactory_p.h create mode 100644 src/xmlpatterns/functions/qcontextfns.cpp create mode 100644 src/xmlpatterns/functions/qcontextfns_p.h create mode 100644 src/xmlpatterns/functions/qcontextnodechecker.cpp create mode 100644 src/xmlpatterns/functions/qcontextnodechecker_p.h create mode 100644 src/xmlpatterns/functions/qcurrentfn.cpp create mode 100644 src/xmlpatterns/functions/qcurrentfn_p.h create mode 100644 src/xmlpatterns/functions/qdatetimefn.cpp create mode 100644 src/xmlpatterns/functions/qdatetimefn_p.h create mode 100644 src/xmlpatterns/functions/qdatetimefns.cpp create mode 100644 src/xmlpatterns/functions/qdatetimefns_p.h create mode 100644 src/xmlpatterns/functions/qdeepequalfn.cpp create mode 100644 src/xmlpatterns/functions/qdeepequalfn_p.h create mode 100644 src/xmlpatterns/functions/qdocumentfn.cpp create mode 100644 src/xmlpatterns/functions/qdocumentfn_p.h create mode 100644 src/xmlpatterns/functions/qelementavailablefn.cpp create mode 100644 src/xmlpatterns/functions/qelementavailablefn_p.h create mode 100644 src/xmlpatterns/functions/qerrorfn.cpp create mode 100644 src/xmlpatterns/functions/qerrorfn_p.h create mode 100644 src/xmlpatterns/functions/qfunctionargument.cpp create mode 100644 src/xmlpatterns/functions/qfunctionargument_p.h create mode 100644 src/xmlpatterns/functions/qfunctionavailablefn.cpp create mode 100644 src/xmlpatterns/functions/qfunctionavailablefn_p.h create mode 100644 src/xmlpatterns/functions/qfunctioncall.cpp create mode 100644 src/xmlpatterns/functions/qfunctioncall_p.h create mode 100644 src/xmlpatterns/functions/qfunctionfactory.cpp create mode 100644 src/xmlpatterns/functions/qfunctionfactory_p.h create mode 100644 src/xmlpatterns/functions/qfunctionfactorycollection.cpp create mode 100644 src/xmlpatterns/functions/qfunctionfactorycollection_p.h create mode 100644 src/xmlpatterns/functions/qfunctionsignature.cpp create mode 100644 src/xmlpatterns/functions/qfunctionsignature_p.h create mode 100644 src/xmlpatterns/functions/qgenerateidfn.cpp create mode 100644 src/xmlpatterns/functions/qgenerateidfn_p.h create mode 100644 src/xmlpatterns/functions/qnodefns.cpp create mode 100644 src/xmlpatterns/functions/qnodefns_p.h create mode 100644 src/xmlpatterns/functions/qnumericfns.cpp create mode 100644 src/xmlpatterns/functions/qnumericfns_p.h create mode 100644 src/xmlpatterns/functions/qpatternmatchingfns.cpp create mode 100644 src/xmlpatterns/functions/qpatternmatchingfns_p.h create mode 100644 src/xmlpatterns/functions/qpatternplatform.cpp create mode 100644 src/xmlpatterns/functions/qpatternplatform_p.h create mode 100644 src/xmlpatterns/functions/qqnamefns.cpp create mode 100644 src/xmlpatterns/functions/qqnamefns_p.h create mode 100644 src/xmlpatterns/functions/qresolveurifn.cpp create mode 100644 src/xmlpatterns/functions/qresolveurifn_p.h create mode 100644 src/xmlpatterns/functions/qsequencefns.cpp create mode 100644 src/xmlpatterns/functions/qsequencefns_p.h create mode 100644 src/xmlpatterns/functions/qsequencegeneratingfns.cpp create mode 100644 src/xmlpatterns/functions/qsequencegeneratingfns_p.h create mode 100644 src/xmlpatterns/functions/qstaticbaseuricontainer_p.h create mode 100644 src/xmlpatterns/functions/qstaticnamespacescontainer.cpp create mode 100644 src/xmlpatterns/functions/qstaticnamespacescontainer_p.h create mode 100644 src/xmlpatterns/functions/qstringvaluefns.cpp create mode 100644 src/xmlpatterns/functions/qstringvaluefns_p.h create mode 100644 src/xmlpatterns/functions/qsubstringfns.cpp create mode 100644 src/xmlpatterns/functions/qsubstringfns_p.h create mode 100644 src/xmlpatterns/functions/qsystempropertyfn.cpp create mode 100644 src/xmlpatterns/functions/qsystempropertyfn_p.h create mode 100644 src/xmlpatterns/functions/qtimezonefns.cpp create mode 100644 src/xmlpatterns/functions/qtimezonefns_p.h create mode 100644 src/xmlpatterns/functions/qtracefn.cpp create mode 100644 src/xmlpatterns/functions/qtracefn_p.h create mode 100644 src/xmlpatterns/functions/qtypeavailablefn.cpp create mode 100644 src/xmlpatterns/functions/qtypeavailablefn_p.h create mode 100644 src/xmlpatterns/functions/qunparsedentitypublicidfn.cpp create mode 100644 src/xmlpatterns/functions/qunparsedentitypublicidfn_p.h create mode 100644 src/xmlpatterns/functions/qunparsedentityurifn.cpp create mode 100644 src/xmlpatterns/functions/qunparsedentityurifn_p.h create mode 100644 src/xmlpatterns/functions/qunparsedtextavailablefn.cpp create mode 100644 src/xmlpatterns/functions/qunparsedtextavailablefn_p.h create mode 100644 src/xmlpatterns/functions/qunparsedtextfn.cpp create mode 100644 src/xmlpatterns/functions/qunparsedtextfn_p.h create mode 100644 src/xmlpatterns/functions/qxpath10corefunctions.cpp create mode 100644 src/xmlpatterns/functions/qxpath10corefunctions_p.h create mode 100644 src/xmlpatterns/functions/qxpath20corefunctions.cpp create mode 100644 src/xmlpatterns/functions/qxpath20corefunctions_p.h create mode 100644 src/xmlpatterns/functions/qxslt20corefunctions.cpp create mode 100644 src/xmlpatterns/functions/qxslt20corefunctions_p.h create mode 100644 src/xmlpatterns/iterators/iterators.pri create mode 100644 src/xmlpatterns/iterators/qcachingiterator.cpp create mode 100644 src/xmlpatterns/iterators/qcachingiterator_p.h create mode 100644 src/xmlpatterns/iterators/qdeduplicateiterator.cpp create mode 100644 src/xmlpatterns/iterators/qdeduplicateiterator_p.h create mode 100644 src/xmlpatterns/iterators/qdistinctiterator.cpp create mode 100644 src/xmlpatterns/iterators/qdistinctiterator_p.h create mode 100644 src/xmlpatterns/iterators/qemptyiterator_p.h create mode 100644 src/xmlpatterns/iterators/qexceptiterator.cpp create mode 100644 src/xmlpatterns/iterators/qexceptiterator_p.h create mode 100644 src/xmlpatterns/iterators/qindexofiterator.cpp create mode 100644 src/xmlpatterns/iterators/qindexofiterator_p.h create mode 100644 src/xmlpatterns/iterators/qinsertioniterator.cpp create mode 100644 src/xmlpatterns/iterators/qinsertioniterator_p.h create mode 100644 src/xmlpatterns/iterators/qintersectiterator.cpp create mode 100644 src/xmlpatterns/iterators/qintersectiterator_p.h create mode 100644 src/xmlpatterns/iterators/qitemmappingiterator_p.h create mode 100644 src/xmlpatterns/iterators/qrangeiterator.cpp create mode 100644 src/xmlpatterns/iterators/qrangeiterator_p.h create mode 100644 src/xmlpatterns/iterators/qremovaliterator.cpp create mode 100644 src/xmlpatterns/iterators/qremovaliterator_p.h create mode 100644 src/xmlpatterns/iterators/qsequencemappingiterator_p.h create mode 100644 src/xmlpatterns/iterators/qsingletoniterator_p.h create mode 100644 src/xmlpatterns/iterators/qsubsequenceiterator.cpp create mode 100644 src/xmlpatterns/iterators/qsubsequenceiterator_p.h create mode 100644 src/xmlpatterns/iterators/qtocodepointsiterator.cpp create mode 100644 src/xmlpatterns/iterators/qtocodepointsiterator_p.h create mode 100644 src/xmlpatterns/iterators/qunioniterator.cpp create mode 100644 src/xmlpatterns/iterators/qunioniterator_p.h create mode 100644 src/xmlpatterns/janitors/janitors.pri create mode 100644 src/xmlpatterns/janitors/qargumentconverter.cpp create mode 100644 src/xmlpatterns/janitors/qargumentconverter_p.h create mode 100644 src/xmlpatterns/janitors/qatomizer.cpp create mode 100644 src/xmlpatterns/janitors/qatomizer_p.h create mode 100644 src/xmlpatterns/janitors/qcardinalityverifier.cpp create mode 100644 src/xmlpatterns/janitors/qcardinalityverifier_p.h create mode 100644 src/xmlpatterns/janitors/qebvextractor.cpp create mode 100644 src/xmlpatterns/janitors/qebvextractor_p.h create mode 100644 src/xmlpatterns/janitors/qitemverifier.cpp create mode 100644 src/xmlpatterns/janitors/qitemverifier_p.h create mode 100644 src/xmlpatterns/janitors/quntypedatomicconverter.cpp create mode 100644 src/xmlpatterns/janitors/quntypedatomicconverter_p.h create mode 100644 src/xmlpatterns/parser/.gitattributes create mode 100644 src/xmlpatterns/parser/.gitignore create mode 100644 src/xmlpatterns/parser/TokenLookup.gperf create mode 100755 src/xmlpatterns/parser/createParser.sh create mode 100755 src/xmlpatterns/parser/createTokenLookup.sh create mode 100755 src/xmlpatterns/parser/createXSLTTokenLookup.sh create mode 100644 src/xmlpatterns/parser/parser.pri create mode 100644 src/xmlpatterns/parser/qmaintainingreader.cpp create mode 100644 src/xmlpatterns/parser/qmaintainingreader_p.h create mode 100644 src/xmlpatterns/parser/qparsercontext.cpp create mode 100644 src/xmlpatterns/parser/qparsercontext_p.h create mode 100644 src/xmlpatterns/parser/qquerytransformparser.cpp create mode 100644 src/xmlpatterns/parser/qquerytransformparser_p.h create mode 100644 src/xmlpatterns/parser/qtokenizer_p.h create mode 100644 src/xmlpatterns/parser/qtokenlookup.cpp create mode 100644 src/xmlpatterns/parser/qtokenrevealer.cpp create mode 100644 src/xmlpatterns/parser/qtokenrevealer_p.h create mode 100644 src/xmlpatterns/parser/qtokensource.cpp create mode 100644 src/xmlpatterns/parser/qtokensource_p.h create mode 100644 src/xmlpatterns/parser/querytransformparser.ypp create mode 100644 src/xmlpatterns/parser/qxquerytokenizer.cpp create mode 100644 src/xmlpatterns/parser/qxquerytokenizer_p.h create mode 100644 src/xmlpatterns/parser/qxslttokenizer.cpp create mode 100644 src/xmlpatterns/parser/qxslttokenizer_p.h create mode 100644 src/xmlpatterns/parser/qxslttokenlookup.cpp create mode 100644 src/xmlpatterns/parser/qxslttokenlookup.xml create mode 100644 src/xmlpatterns/parser/qxslttokenlookup_p.h create mode 100644 src/xmlpatterns/parser/trolltechHeader.txt create mode 100644 src/xmlpatterns/parser/winCEWorkaround.sed create mode 100644 src/xmlpatterns/projection/projection.pri create mode 100644 src/xmlpatterns/projection/qdocumentprojector.cpp create mode 100644 src/xmlpatterns/projection/qdocumentprojector_p.h create mode 100644 src/xmlpatterns/projection/qprojectedexpression_p.h create mode 100644 src/xmlpatterns/qtokenautomaton/README create mode 100644 src/xmlpatterns/qtokenautomaton/exampleFile.xml create mode 100644 src/xmlpatterns/qtokenautomaton/qautomaton2cpp.xsl create mode 100644 src/xmlpatterns/qtokenautomaton/qtokenautomaton.xsd create mode 100644 src/xmlpatterns/query.pri create mode 100644 src/xmlpatterns/schema/.gitignore create mode 100644 src/xmlpatterns/schema/builtinschemas.qrc create mode 100644 src/xmlpatterns/schema/doc/All_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Alternative_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Annotation_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/AnyAttribute_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Any_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Assert_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Choice_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/ComplexContentExtension_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/ComplexContentRestriction_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/ComplexContent_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/DefaultOpenContent_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/EnumerationFacet_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Field_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/FractionDigitsFacet_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/GlobalAttribute_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/GlobalComplexType_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/GlobalElement_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/GlobalSimpleType_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Import_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Include_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/KeyRef_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Key_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/LengthFacet_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/List_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/LocalAll_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/LocalAttribute_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/LocalChoice_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/LocalComplexType_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/LocalElement_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/LocalSequence_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/LocalSimpleType_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/MaxExclusiveFacet_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/MaxInclusiveFacet_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/MaxLengthFacet_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/MinExclusiveFacet_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/MinInclusiveFacet_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/MinLengthFacet_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/NamedAttributeGroup_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/NamedGroup_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Notation_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Override_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/PatternFacet_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Redefine_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/ReferredAttributeGroup_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/ReferredGroup_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Schema_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Selector_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Sequence_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/SimpleContentExtension_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/SimpleContentRestriction_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/SimpleContent_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/SimpleRestriction_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/TotalDigitsFacet_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Union_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/Unique_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/WhiteSpaceFacet_diagram.dot create mode 100644 src/xmlpatterns/schema/doc/legend.dot create mode 100644 src/xmlpatterns/schema/qnamespacesupport.cpp create mode 100644 src/xmlpatterns/schema/qnamespacesupport_p.h create mode 100644 src/xmlpatterns/schema/qxsdalternative.cpp create mode 100644 src/xmlpatterns/schema/qxsdalternative_p.h create mode 100644 src/xmlpatterns/schema/qxsdannotated.cpp create mode 100644 src/xmlpatterns/schema/qxsdannotated_p.h create mode 100644 src/xmlpatterns/schema/qxsdannotation.cpp create mode 100644 src/xmlpatterns/schema/qxsdannotation_p.h create mode 100644 src/xmlpatterns/schema/qxsdapplicationinformation.cpp create mode 100644 src/xmlpatterns/schema/qxsdapplicationinformation_p.h create mode 100644 src/xmlpatterns/schema/qxsdassertion.cpp create mode 100644 src/xmlpatterns/schema/qxsdassertion_p.h create mode 100644 src/xmlpatterns/schema/qxsdattribute.cpp create mode 100644 src/xmlpatterns/schema/qxsdattribute_p.h create mode 100644 src/xmlpatterns/schema/qxsdattributegroup.cpp create mode 100644 src/xmlpatterns/schema/qxsdattributegroup_p.h create mode 100644 src/xmlpatterns/schema/qxsdattributereference.cpp create mode 100644 src/xmlpatterns/schema/qxsdattributereference_p.h create mode 100644 src/xmlpatterns/schema/qxsdattributeterm.cpp create mode 100644 src/xmlpatterns/schema/qxsdattributeterm_p.h create mode 100644 src/xmlpatterns/schema/qxsdattributeuse.cpp create mode 100644 src/xmlpatterns/schema/qxsdattributeuse_p.h create mode 100644 src/xmlpatterns/schema/qxsdcomplextype.cpp create mode 100644 src/xmlpatterns/schema/qxsdcomplextype_p.h create mode 100644 src/xmlpatterns/schema/qxsddocumentation.cpp create mode 100644 src/xmlpatterns/schema/qxsddocumentation_p.h create mode 100644 src/xmlpatterns/schema/qxsdelement.cpp create mode 100644 src/xmlpatterns/schema/qxsdelement_p.h create mode 100644 src/xmlpatterns/schema/qxsdfacet.cpp create mode 100644 src/xmlpatterns/schema/qxsdfacet_p.h create mode 100644 src/xmlpatterns/schema/qxsdidcache.cpp create mode 100644 src/xmlpatterns/schema/qxsdidcache_p.h create mode 100644 src/xmlpatterns/schema/qxsdidchelper.cpp create mode 100644 src/xmlpatterns/schema/qxsdidchelper_p.h create mode 100644 src/xmlpatterns/schema/qxsdidentityconstraint.cpp create mode 100644 src/xmlpatterns/schema/qxsdidentityconstraint_p.h create mode 100644 src/xmlpatterns/schema/qxsdinstancereader.cpp create mode 100644 src/xmlpatterns/schema/qxsdinstancereader_p.h create mode 100644 src/xmlpatterns/schema/qxsdmodelgroup.cpp create mode 100644 src/xmlpatterns/schema/qxsdmodelgroup_p.h create mode 100644 src/xmlpatterns/schema/qxsdnotation.cpp create mode 100644 src/xmlpatterns/schema/qxsdnotation_p.h create mode 100644 src/xmlpatterns/schema/qxsdparticle.cpp create mode 100644 src/xmlpatterns/schema/qxsdparticle_p.h create mode 100644 src/xmlpatterns/schema/qxsdparticlechecker.cpp create mode 100644 src/xmlpatterns/schema/qxsdparticlechecker_p.h create mode 100644 src/xmlpatterns/schema/qxsdreference.cpp create mode 100644 src/xmlpatterns/schema/qxsdreference_p.h create mode 100644 src/xmlpatterns/schema/qxsdschema.cpp create mode 100644 src/xmlpatterns/schema/qxsdschema_p.h create mode 100644 src/xmlpatterns/schema/qxsdschemachecker.cpp create mode 100644 src/xmlpatterns/schema/qxsdschemachecker_helper.cpp create mode 100644 src/xmlpatterns/schema/qxsdschemachecker_p.h create mode 100644 src/xmlpatterns/schema/qxsdschemachecker_setup.cpp create mode 100644 src/xmlpatterns/schema/qxsdschemacontext.cpp create mode 100644 src/xmlpatterns/schema/qxsdschemacontext_p.h create mode 100644 src/xmlpatterns/schema/qxsdschemadebugger.cpp create mode 100644 src/xmlpatterns/schema/qxsdschemadebugger_p.h create mode 100644 src/xmlpatterns/schema/qxsdschemahelper.cpp create mode 100644 src/xmlpatterns/schema/qxsdschemahelper_p.h create mode 100644 src/xmlpatterns/schema/qxsdschemamerger.cpp create mode 100644 src/xmlpatterns/schema/qxsdschemamerger_p.h create mode 100644 src/xmlpatterns/schema/qxsdschemaparser.cpp create mode 100644 src/xmlpatterns/schema/qxsdschemaparser_p.h create mode 100644 src/xmlpatterns/schema/qxsdschemaparser_setup.cpp create mode 100644 src/xmlpatterns/schema/qxsdschemaparsercontext.cpp create mode 100644 src/xmlpatterns/schema/qxsdschemaparsercontext_p.h create mode 100644 src/xmlpatterns/schema/qxsdschemaresolver.cpp create mode 100644 src/xmlpatterns/schema/qxsdschemaresolver_p.h create mode 100644 src/xmlpatterns/schema/qxsdschematoken.cpp create mode 100644 src/xmlpatterns/schema/qxsdschematoken_p.h create mode 100644 src/xmlpatterns/schema/qxsdschematypesfactory.cpp create mode 100644 src/xmlpatterns/schema/qxsdschematypesfactory_p.h create mode 100644 src/xmlpatterns/schema/qxsdsimpletype.cpp create mode 100644 src/xmlpatterns/schema/qxsdsimpletype_p.h create mode 100644 src/xmlpatterns/schema/qxsdstatemachine.cpp create mode 100644 src/xmlpatterns/schema/qxsdstatemachine_p.h create mode 100644 src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp create mode 100644 src/xmlpatterns/schema/qxsdstatemachinebuilder_p.h create mode 100644 src/xmlpatterns/schema/qxsdterm.cpp create mode 100644 src/xmlpatterns/schema/qxsdterm_p.h create mode 100644 src/xmlpatterns/schema/qxsdtypechecker.cpp create mode 100644 src/xmlpatterns/schema/qxsdtypechecker_p.h create mode 100644 src/xmlpatterns/schema/qxsduserschematype.cpp create mode 100644 src/xmlpatterns/schema/qxsduserschematype_p.h create mode 100644 src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel.cpp create mode 100644 src/xmlpatterns/schema/qxsdvalidatedxmlnodemodel_p.h create mode 100644 src/xmlpatterns/schema/qxsdvalidatinginstancereader.cpp create mode 100644 src/xmlpatterns/schema/qxsdvalidatinginstancereader_p.h create mode 100644 src/xmlpatterns/schema/qxsdwildcard.cpp create mode 100644 src/xmlpatterns/schema/qxsdwildcard_p.h create mode 100644 src/xmlpatterns/schema/qxsdxpathexpression.cpp create mode 100644 src/xmlpatterns/schema/qxsdxpathexpression_p.h create mode 100644 src/xmlpatterns/schema/schema.pri create mode 100644 src/xmlpatterns/schema/schemas/xml.xsd create mode 100644 src/xmlpatterns/schema/schemas/xml.xsd-LICENSE create mode 100644 src/xmlpatterns/schema/tokens.xml create mode 100644 src/xmlpatterns/type/qabstractnodetest.cpp create mode 100644 src/xmlpatterns/type/qabstractnodetest_p.h create mode 100644 src/xmlpatterns/type/qanyitemtype.cpp create mode 100644 src/xmlpatterns/type/qanyitemtype_p.h create mode 100644 src/xmlpatterns/type/qanynodetype.cpp create mode 100644 src/xmlpatterns/type/qanynodetype_p.h create mode 100644 src/xmlpatterns/type/qanysimpletype.cpp create mode 100644 src/xmlpatterns/type/qanysimpletype_p.h create mode 100644 src/xmlpatterns/type/qanytype.cpp create mode 100644 src/xmlpatterns/type/qanytype_p.h create mode 100644 src/xmlpatterns/type/qatomiccasterlocator.cpp create mode 100644 src/xmlpatterns/type/qatomiccasterlocator_p.h create mode 100644 src/xmlpatterns/type/qatomiccasterlocators.cpp create mode 100644 src/xmlpatterns/type/qatomiccasterlocators_p.h create mode 100644 src/xmlpatterns/type/qatomiccomparatorlocator.cpp create mode 100644 src/xmlpatterns/type/qatomiccomparatorlocator_p.h create mode 100644 src/xmlpatterns/type/qatomiccomparatorlocators.cpp create mode 100644 src/xmlpatterns/type/qatomiccomparatorlocators_p.h create mode 100644 src/xmlpatterns/type/qatomicmathematicianlocator.cpp create mode 100644 src/xmlpatterns/type/qatomicmathematicianlocator_p.h create mode 100644 src/xmlpatterns/type/qatomicmathematicianlocators.cpp create mode 100644 src/xmlpatterns/type/qatomicmathematicianlocators_p.h create mode 100644 src/xmlpatterns/type/qatomictype.cpp create mode 100644 src/xmlpatterns/type/qatomictype_p.h create mode 100644 src/xmlpatterns/type/qatomictypedispatch_p.h create mode 100644 src/xmlpatterns/type/qbasictypesfactory.cpp create mode 100644 src/xmlpatterns/type/qbasictypesfactory_p.h create mode 100644 src/xmlpatterns/type/qbuiltinatomictype.cpp create mode 100644 src/xmlpatterns/type/qbuiltinatomictype_p.h create mode 100644 src/xmlpatterns/type/qbuiltinatomictypes.cpp create mode 100644 src/xmlpatterns/type/qbuiltinatomictypes_p.h create mode 100644 src/xmlpatterns/type/qbuiltinnodetype.cpp create mode 100644 src/xmlpatterns/type/qbuiltinnodetype_p.h create mode 100644 src/xmlpatterns/type/qbuiltintypes.cpp create mode 100644 src/xmlpatterns/type/qbuiltintypes_p.h create mode 100644 src/xmlpatterns/type/qcardinality.cpp create mode 100644 src/xmlpatterns/type/qcardinality_p.h create mode 100644 src/xmlpatterns/type/qcommonsequencetypes.cpp create mode 100644 src/xmlpatterns/type/qcommonsequencetypes_p.h create mode 100644 src/xmlpatterns/type/qebvtype.cpp create mode 100644 src/xmlpatterns/type/qebvtype_p.h create mode 100644 src/xmlpatterns/type/qemptysequencetype.cpp create mode 100644 src/xmlpatterns/type/qemptysequencetype_p.h create mode 100644 src/xmlpatterns/type/qgenericsequencetype.cpp create mode 100644 src/xmlpatterns/type/qgenericsequencetype_p.h create mode 100644 src/xmlpatterns/type/qitemtype.cpp create mode 100644 src/xmlpatterns/type/qitemtype_p.h create mode 100644 src/xmlpatterns/type/qlocalnametest.cpp create mode 100644 src/xmlpatterns/type/qlocalnametest_p.h create mode 100644 src/xmlpatterns/type/qmultiitemtype.cpp create mode 100644 src/xmlpatterns/type/qmultiitemtype_p.h create mode 100644 src/xmlpatterns/type/qnamedschemacomponent.cpp create mode 100644 src/xmlpatterns/type/qnamedschemacomponent_p.h create mode 100644 src/xmlpatterns/type/qnamespacenametest.cpp create mode 100644 src/xmlpatterns/type/qnamespacenametest_p.h create mode 100644 src/xmlpatterns/type/qnonetype.cpp create mode 100644 src/xmlpatterns/type/qnonetype_p.h create mode 100644 src/xmlpatterns/type/qnumerictype.cpp create mode 100644 src/xmlpatterns/type/qnumerictype_p.h create mode 100644 src/xmlpatterns/type/qprimitives_p.h create mode 100644 src/xmlpatterns/type/qqnametest.cpp create mode 100644 src/xmlpatterns/type/qqnametest_p.h create mode 100644 src/xmlpatterns/type/qschemacomponent.cpp create mode 100644 src/xmlpatterns/type/qschemacomponent_p.h create mode 100644 src/xmlpatterns/type/qschematype.cpp create mode 100644 src/xmlpatterns/type/qschematype_p.h create mode 100644 src/xmlpatterns/type/qschematypefactory.cpp create mode 100644 src/xmlpatterns/type/qschematypefactory_p.h create mode 100644 src/xmlpatterns/type/qsequencetype.cpp create mode 100644 src/xmlpatterns/type/qsequencetype_p.h create mode 100644 src/xmlpatterns/type/qtypechecker.cpp create mode 100644 src/xmlpatterns/type/qtypechecker_p.h create mode 100644 src/xmlpatterns/type/quntyped.cpp create mode 100644 src/xmlpatterns/type/quntyped_p.h create mode 100644 src/xmlpatterns/type/qxsltnodetest.cpp create mode 100644 src/xmlpatterns/type/qxsltnodetest_p.h create mode 100644 src/xmlpatterns/type/type.pri create mode 100644 src/xmlpatterns/utils/qautoptr.cpp create mode 100644 src/xmlpatterns/utils/qautoptr_p.h create mode 100644 src/xmlpatterns/utils/qcommonnamespaces_p.h create mode 100644 src/xmlpatterns/utils/qcppcastinghelper_p.h create mode 100644 src/xmlpatterns/utils/qdebug_p.h create mode 100644 src/xmlpatterns/utils/qdelegatingnamespaceresolver.cpp create mode 100644 src/xmlpatterns/utils/qdelegatingnamespaceresolver_p.h create mode 100644 src/xmlpatterns/utils/qgenericnamespaceresolver.cpp create mode 100644 src/xmlpatterns/utils/qgenericnamespaceresolver_p.h create mode 100644 src/xmlpatterns/utils/qnamepool.cpp create mode 100644 src/xmlpatterns/utils/qnamepool_p.h create mode 100644 src/xmlpatterns/utils/qnamespacebinding_p.h create mode 100644 src/xmlpatterns/utils/qnamespaceresolver.cpp create mode 100644 src/xmlpatterns/utils/qnamespaceresolver_p.h create mode 100644 src/xmlpatterns/utils/qnodenamespaceresolver.cpp create mode 100644 src/xmlpatterns/utils/qnodenamespaceresolver_p.h create mode 100644 src/xmlpatterns/utils/qoutputvalidator.cpp create mode 100644 src/xmlpatterns/utils/qoutputvalidator_p.h create mode 100644 src/xmlpatterns/utils/qpatternistlocale.cpp create mode 100644 src/xmlpatterns/utils/qpatternistlocale_p.h create mode 100644 src/xmlpatterns/utils/qxpathhelper.cpp create mode 100644 src/xmlpatterns/utils/qxpathhelper_p.h create mode 100644 src/xmlpatterns/utils/utils.pri create mode 100644 src/xmlpatterns/xmlpatterns.pro (limited to 'src/xmlpatterns') diff --git a/src/xmlpatterns/.gitignore b/src/xmlpatterns/.gitignore new file mode 100644 index 0000000..eb12d93 --- /dev/null +++ b/src/xmlpatterns/.gitignore @@ -0,0 +1 @@ +internal-docs/ diff --git a/src/xmlpatterns/Doxyfile b/src/xmlpatterns/Doxyfile new file mode 100644 index 0000000..83f7062 --- /dev/null +++ b/src/xmlpatterns/Doxyfile @@ -0,0 +1,1196 @@ +# Doxyfile 1.4.5 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = QtXmlPatterns + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = internal-docs + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to +# include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = yes + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = YES + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = YES + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = YES + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is YES. + +SHOW_DIRECTORIES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +# Having it set to not, output a lot of status messages to stdout, we still +# get the warning into the log file +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = NO + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = internal-docs/doxygen.log + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = . ../../tests/auto/xmlpatternsxqts/ ../../tests/auto/xmlpatternsview + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: + +FILE_PATTERNS = *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.dox *.gperf + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +# The Qt API uses qdoc and Doxygen doesn't like its tags, so exclude the q* files. +EXCLUDE_PATTERNS = *.moc *.moc.cpp moc_*.cpp ui_*.h + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = YES + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = YES + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = Q_SLOTS="slots" \ + Q_SIGNALS="signals" + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +CALLER_GRAPH = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = schema/doc/ + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = YES + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = YES + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/src/xmlpatterns/Mainpage.dox b/src/xmlpatterns/Mainpage.dox new file mode 100644 index 0000000..641619c --- /dev/null +++ b/src/xmlpatterns/Mainpage.dox @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +/** + * @mainpage QtXmlPatterns -- an implementation of XML technologies + * + * - @ref Patternist_info + * - @ref Patternist_writingDoxygen + * + * @section Patternist_info Overview + * + * This is the internal developer documentation for QtXmlPatterns. Please refer + * to Qt Assistant for usage documentation. + * + * The documentation that you are reading right now, can be generated by + * running doxygen in this directory without arguments. The generated + * documentation can subsequently be browsed from + * internal-docs/html/index.html. + * + * @subsection Patternist_writingDoxygen Doxygen Conventions + * + * Doxygen conventions, are as follows. + * + * - @@returns and @@param paragraphs are terminated with a period. + * - When XPath or XQuery expressions/queries appears in the Doxygen comments, wrap them + * in the @c tt HTML tag. + * - Classes and free standing functions should have an @@author tag, specifying who + * is the main author of it. + * - No code examples should appear directly in the Doxygen comments, they should be included with + * @@include or @@dontinclude. + * - The following terms are marked with @@c or the @c tt HTML tag: + * - @c NaN + * - @c true and @c false, when referred to as boolean values + * - All QNames and item types. For example, item\() and xs:string. Remember + * to use the @c tt HTML tag in these cases in order to include non-trivial characters + * such as paranteses + * - @c null + * - @c stderr, @c stdout, and @c stdin + * + * + * The current Doxygen comments does in some cases not adhere to this, but the + * idea is to harmonize in that direction over time. + * + * PatternistSDK, located in the test sources, is documented in the + * PatternistSDK Doxygen module. + * + * @author Frans Englich + */ diff --git a/src/xmlpatterns/acceltree/acceltree.pri b/src/xmlpatterns/acceltree/acceltree.pri new file mode 100644 index 0000000..284371a --- /dev/null +++ b/src/xmlpatterns/acceltree/acceltree.pri @@ -0,0 +1,10 @@ +SOURCES += $$PWD/qacceltree.cpp \ + $$PWD/qacceltreeresourceloader.cpp \ + $$PWD/qacceliterators.cpp \ + $$PWD/qcompressedwhitespace.cpp + +HEADERS += $$PWD/qacceltreebuilder_p.h \ + $$PWD/qacceltree_p.h \ + $$PWD/qacceltreeresourceloader_p.h \ + $$PWD/qacceliterators_p.h \ + $$PWD/qcompressedwhitespace_p.h diff --git a/src/xmlpatterns/acceltree/qacceliterators.cpp b/src/xmlpatterns/acceltree/qacceliterators.cpp new file mode 100644 index 0000000..20cd805 --- /dev/null +++ b/src/xmlpatterns/acceltree/qacceliterators.cpp @@ -0,0 +1,181 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qacceliterators_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +xsInteger AccelIterator::position() const +{ + return m_position; +} + +QXmlNodeModelIndex AccelIterator::current() const +{ + return m_current; +} + +QXmlNodeModelIndex FollowingIterator::next() +{ + /* "the following axis contains all nodes that are descendants + * of the root of the tree in which the context node is found, + * are not descendants of the context node, and occur after + * the context node in document order." */ + + if(m_position == 0) + { + /* Skip the descendants. */ + m_currentPre += m_document->size(m_preNumber) + 1; + } + + if(m_currentPre > m_document->maximumPreNumber()) + return closedExit(); + + while(m_document->kind(m_currentPre) == QXmlNodeModelIndex::Attribute) + { + ++m_currentPre; + if(m_currentPre > m_document->maximumPreNumber()) + return closedExit(); + } + + m_current = m_document->createIndex(m_currentPre); + ++m_position; + ++m_currentPre; + return m_current; +} + +QXmlNodeModelIndex PrecedingIterator::next() +{ + if(m_currentPre == -1) + return closedExit(); + + /* We skip ancestors and attributes and take into account that they can be intermixed. If one + * skips them in two separate loops, one can end up with skipping all the attributes to then + * be positioned at an ancestor(which will be accepted because the ancestor loop was before the + * attributes loop). */ + while(m_document->kind(m_currentPre) == QXmlNodeModelIndex::Attribute || + m_document->postNumber(m_currentPre) > m_postNumber) + { + --m_currentPre; + if(m_currentPre == -1) + return closedExit(); + } + + if(m_currentPre == -1) + { + m_currentPre = -1; + return closedExit(); + } + + /* Phew, m_currentPre is now 1) not an ancestor; and + * 2) not an attribute; and 3) preceds the context node. */ + + m_current = m_document->createIndex(m_currentPre); + ++m_position; + --m_currentPre; + + return m_current; +} + +QXmlNodeModelIndex::Iterator::Ptr PrecedingIterator::copy() const +{ + return QXmlNodeModelIndex::Iterator::Ptr(new PrecedingIterator(m_document, m_preNumber)); +} + +QXmlNodeModelIndex::Iterator::Ptr FollowingIterator::copy() const +{ + return QXmlNodeModelIndex::Iterator::Ptr(new FollowingIterator(m_document, m_preNumber)); +} + +QXmlNodeModelIndex ChildIterator::next() +{ + if(m_currentPre == -1) + return closedExit(); + + ++m_position; + m_current = m_document->createIndex(m_currentPre); + + /* We get the count of the descendants, and increment m_currentPre. After + * this, m_currentPre is the node after the descendants. */ + m_currentPre += m_document->size(m_currentPre); + ++m_currentPre; + + if(m_currentPre > m_document->maximumPreNumber() || m_document->depth(m_currentPre) != m_depth) + m_currentPre = -1; + + return m_current; +} + +QXmlNodeModelIndex::Iterator::Ptr ChildIterator::copy() const +{ + return QXmlNodeModelIndex::Iterator::Ptr(new ChildIterator(m_document, m_preNumber)); +} + +QXmlNodeModelIndex AttributeIterator::next() +{ + if(m_currentPre == -1) + return closedExit(); + else + { + m_current = m_document->createIndex(m_currentPre); + ++m_position; + + ++m_currentPre; + + if(m_currentPre > m_document->maximumPreNumber() || + m_document->kind(m_currentPre) != QXmlNodeModelIndex::Attribute) + m_currentPre = -1; + + return m_current; + } +} + +QXmlNodeModelIndex::Iterator::Ptr AttributeIterator::copy() const +{ + return QXmlNodeModelIndex::Iterator::Ptr(new AttributeIterator(m_document, m_preNumber)); +} + +QT_END_NAMESPACE + diff --git a/src/xmlpatterns/acceltree/qacceliterators_p.h b/src/xmlpatterns/acceltree/qacceliterators_p.h new file mode 100644 index 0000000..e472fb2 --- /dev/null +++ b/src/xmlpatterns/acceltree/qacceliterators_p.h @@ -0,0 +1,413 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_AccelIterators_H +#define Patternist_AccelIterators_H + +#include "qacceltree_p.h" +#include "qitem_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Abstract base class for Iterators for the AccelTree, that + * contains common functions and members. + * + * @author Frans Englich + */ + class AccelIterator : public QXmlNodeModelIndex::Iterator + { + public: + virtual xsInteger position() const; + virtual QXmlNodeModelIndex current() const; + + protected: + inline AccelIterator(const AccelTree *const doc, + const AccelTree::PreNumber pre, + const AccelTree::PreNumber currentPre) : m_document(doc) + , m_preNumber(pre) + , m_currentPre(currentPre) + , m_position(0) + + { + Q_ASSERT(m_document); + Q_ASSERT(m_preNumber >= 0); + } + + inline QXmlNodeModelIndex closedExit() + { + m_position = -1; + m_current.reset(); + return QXmlNodeModelIndex(); + } + + /** + * We do not own it. + */ + const AccelTree *const m_document; + + /** + * The pre number of the node that should be navigated from. + */ + const AccelTree::PreNumber m_preNumber; + AccelTree::PreNumber m_currentPre; + xsInteger m_position; + QXmlNodeModelIndex m_current; + }; + + /** + * @short Iterates along the @c ancestor or @c ancestor-or-self axis in an AccelTree. + * + * @author Frans Englich + */ + template + class AncestorIterator : public AccelIterator + { + public: + /** + * @p pre is the node from which iteration starts + * from. In the @c ancestor axis it is excluded, + * while in @c ancestor-or-self it is included. @p pre + * must have at least one ancestor. + */ + inline AncestorIterator(const AccelTree *const doc, + const AccelTree::PreNumber pre) : AccelIterator(doc, pre, IncludeSelf ? pre : doc->basicData.at(pre).parent()) + { + Q_ASSERT(IncludeSelf || m_document->hasParent(pre)); + } + + virtual QXmlNodeModelIndex next() + { + if(m_currentPre == -1) + return closedExit(); + else + { + ++m_position; + m_current = m_document->createIndex(m_currentPre); + m_currentPre = m_document->basicData.at(m_currentPre).parent(); + + return m_current; + } + } + + virtual QXmlNodeModelIndex::Iterator::Ptr copy() const + { + return QXmlNodeModelIndex::Iterator::Ptr(new AncestorIterator(m_document, m_preNumber)); + } + }; + + /** + * @short Iterates along the @c child axis in an AccelTree. + * + * @author Frans Englich + */ + class ChildIterator : public AccelIterator + { + public: + /** + * @p pre must have at least one child. + */ + inline ChildIterator(const AccelTree *const doc, + const AccelTree::PreNumber pre) : AccelIterator(doc, pre, pre + 1), + m_depth(m_document->depth(m_currentPre)) + { + Q_ASSERT(m_document->hasChildren(pre)); + + /* Skip the attributes, that are children in the pre/post plane, of + * the node we're applying the child axis to. */ + while(m_document->kind(m_currentPre) == QXmlNodeModelIndex::Attribute) + { + ++m_currentPre; + /* We check the depth here because we would otherwise include + * following siblings. */ + if(m_currentPre > m_document->maximumPreNumber() || m_document->depth(m_currentPre) != m_depth) + { + m_currentPre = -1; + break; + } + } + } + + virtual QXmlNodeModelIndex next(); + virtual QXmlNodeModelIndex::Iterator::Ptr copy() const; + + private: + const AccelTree::Depth m_depth; + }; + + /** + * @short Iterates along the sibling axes in an AccelTree. + * + * @author Frans Englich + */ + template + class SiblingIterator : public AccelIterator + { + public: + inline SiblingIterator(const AccelTree *const doc, + const AccelTree::PreNumber pre) : AccelIterator(doc, pre, pre + (IsFollowing ? 0 : -1)), + m_depth(doc->depth(pre)) + { + Q_ASSERT_X(IsFollowing || pre != 0, "", + "When being preceding-sibling, the context node cannot be the first node in the document."); + Q_ASSERT_X(!IsFollowing || pre != m_document->maximumPreNumber(), "", + "When being following-sibling, the context node cannot be the last node in the document."); + } + + virtual QXmlNodeModelIndex next() + { + if(m_currentPre == -1) + return QXmlNodeModelIndex(); + + if(IsFollowing) + { + /* Skip the descendants, and jump to the next node. */ + m_currentPre += m_document->size(m_currentPre) + 1; + + if(m_currentPre > m_document->maximumPreNumber() || m_document->depth(m_currentPre) != m_depth) + return closedExit(); + else + { + ++m_position; + m_current = m_document->createIndex(m_currentPre); + return m_current; + } + } + else + { + while(m_document->depth(m_currentPre) > m_depth) + --m_currentPre; + + while(m_document->kind(m_currentPre) == QXmlNodeModelIndex::Attribute) + --m_currentPre; + + if(m_document->depth(m_currentPre) == m_depth && + m_document->kind(m_currentPre) != QXmlNodeModelIndex::Attribute) + { + m_current = m_document->createIndex(m_currentPre); + ++m_position; + --m_currentPre; + return m_current; + } + else + { + m_currentPre = -1; + return closedExit(); + } + } + } + + virtual QXmlNodeModelIndex::Iterator::Ptr copy() const + { + return QXmlNodeModelIndex::Iterator::Ptr(new SiblingIterator(m_document, m_preNumber)); + } + + private: + const AccelTree::Depth m_depth; + }; + + /** + * @short Implements axis @c descendant and @c descendant-or-self for the + * AccelTree. + * + * @author Frans Englich + */ + template + class DescendantIterator : public AccelIterator + { + public: + /** + * @p pre must have at least one child. + */ + inline DescendantIterator(const AccelTree *const doc, + const AccelTree::PreNumber pre) : AccelIterator(doc, pre, pre + (IncludeSelf ? 0 : 1)), + m_postNumber(doc->postNumber(pre)) + { + Q_ASSERT(IncludeSelf || m_document->hasChildren(pre)); + + /* Make sure that m_currentPre is the first node part of this axis. + * Since we're not including ourself, advance to the node after our + * attributes, if any. */ + if(!IncludeSelf) + { + while(m_document->kind(m_currentPre) == QXmlNodeModelIndex::Attribute) + { + ++m_currentPre; + /* We check the depth here because we would otherwise include + * following siblings. */ + if(m_currentPre > m_document->maximumPreNumber() || m_document->postNumber(m_currentPre) > m_postNumber) + { + m_currentPre = -1; + break; + } + } + } + } + + virtual QXmlNodeModelIndex next() + { + if(m_currentPre == -1) + return closedExit(); + + ++m_position; + m_current = m_document->createIndex(m_currentPre); + + ++m_currentPre; + + if(m_currentPre > m_document->maximumPreNumber()) + { + m_currentPre = -1; + return m_current; + } + + if(m_document->postNumber(m_currentPre) < m_postNumber) + { + while(m_document->kind(m_currentPre) == QXmlNodeModelIndex::Attribute) + { + ++m_currentPre; + if(m_currentPre > m_document->maximumPreNumber()) + { + m_currentPre = -1; + break; + } + } + } + else + m_currentPre = -1; + + return m_current; + } + + virtual QXmlNodeModelIndex::Iterator::Ptr copy() const + { + return QXmlNodeModelIndex::Iterator::Ptr(new DescendantIterator(m_document, m_preNumber)); + } + + private: + const AccelTree::PreNumber m_postNumber; + }; + + /** + * @short Implements axis @c following for the AccelTree. + * + * @author Frans Englich + */ + class FollowingIterator : public AccelIterator + { + public: + /** + * @ pre must have at least one child. + */ + inline FollowingIterator(const AccelTree *const doc, + const AccelTree::PreNumber pre) : AccelIterator(doc, pre, pre) + { + } + + virtual QXmlNodeModelIndex next(); + virtual QXmlNodeModelIndex::Iterator::Ptr copy() const; + }; + + /** + * @short Implements axis @c preceding for the AccelTree. + * + * @author Frans Englich + */ + class PrecedingIterator : public AccelIterator + { + public: + /** + * @ pre must have at least one child. + */ + inline PrecedingIterator(const AccelTree *const doc, + const AccelTree::PreNumber pre) : AccelIterator(doc, pre, + pre - 1 /* currentPre */) + , m_postNumber(m_document->postNumber(m_preNumber)) + { + } + + virtual QXmlNodeModelIndex next(); + virtual QXmlNodeModelIndex::Iterator::Ptr copy() const; + + private: + const AccelTree::PreNumber m_postNumber; + }; + + /** + * @short Implements axis @c attribute for the AccelTree. + * + * @author Frans Englich + */ + class AttributeIterator : public AccelIterator + { + public: + /** + * @p pre must have at least one child. + */ + inline AttributeIterator(const AccelTree *const doc, const AccelTree::PreNumber pre) : AccelIterator(doc, pre, pre + 1) + { + Q_ASSERT(m_document->hasChildren(pre)); + Q_ASSERT(m_document->kind(m_currentPre) == QXmlNodeModelIndex::Attribute); + } + + virtual QXmlNodeModelIndex next(); + virtual QXmlNodeModelIndex::Iterator::Ptr copy() const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/acceltree/qacceltree.cpp b/src/xmlpatterns/acceltree/qacceltree.cpp new file mode 100644 index 0000000..f2f383a --- /dev/null +++ b/src/xmlpatterns/acceltree/qacceltree.cpp @@ -0,0 +1,749 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qabstractxmlreceiver.h" +#include "qabstractxmlnodemodel_p.h" +#include "qacceliterators_p.h" +#include "qacceltree_p.h" +#include "qatomicstring_p.h" +#include "qcommonvalues_p.h" +#include "qcompressedwhitespace_p.h" +#include "qdebug_p.h" +#include "quntypedatomic_p.h" +#include "qxpathhelper_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +namespace QPatternist { + + class AccelTreePrivate : public QAbstractXmlNodeModelPrivate + { + public: + AccelTreePrivate(AccelTree *accelTree) + : m_accelTree(accelTree) + { + } + + virtual QSourceLocation sourceLocation(const QXmlNodeModelIndex &index) const + { + return m_accelTree->sourceLocation(index); + } + + private: + AccelTree *m_accelTree; + }; +} + +AccelTree::AccelTree(const QUrl &docURI, const QUrl &bURI) + : QAbstractXmlNodeModel(new AccelTreePrivate(this)) + , m_documentURI(docURI) + , m_baseURI(bURI) +{ + /* Pre-allocate at least a little bit. */ + // TODO. Do it according to what an average 4 KB doc contains. + basicData.reserve(100); + data.reserve(30); +} + +void AccelTree::printStats(const NamePool::Ptr &np) const +{ + Q_ASSERT(np); +#ifdef QT_NO_DEBUG + Q_UNUSED(np); /* Needed when compiling in release mode. */ +#else + const int len = basicData.count(); + + pDebug() << "AccelTree stats for" << (m_documentURI.isEmpty() ? QString::fromLatin1("") : m_documentURI.toString()); + pDebug() << "Maximum pre number:" << maximumPreNumber(); + pDebug() << "+---------------+-------+-------+---------------+-------+--------------+-------+"; + pDebug() << "| Pre number | Depth | Size | Post Number | Kind | Name | Value |"; + pDebug() << "+---------------+-------+-------+---------------+-------+--------------+-------+"; + for(int i = 0; i < len; ++i) + { + const BasicNodeData &v = basicData.at(i); + pDebug() << '|' << i + << "\t\t|" << v.depth() + << "\t|" << v.size() + << "\t|" << postNumber(i) + << "\t|" << v.kind() + << "\t\t|" << (v.name().isNull() ? QString::fromLatin1("(none)") : np->displayName(v.name())) + << "\t\t|" << ((v.kind() == QXmlNodeModelIndex::Text && isCompressed(i)) ? CompressedWhitespace::decompress(data.value(i)) + : data.value(i)) + << "\t|"; + /* + pDebug() << '|' << QString().arg(i, 14) + << '|' << QString().arg(v.depth(), 6) + << '|' << QString().arg(v.size(), 6) + << '|' << QString().arg(postNumber(i), 14) + << '|' << QString().arg(v.kind(), 6) + << '|'; + */ + } + pDebug() << "+---------------+-------+-------+---------------+-------+--------------+"; + pDebug() << "Namespaces(" << namespaces.count() << "):"; + + QHashIterator > it(namespaces); + while(it.hasNext()) + { + it.next(); + + pDebug() << "PreNumber: " << QString::number(it.key()); + for(int i = 0; i < it.value().count(); ++i) + pDebug() << "\t\t" << np->stringForPrefix(it.value().at(i).prefix()) << " = " << np->stringForNamespace(it.value().at(i).namespaceURI()); + } + +#endif +} + +QUrl AccelTree::baseUri(const QXmlNodeModelIndex &ni) const +{ + switch(kind(toPreNumber(ni))) + { + case QXmlNodeModelIndex::Document: + return baseUri(); + case QXmlNodeModelIndex::Element: + { + const QXmlNodeModelIndex::Iterator::Ptr it(iterate(ni, QXmlNodeModelIndex::AxisAttribute)); + QXmlNodeModelIndex next(it->next()); + + while(!next.isNull()) + { + if(next.name() == QXmlName(StandardNamespaces::xml, StandardLocalNames::base)) + { + const QUrl candidate(next.stringValue()); + // TODO. The xml:base spec says to do URI escaping here. + + if(!candidate.isValid()) + return QUrl(); + else if(candidate.isRelative()) + { + const QXmlNodeModelIndex par(parent(ni)); + + if(par.isNull()) + return baseUri().resolved(candidate); + else + return par.baseUri().resolved(candidate); + } + else + return candidate; + } + + next = it->next(); + } + + /* We have no xml:base-attribute. Can any parent supply us a base URI? */ + const QXmlNodeModelIndex par(parent(ni)); + + if(par.isNull()) + return baseUri(); + else + return par.baseUri(); + } + case QXmlNodeModelIndex::ProcessingInstruction: + /* Fallthrough. */ + case QXmlNodeModelIndex::Comment: + /* Fallthrough. */ + case QXmlNodeModelIndex::Attribute: + /* Fallthrough. */ + case QXmlNodeModelIndex::Text: + { + const QXmlNodeModelIndex par(ni.iterate(QXmlNodeModelIndex::AxisParent)->next()); + if(par.isNull()) + return QUrl(); + else + return par.baseUri(); + } + case QXmlNodeModelIndex::Namespace: + return QUrl(); + } + + Q_ASSERT_X(false, Q_FUNC_INFO, "This line is never supposed to be reached."); + return QUrl(); +} + +QUrl AccelTree::documentUri(const QXmlNodeModelIndex &ni) const +{ + if(kind(toPreNumber(ni)) == QXmlNodeModelIndex::Document) + return documentUri(); + else + return QUrl(); +} + +QXmlNodeModelIndex::NodeKind AccelTree::kind(const QXmlNodeModelIndex &ni) const +{ + return kind(toPreNumber(ni)); +} + +QXmlNodeModelIndex::DocumentOrder AccelTree::compareOrder(const QXmlNodeModelIndex &ni1, + const QXmlNodeModelIndex &ni2) const +{ + Q_ASSERT_X(ni1.model() == ni2.model(), Q_FUNC_INFO, + "The API docs guarantees the two nodes are from the same model"); + + const PreNumber p1 = ni1.data(); + const PreNumber p2 = ni2.data(); + + if(p1 == p2) + return QXmlNodeModelIndex::Is; + else if(p1 < p2) + return QXmlNodeModelIndex::Precedes; + else + return QXmlNodeModelIndex::Follows; +} + +QXmlNodeModelIndex AccelTree::root(const QXmlNodeModelIndex &) const +{ + return createIndex(qint64(0)); +} + +QXmlNodeModelIndex AccelTree::parent(const QXmlNodeModelIndex &ni) const +{ + const AccelTree::PreNumber p = basicData.at(toPreNumber(ni)).parent(); + + if(p == -1) + return QXmlNodeModelIndex(); + else + return createIndex(p); +} + +QXmlNodeModelIndex::Iterator::Ptr AccelTree::iterate(const QXmlNodeModelIndex &ni, + QXmlNodeModelIndex::Axis axis) const +{ + const PreNumber preNumber = toPreNumber(ni); + + switch(axis) + { + case QXmlNodeModelIndex::AxisChildOrTop: + { + if(!hasParent(preNumber)) + { + switch(kind(preNumber)) + { + case QXmlNodeModelIndex::Comment: + /* Fallthrough. */ + case QXmlNodeModelIndex::ProcessingInstruction: + /* Fallthrough. */ + case QXmlNodeModelIndex::Element: + /* Fallthrough. */ + case QXmlNodeModelIndex::Text: + return makeSingletonIterator(ni); + case QXmlNodeModelIndex::Attribute: + /* Fallthrough. */ + case QXmlNodeModelIndex::Document: + /* Fallthrough. */ + case QXmlNodeModelIndex::Namespace: + /* Do nothing. */; + } + } + /* Else, fallthrough to AxisChild. */ + } + case QXmlNodeModelIndex::AxisChild: + { + if(hasChildren(preNumber)) + return QXmlNodeModelIndex::Iterator::Ptr(new ChildIterator(this, preNumber)); + else + return makeEmptyIterator(); + } + case QXmlNodeModelIndex::AxisAncestor: + { + if(hasParent(preNumber)) + return QXmlNodeModelIndex::Iterator::Ptr(new AncestorIterator(this, preNumber)); + else + return makeEmptyIterator(); + } + case QXmlNodeModelIndex::AxisAncestorOrSelf: + return QXmlNodeModelIndex::Iterator::Ptr(new AncestorIterator(this, preNumber)); + case QXmlNodeModelIndex::AxisParent: + { + if(hasParent(preNumber)) + return makeSingletonIterator(createIndex(parent(preNumber))); + else + return makeEmptyIterator(); + } + case QXmlNodeModelIndex::AxisDescendant: + { + if(hasChildren(preNumber)) + return QXmlNodeModelIndex::Iterator::Ptr(new DescendantIterator(this, preNumber)); + else + return makeEmptyIterator(); + } + case QXmlNodeModelIndex::AxisDescendantOrSelf: + return QXmlNodeModelIndex::Iterator::Ptr(new DescendantIterator(this, preNumber)); + case QXmlNodeModelIndex::AxisFollowing: + { + if(preNumber == maximumPreNumber()) + return makeEmptyIterator(); + else + return QXmlNodeModelIndex::Iterator::Ptr(new FollowingIterator(this, preNumber)); + } + case QXmlNodeModelIndex::AxisAttributeOrTop: + { + if(!hasParent(preNumber) && kind(preNumber) == QXmlNodeModelIndex::Attribute) + return makeSingletonIterator(ni); + /* Else, falthrough to AxisAttribute. */ + } + case QXmlNodeModelIndex::AxisAttribute: + { + if(hasChildren(preNumber) && kind(preNumber + 1) == QXmlNodeModelIndex::Attribute) + return QXmlNodeModelIndex::Iterator::Ptr(new AttributeIterator(this, preNumber)); + else + return makeEmptyIterator(); + } + case QXmlNodeModelIndex::AxisPreceding: + { + if(preNumber == 0) + return makeEmptyIterator(); + else + return QXmlNodeModelIndex::Iterator::Ptr(new PrecedingIterator(this, preNumber)); + } + case QXmlNodeModelIndex::AxisSelf: + return makeSingletonIterator(createIndex(toPreNumber(ni))); + case QXmlNodeModelIndex::AxisFollowingSibling: + { + if(preNumber == maximumPreNumber()) + return makeEmptyIterator(); + else + return QXmlNodeModelIndex::Iterator::Ptr(new SiblingIterator(this, preNumber)); + } + case QXmlNodeModelIndex::AxisPrecedingSibling: + { + if(preNumber == 0) + return makeEmptyIterator(); + else + return QXmlNodeModelIndex::Iterator::Ptr(new SiblingIterator(this, preNumber)); + } + case QXmlNodeModelIndex::AxisNamespace: + return makeEmptyIterator(); + } + + Q_ASSERT(false); + return QXmlNodeModelIndex::Iterator::Ptr(); +} + +QXmlNodeModelIndex AccelTree::nextFromSimpleAxis(QAbstractXmlNodeModel::SimpleAxis, + const QXmlNodeModelIndex&) const +{ + Q_ASSERT_X(false, Q_FUNC_INFO, "This function is not supposed to be called."); + return QXmlNodeModelIndex(); +} + +QVector AccelTree::attributes(const QXmlNodeModelIndex &element) const +{ + Q_ASSERT_X(false, Q_FUNC_INFO, "This function is not supposed to be called."); + Q_UNUSED(element); + return QVector(); +} + +QXmlName AccelTree::name(const QXmlNodeModelIndex &ni) const +{ + /* If this node type does not have a name(for instance, it's a comment) + * we will return the default constructed value, which is conformant with + * this function's contract. */ + return name(toPreNumber(ni)); +} + +QVector AccelTree::namespaceBindings(const QXmlNodeModelIndex &ni) const +{ + /* We get a hold of the ancestor, and loop them in reverse document + * order(first the parent, then the parent's parent, etc). As soon + * we find a binding that hasn't already been added, we add it to the + * result list. In that way, declarations appearing further down override + * those further up. */ + + const PreNumber preNumber = toPreNumber(ni); + + const QXmlNodeModelIndex::Iterator::Ptr it(new AncestorIterator(this, preNumber)); + QVector result; + QXmlNodeModelIndex n(it->next()); + + /* Whether xmlns="" has been encountered. */ + bool hasUndeclaration = false; + + while(!n.isNull()) + { + const QVector &forNode = namespaces.value(toPreNumber(n)); + const int len = forNode.size(); + bool stopInheritance = false; + + for(int i = 0; i < len; ++i) + { + const QXmlName &nsb = forNode.at(i); + + if(nsb.namespaceURI() == StandardNamespaces::StopNamespaceInheritance) + { + stopInheritance = true; + continue; + } + + if(nsb.prefix() == StandardPrefixes::empty && + nsb.namespaceURI() == StandardNamespaces::empty) + { + hasUndeclaration = true; + continue; + } + + if(!hasPrefix(result, nsb.prefix())) + { + /* We've already encountered an undeclaration, so we're supposed to skip + * them. */ + if(hasUndeclaration && nsb.prefix() == StandardPrefixes::empty) + continue; + else + result.append(nsb); + } + } + + if(stopInheritance) + break; + else + n = it->next(); + } + + result.append(QXmlName(StandardNamespaces::xml, StandardLocalNames::empty, StandardPrefixes::xml)); + + return result; +} + +void AccelTree::sendNamespaces(const QXmlNodeModelIndex &n, + QAbstractXmlReceiver *const receiver) const +{ + Q_ASSERT(n.kind() == QXmlNodeModelIndex::Element); + + const QXmlNodeModelIndex::Iterator::Ptr it(iterate(n, QXmlNodeModelIndex::AxisAncestorOrSelf)); + QXmlNodeModelIndex next(it->next()); + QVector alreadySent; + + while(!next.isNull()) + { + const PreNumber preNumber = toPreNumber(next); + + const QVector &nss = namespaces.value(preNumber); + + /* This is by far the most common case. */ + if(nss.isEmpty()) + { + next = it->next(); + continue; + } + + const int len = nss.count(); + bool stopInheritance = false; + + for(int i = 0; i < len; ++i) + { + const QXmlName &name = nss.at(i); + + if(name.namespaceURI() == StandardNamespaces::StopNamespaceInheritance) + { + stopInheritance = true; + continue; + } + + if(!alreadySent.contains(name.prefix())) + { + alreadySent.append(name.prefix()); + receiver->namespaceBinding(name); + } + } + + if(stopInheritance) + break; + else + next = it->next(); + } +} + +QString AccelTree::stringValue(const QXmlNodeModelIndex &ni) const +{ + const PreNumber preNumber = toPreNumber(ni); + + switch(kind(preNumber)) + { + case QXmlNodeModelIndex::Element: + { + /* Concatenate all text nodes that are descendants of this node. */ + if(!hasChildren(preNumber)) + return QString(); + + const AccelTree::PreNumber stop = preNumber + size(preNumber); + AccelTree::PreNumber pn = preNumber + 1; /* Jump over ourselves. */ + QString result; + + for(; pn <= stop; ++pn) + { + if(kind(pn) == QXmlNodeModelIndex::Text) + { + if(isCompressed(pn)) + result += CompressedWhitespace::decompress(data.value(pn)); + else + result += data.value(pn); + } + } + + return result; + } + case QXmlNodeModelIndex::Text: + { + if(isCompressed(preNumber)) + return CompressedWhitespace::decompress(data.value(preNumber)); + /* Else, fallthrough. It's not compressed so use it as it is. */ + } + case QXmlNodeModelIndex::Attribute: + /* Fallthrough */ + case QXmlNodeModelIndex::ProcessingInstruction: + /* Fallthrough */ + case QXmlNodeModelIndex::Comment: + return data.value(preNumber); + case QXmlNodeModelIndex::Document: + { + /* Concatenate all text nodes in the whole document. */ + + QString result; + // Perhaps we can QString::reserve() the result based on the size? + const AccelTree::PreNumber max = maximumPreNumber(); + + for(AccelTree::PreNumber i = 0; i <= max; ++i) + { + if(kind(i) == QXmlNodeModelIndex::Text) + { + if(isCompressed(i)) + result += CompressedWhitespace::decompress(data.value(i)); + else + result += data.value(i); + } + } + + return result; + } + default: + { + Q_ASSERT_X(false, Q_FUNC_INFO, + "A node type that doesn't exist in the XPath Data Model was encountered."); + return QString(); /* Dummy, silence compiler warning. */ + } + } +} + +QVariant AccelTree::typedValue(const QXmlNodeModelIndex &n) const +{ + return stringValue(n); +} + +bool AccelTree::hasPrefix(const QVector &nbs, const QXmlName::PrefixCode prefix) +{ + const int size = nbs.size(); + + for(int i = 0; i < size; ++i) + { + if(nbs.at(i).prefix() == prefix) + return true; + } + + return false; +} + +ItemType::Ptr AccelTree::type(const QXmlNodeModelIndex &ni) const +{ + /* kind() is manually inlined here to avoid a virtual call. */ + return XPathHelper::typeFromKind(basicData.at(toPreNumber(ni)).kind()); +} + +Item::Iterator::Ptr AccelTree::sequencedTypedValue(const QXmlNodeModelIndex &n) const +{ + const PreNumber preNumber = toPreNumber(n); + + switch(kind(preNumber)) + { + case QXmlNodeModelIndex::Element: + /* Fallthrough. */ + case QXmlNodeModelIndex::Document: + /* Fallthrough. */ + case QXmlNodeModelIndex::Attribute: + return makeSingletonIterator(Item(UntypedAtomic::fromValue(stringValue(n)))); + + case QXmlNodeModelIndex::Text: + /* Fallthrough. */ + case QXmlNodeModelIndex::ProcessingInstruction: + /* Fallthrough. */ + case QXmlNodeModelIndex::Comment: + return makeSingletonIterator(Item(AtomicString::fromValue(stringValue(n)))); + default: + { + Q_ASSERT_X(false, Q_FUNC_INFO, + qPrintable(QString::fromLatin1("A node type that doesn't exist " + "in the XPath Data Model was encountered.").arg(kind(preNumber)))); + return Item::Iterator::Ptr(); /* Dummy, silence compiler warning. */ + } + } +} + +void AccelTree::copyNodeTo(const QXmlNodeModelIndex &node, + QAbstractXmlReceiver *const receiver, + const NodeCopySettings &settings) const +{ + /* This code piece can be seen as a customized version of + * QAbstractXmlReceiver::item/sendAsNode(). */ + Q_ASSERT(receiver); + Q_ASSERT(!node.isNull()); + + typedef QHash Binding; + QStack outputted; + + switch(node.kind()) + { + case QXmlNodeModelIndex::Element: + { + outputted.push(Binding()); + + /* Add the namespace for our element name. */ + const QXmlName elementName(node.name()); + + receiver->startElement(elementName); + + if(!settings.testFlag(InheritNamespaces)) + receiver->namespaceBinding(QXmlName(StandardNamespaces::StopNamespaceInheritance, 0, + StandardPrefixes::StopNamespaceInheritance)); + + if(settings.testFlag(PreserveNamespaces)) + node.sendNamespaces(receiver); + else + { + /* Find the namespaces that we actually use and add them to outputted. These are drawn + * from the element name, and the node's attributes. */ + outputted.top().insert(elementName.prefix(), elementName.namespaceURI()); + + const QXmlNodeModelIndex::Iterator::Ptr attributes(iterate(node, QXmlNodeModelIndex::AxisAttribute)); + QXmlNodeModelIndex attr(attributes->next()); + + while(!attr.isNull()) + { + const QXmlName &attrName = attr.name(); + outputted.top().insert(attrName.prefix(), attrName.namespaceURI()); + attr = attributes->next(); + } + + Binding::const_iterator it(outputted.top().constBegin()); + const Binding::const_iterator end(outputted.top().constEnd()); + + for(; it != end; ++it) + receiver->namespaceBinding(QXmlName(it.value(), 0, it.key())); + } + + /* Send the attributes of the element. */ + { + QXmlNodeModelIndex::Iterator::Ptr attributes(node.iterate(QXmlNodeModelIndex::AxisAttribute)); + QXmlNodeModelIndex attribute(attributes->next()); + + while(!attribute.isNull()) + { + const QString &v = attribute.stringValue(); + receiver->attribute(attribute.name(), QStringRef(&v)); + attribute = attributes->next(); + } + } + + /* Send the children of the element. */ + copyChildren(node, receiver, settings); + + receiver->endElement(); + outputted.pop(); + break; + } + case QXmlNodeModelIndex::Document: + { + /* We need to intercept and grab the elements of the document node, such + * that we preserve/inherit preference applies to them. */ + receiver->startDocument(); + copyChildren(node, receiver, settings); + receiver->endDocument(); + break; + } + default: + receiver->item(node); + } + +} + +QSourceLocation AccelTree::sourceLocation(const QXmlNodeModelIndex &index) const +{ + const PreNumber key = toPreNumber(index); + if (sourcePositions.contains(key)) { + const QPair position = sourcePositions.value(key); + return QSourceLocation(m_documentURI, position.first, position.second); + } else { + return QSourceLocation(); + } +} + +void AccelTree::copyChildren(const QXmlNodeModelIndex &node, + QAbstractXmlReceiver *const receiver, + const NodeCopySettings &settings) const +{ + QXmlNodeModelIndex::Iterator::Ptr children(node.iterate(QXmlNodeModelIndex::AxisChild)); + QXmlNodeModelIndex child(children->next()); + + while(!child.isNull()) + { + copyNodeTo(child, receiver, settings); + child = children->next(); + } +} + +QXmlNodeModelIndex AccelTree::elementById(const QXmlName &id) const +{ + const PreNumber pre = m_IDs.value(id.localName(), -1); + if(pre == -1) + return QXmlNodeModelIndex(); + else + return createIndex(pre); +} + +QVector AccelTree::nodesByIdref(const QXmlName &) const +{ + return QVector(); +} + +QT_END_NAMESPACE + diff --git a/src/xmlpatterns/acceltree/qacceltree_p.h b/src/xmlpatterns/acceltree/qacceltree_p.h new file mode 100644 index 0000000..0a9bf6c --- /dev/null +++ b/src/xmlpatterns/acceltree/qacceltree_p.h @@ -0,0 +1,404 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_AccelTree_H +#define Patternist_AccelTree_H + +#include +#include +#include +#include + +#include "qitem_p.h" +#include "qnamepool_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + template class AccelTreeBuilder; + + /** + * @short Stores an XML document using the XPath Accelerator scheme, also + * known as pre/post numbering. + * + * Working on this code will be destructive without a proper understanding of + * the Accelerator scheme, so do check out the links. We don't implement any form + * of staircase join, although that is only due to time constraints. + * + * @author Frans Englich + * @see XPath + * Accelerator + * @see Accelerating + * XPath Location Steps, Torsten Grust + * @see Staircase Join: + * Teach a Relational DBMS to Watch its (Axis) Steps + * @see Loop-lifted + * staircase join: from XPath to XQuery, Torsten Grust + * @see xmlstat, Frans Englich + * @see Accelerating + * XPath Evaluation in Any RDBMS, Torsten Grust + */ + class Q_AUTOTEST_EXPORT AccelTree : public QAbstractXmlNodeModel + { + friend class AccelTreePrivate; + public: + using QAbstractXmlNodeModel::createIndex; + + typedef QExplicitlySharedDataPointer Ptr; + typedef qint32 PreNumber; + typedef PreNumber PostNumber; + typedef qint8 Depth; + + AccelTree(const QUrl &docURI, const QUrl &bURI); + + /** + * @short Houses data for a node, and that all node kinds have. + * + * BasicNodeData is internal to the Accel tree implementation, and is + * only used by those classes. + * + * @author Frans Englich + * @todo Can't m_kind be coded somewhere else? If m_name is invalid, + * its bits can be used to distinguish the node types that doesn't have + * names, and for elements, attributes and processing instructions, we need + * two bits, somewhere. Attributes and processing instructions can't have a + * size, is that of help? There's also certain rules for the names. For instance, + * a processing instruction will never have a prefix nor namespace. Neither + * will an attribute node have a default, non-empty namespace, right? + * @todo Compress text nodes, add general support for it in Patternist. + */ + class BasicNodeData + { + public: + /* No need to initialize the members. See AccelTreeBuilder. */ + inline BasicNodeData() + { + } + + inline BasicNodeData(const PreNumber aDepth, + const PreNumber aParent, + const QXmlNodeModelIndex::NodeKind k, + const PreNumber s, + const QXmlName n = QXmlName()) : m_parent(aParent) + , m_size(s) + , m_name(n) + , m_depth(aDepth) + , m_kind(k) + { + } + + inline Depth depth() const + { + return m_depth; + } + + inline PreNumber parent() const + { + return m_parent; + } + + /** + * @see AccelTree::size() + */ + inline PreNumber size() const + { + /* Remember that we use the m_size to signal compression if + * we're a text node. */ + if(m_kind == QXmlNodeModelIndex::Text) + return 0; + else + return m_size; + } + + inline void setSize(const PreNumber aSize) + { + m_size = aSize; + } + + inline QXmlNodeModelIndex::NodeKind kind() const + { + return m_kind; + } + + inline QXmlName name() const + { + return m_name; + } + + inline bool isCompressed() const + { + Q_ASSERT_X(m_kind == QXmlNodeModelIndex::Text, Q_FUNC_INFO, + "Currently, only text nodes are compressed."); + /* Note, we don't call size() here, since it has logic for text + * nodes. */ + return m_size == IsCompressed; + } + + private: + /** + * This is the pre number of the parent. + */ + PreNumber m_parent; + + /** + * This is the count of children this node has. + * + * In the case of a text node, which cannot have children, + * it is set to IsCompressed, if the content has been the result + * of CompressedWhitespace::compress(). If it's not compressed, + * it is zero. + */ + PreNumber m_size; + + /** + * For text nodes, and less importantly, comments, + * this variable is not used. + */ + QXmlName m_name; + + Depth m_depth; + + /** + * Technically it is sufficient with 7 bits. However, at least MSVC + * 2005 miscompiles it such that QXmlNodeModelIndex::Text becomes + * -64 instead of 64 with hilarious crashes as result. + * + * Fortunately this extra bit would be padded anyway. + */ + QXmlNodeModelIndex::NodeKind m_kind : 8; + }; + + virtual QUrl baseUri(const QXmlNodeModelIndex &ni) const; + virtual QUrl documentUri(const QXmlNodeModelIndex &ni) const; + virtual QXmlNodeModelIndex::NodeKind kind(const QXmlNodeModelIndex &ni) const; + virtual QXmlNodeModelIndex::DocumentOrder compareOrder(const QXmlNodeModelIndex &ni1, + const QXmlNodeModelIndex &ni2) const; + + /** + * @short Returns the root node. + * + * This function does not use @p n, so a default constructed + * QXmlNodeModelIndex may be passed. + */ + virtual QXmlNodeModelIndex root(const QXmlNodeModelIndex &n) const; + + virtual QXmlNodeModelIndex parent(const QXmlNodeModelIndex &ni) const; + virtual QXmlNodeModelIndex::Iterator::Ptr iterate(const QXmlNodeModelIndex &ni, + QXmlNodeModelIndex::Axis axis) const; + virtual QXmlName name(const QXmlNodeModelIndex &ni) const; + virtual QVector namespaceBindings(const QXmlNodeModelIndex &n) const; + virtual void sendNamespaces(const QXmlNodeModelIndex &n, + QAbstractXmlReceiver *const receiver) const; + virtual QString stringValue(const QXmlNodeModelIndex &n) const; + virtual QVariant typedValue(const QXmlNodeModelIndex &n) const; + virtual Item::Iterator::Ptr sequencedTypedValue(const QXmlNodeModelIndex &n) const; + virtual ItemType::Ptr type(const QXmlNodeModelIndex &ni) const; + virtual QXmlNodeModelIndex elementById(const QXmlName &id) const; + virtual QVector nodesByIdref(const QXmlName &idref) const; + virtual void copyNodeTo(const QXmlNodeModelIndex &node, + QAbstractXmlReceiver *const receiver, + const NodeCopySettings &settings) const; + + friend class AccelTreeBuilder; + friend class AccelTreeBuilder; + + enum Constants + { + IsCompressed = 1 + }; + + /** + * The key is the pre number of an element, and the value is a vector + * containing the namespace declarations being declared on that + * element. Therefore, it does not reflect the namespaces being in + * scope for that element. For that, a walk along axis ancestor is + * necessary. + */ + QHash > namespaces; + + /** + * Stores data for nodes. The QHash's value is the data of the processing instruction, and the + * content of a text node or comment. + */ + QHash data; + + QVector basicData; + QHash > sourcePositions; + + inline QUrl documentUri() const + { + return m_documentURI; + } + + inline QUrl baseUri() const + { + return m_baseURI; + } + + /** + * @short Returns @c true if the node identified by @p pre has child + * nodes(in the sense of the XDM), but also if it has namespace nodes, + * or attribute nodes. + */ + inline bool hasChildren(const PreNumber pre) const + { + return basicData.at(pre).size() > 0; + } + + /** + * @short Returns the parent node of @p pre. + * + * If @p pre parent doesn't have a parent node, the return value is + * undefined. + * + * @see hasParent() + */ + inline PreNumber parent(const PreNumber pre) const + { + return basicData.at(pre).parent(); + } + + inline bool hasParent(const PreNumber pre) const + { + return basicData.at(pre).depth() > 0; + } + + inline bool hasFollowingSibling(const PreNumber pre) const + { + return pre < maximumPreNumber(); + } + + inline PostNumber postNumber(const PreNumber pre) const + { + const BasicNodeData &b = basicData.at(pre); + return pre + b.size() - b.depth(); + } + + inline QXmlNodeModelIndex::NodeKind kind(const PreNumber pre) const + { + return basicData.at(pre).kind(); + } + + inline PreNumber maximumPreNumber() const + { + return basicData.count() - 1; + } + + inline PreNumber toPreNumber(const QXmlNodeModelIndex n) const + { + return n.data(); + } + + inline PreNumber size(const PreNumber pre) const + { + Q_ASSERT_X(basicData.at(pre).size() != -1, Q_FUNC_INFO, + "The size cannot be -1. That means an uninitialized value is attempted to be used."); + return basicData.at(pre).size(); + } + + inline Depth depth(const PreNumber pre) const + { + return basicData.at(pre).depth(); + } + + void printStats(const NamePool::Ptr &np) const; + + inline QXmlName name(const PreNumber pre) const + { + return basicData.at(pre).name(); + } + + inline bool isCompressed(const PreNumber pre) const + { + return basicData.at(pre).isCompressed(); + } + + static inline bool hasPrefix(const QVector &nbs, const QXmlName::PrefixCode prefix); + + QUrl m_documentURI; + QUrl m_baseURI; + + protected: + virtual QXmlNodeModelIndex nextFromSimpleAxis(QAbstractXmlNodeModel::SimpleAxis, + const QXmlNodeModelIndex&) const; + virtual QVector attributes(const QXmlNodeModelIndex &element) const; + + private: + /** + * Returns the source location for the object with the given @p index. + */ + QSourceLocation sourceLocation(const QXmlNodeModelIndex &index) const; + + /** + * Copies the children of @p node to @p receiver. + */ + inline void copyChildren(const QXmlNodeModelIndex &node, + QAbstractXmlReceiver *const receiver, + const NodeCopySettings &settings) const; + + /** + * The key is the xml:id value, and the value is the element + * with that value. + */ + QHash m_IDs; + }; +} + +Q_DECLARE_TYPEINFO(QPatternist::AccelTree::BasicNodeData, Q_MOVABLE_TYPE); + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/acceltree/qacceltreebuilder.cpp b/src/xmlpatterns/acceltree/qacceltreebuilder.cpp new file mode 100644 index 0000000..e752632 --- /dev/null +++ b/src/xmlpatterns/acceltree/qacceltreebuilder.cpp @@ -0,0 +1,440 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/** + * @file + * @short This file is included by qacceltreebuilder_p.h. + * If you need includes in this file, put them in qacceltreebuilder_p.h, outside of the namespace. + */ + +template +AccelTreeBuilder::AccelTreeBuilder(const QUrl &docURI, + const QUrl &baseURI, + const NamePool::Ptr &np, + ReportContext *const context, + Features features) : m_preNumber(-1) + , m_isPreviousAtomic(false) + , m_hasCharacters(false) + , m_isCharactersCompressed(false) + , m_namePool(np) + , m_document(new AccelTree(docURI, baseURI)) + , m_skippedDocumentNodes(0) + , m_documentURI(docURI) + , m_context(context) + , m_features(features) +{ + Q_ASSERT(m_namePool); + + /* TODO Perhaps we can merge m_ancestors and m_size + * into one, and store a struct for the two instead? */ + m_ancestors.reserve(DefaultNodeStackSize); + m_ancestors.push(-1); + + m_size.reserve(DefaultNodeStackSize); + m_size.push(0); +} + +template +void AccelTreeBuilder::startStructure() +{ + if(m_hasCharacters) + { + /* We create a node even if m_characters is empty. + * Remember that `text {""}' creates one text node + * with string value "". */ + + ++m_preNumber; + m_document->basicData.append(AccelTree::BasicNodeData(currentDepth(), + currentParent(), + QXmlNodeModelIndex::Text, + m_isCharactersCompressed ? AccelTree::IsCompressed : 0)); + m_document->data.insert(m_preNumber, m_characters); + ++m_size.top(); + + m_characters.clear(); /* We don't want it added twice. */ + m_hasCharacters = false; + + if(m_isCharactersCompressed) + m_isCharactersCompressed = false; + } +} + +template +void AccelTreeBuilder::item(const Item &it) +{ + Q_ASSERT(it); + + if(it.isAtomicValue()) + { + if(m_isPreviousAtomic) + { + m_characters += QLatin1Char(' '); + m_characters += it.stringValue(); + } + else + { + m_isPreviousAtomic = true; + const QString sv(it.stringValue()); + + if(!sv.isEmpty()) + { + m_characters += sv; + m_hasCharacters = true; + } + } + } + else + sendAsNode(it); +} + +template +void AccelTreeBuilder::startElement(const QXmlName &name) +{ + startElement(name, 1, 1); +} + +template +void AccelTreeBuilder::startElement(const QXmlName &name, qint64 line, qint64 column) +{ + startStructure(); + + AccelTree::BasicNodeData data(currentDepth(), currentParent(), QXmlNodeModelIndex::Element, -1, name); + m_document->basicData.append(data); + if (m_features & SourceLocationsFeature) + m_document->sourcePositions.insert(m_document->maximumPreNumber(), qMakePair(line, column)); + + ++m_preNumber; + m_ancestors.push(m_preNumber); + + ++m_size.top(); + m_size.push(0); + + /* With node constructors, we can receive names for which we have no namespace + * constructors, such as in the query ''. Since the 'xs' prefix has no + * NamespaceConstructor in this case, we synthesize the namespace. + * + * In case we're constructing from an XML document we avoid the call because + * although it's redundant, it's on extra virtual call for each element. */ + if(!FromDocument) + namespaceBinding(QXmlName(name.namespaceURI(), 0, name.prefix())); + + m_isPreviousAtomic = false; +} + +template +void AccelTreeBuilder::endElement() +{ + startStructure(); + const AccelTree::PreNumber index = m_ancestors.pop(); + AccelTree::BasicNodeData &data = m_document->basicData[index]; + + /* Sub trees needs to be included in upper trees, so we add the count of this element + * to our parent. */ + m_size[m_size.count() - 2] += m_size.top(); + + data.setSize(m_size.pop()); + m_isPreviousAtomic = false; +} + +template +void AccelTreeBuilder::attribute(const QXmlName &name, const QStringRef &value) +{ + /* Attributes adds a namespace binding, so lets synthesize one. + * + * We optimize by checking whether we have a namespace for which a binding would + * be generated. Happens relatively rarely. */ + if(name.hasPrefix()) + namespaceBinding(QXmlName(name.namespaceURI(), 0, name.prefix())); + + m_document->basicData.append(AccelTree::BasicNodeData(currentDepth(), currentParent(), QXmlNodeModelIndex::Attribute, 0, name)); + ++m_preNumber; + ++m_size.top(); + + m_isPreviousAtomic = false; + + if(name.namespaceURI() == StandardNamespaces::xml && name.localName() == StandardLocalNames::id) + { + const QString normalized(value.toString().simplified()); + + if(QXmlUtils::isNCName(normalized)) + { + const QXmlName::LocalNameCode id = m_namePool->allocateLocalName(normalized); + + const int oldSize = m_document->m_IDs.count(); + m_document->m_IDs.insert(id, currentParent()); + /* We don't run the value through m_attributeCompress here, because + * the likelyhood of it deing identical to another attribute is + * very small. */ + m_document->data.insert(m_preNumber, normalized); + + /** + * In the case that we're called for doc-available(), m_context is + * null, and we need to flag somehow that we failed to load this + * document. + */ + if(oldSize == m_document->m_IDs.count() && m_context) // TODO + { + Q_ASSERT(m_context); + m_context->error(QtXmlPatterns::tr("An %1-attribute with value %2 has already been declared.") + .arg(formatKeyword("xml:id"), + formatData(normalized)), + FromDocument ? ReportContext::FODC0002 : ReportContext::XQDY0091, + this); + } + } + else if(m_context) // TODO + { + Q_ASSERT(m_context); + + /* If we're building from an XML Document(e.g, we're fed from QXmlStreamReader, we raise FODC0002, + * otherwise XQDY0091. */ + m_context->error(QtXmlPatterns::tr("An %1-attribute must have a " + "valid %2 as value, which %3 isn't.").arg(formatKeyword("xml:id"), + formatType(m_namePool, BuiltinTypes::xsNCName), + formatData(value.toString())), + FromDocument ? ReportContext::FODC0002 : ReportContext::XQDY0091, + this); + } + } + else + m_document->data.insert(m_preNumber, *m_attributeCompress.insert(value.toString())); +} + +template +void AccelTreeBuilder::characters(const QStringRef &ch) +{ + + /* If a text node constructor appears by itself, a node needs to + * be created. Therefore, we set m_hasCharacters + * if we're the only node. + * However, if the text node appears as a child of a document or element + * node it is discarded if it's empty. + */ + if(m_hasCharacters && m_isCharactersCompressed) + { + m_characters = CompressedWhitespace::decompress(m_characters); + m_isCharactersCompressed = false; + } + + m_characters += ch; + + m_isPreviousAtomic = false; + m_hasCharacters = !m_characters.isEmpty() || m_preNumber == -1; /* -1 is our start value. */ +} + +template +void AccelTreeBuilder::whitespaceOnly(const QStringRef &ch) +{ + Q_ASSERT(!ch.isEmpty()); + Q_ASSERT(ch.toString().trimmed().isEmpty()); + + /* This gets problematic due to how QXmlStreamReader works(which + * is the only one we get whitespaceOnly() events from). Namely, text intermingled + * with CDATA gets reported as individual Characters events, and + * QXmlStreamReader::isWhitespace() can return differently for each of those. However, + * it will occur very rarely, so this workaround of 1) mistakenly compressing 2) decompressing 3) + * appending, will happen infrequently. + */ + if(m_hasCharacters) + { + if(m_isCharactersCompressed) + { + m_characters = CompressedWhitespace::decompress(m_characters); + m_isCharactersCompressed = false; + } + + m_characters.append(ch.toString()); + } + else + { + /* We haven't received a text node previously. */ + m_characters = CompressedWhitespace::compress(ch); + m_isCharactersCompressed = true; + m_isPreviousAtomic = false; + m_hasCharacters = true; + } +} + +template +void AccelTreeBuilder::processingInstruction(const QXmlName &target, + const QString &data) +{ + startStructure(); + ++m_preNumber; + m_document->data.insert(m_preNumber, data); + + m_document->basicData.append(AccelTree::BasicNodeData(currentDepth(), + currentParent(), + QXmlNodeModelIndex::ProcessingInstruction, + 0, + target)); + ++m_size.top(); + m_isPreviousAtomic = false; +} + +template +void AccelTreeBuilder::comment(const QString &content) +{ + startStructure(); + m_document->basicData.append(AccelTree::BasicNodeData(currentDepth(), currentParent(), QXmlNodeModelIndex::Comment, 0)); + ++m_preNumber; + m_document->data.insert(m_preNumber, content); + ++m_size.top(); +} + +template +void AccelTreeBuilder::namespaceBinding(const QXmlName &nb) +{ + /* Note, because attribute() sometimes generate namespaceBinding() calls, this function + * can be called after attributes, in contrast to what the class documentation says. This is ok, + * as long as we're not dealing with public API. */ + + /* If we've received attributes, it means the element's size have changed and m_preNumber have advanced, + * so "reverse back" to the actual element. */ + const AccelTree::PreNumber pn = m_preNumber - m_size.top(); + + QVector &nss = m_document->namespaces[pn]; + + /* "xml" hasn't been declared for each node, AccelTree::namespaceBindings() adds it, so avoid it + * such that we don't get duplicates. */ + if(nb.prefix() == StandardPrefixes::xml) + return; + + /* If we already have the binding, skip it. */ + const int len = nss.count(); + for(int i = 0; i < len; ++i) + { + if(nss.at(i).prefix() == nb.prefix()) + return; + } + + nss.append(nb); +} + +template +void AccelTreeBuilder::startDocument() +{ + /* If we have already received nodes, we can't add a document node. */ + if(m_preNumber == -1) /* -1 is our start value. */ + { + m_size.push(0); + m_document->basicData.append(AccelTree::BasicNodeData(0, -1, QXmlNodeModelIndex::Document, -1)); + ++m_preNumber; + m_ancestors.push(m_preNumber); + } + else + ++m_skippedDocumentNodes; + + m_isPreviousAtomic = false; +} + +template +void AccelTreeBuilder::endDocument() +{ + if(m_skippedDocumentNodes == 0) + { + /* Create text nodes, if we've received any. We do this only if we're the + * top node because if we're getting this event as being a child of an element, + * text nodes or atomic values can appear after us, and which must get + * merged with the previous text. + * + * We call startStructure() before we pop the ancestor, such that the text node becomes + * a child of this document node. */ + startStructure(); + + m_document->basicData.first().setSize(m_size.pop()); + m_ancestors.pop(); + } + else + --m_skippedDocumentNodes; + + m_isPreviousAtomic = false; +} + +template +void AccelTreeBuilder::atomicValue(const QVariant &value) +{ + Q_UNUSED(value); + // TODO +} + +template +QAbstractXmlNodeModel::Ptr AccelTreeBuilder::builtDocument() +{ + /* Create a text node, if we have received text in some way. */ + startStructure(); + m_document->printStats(m_namePool); + + return m_document; +} + +template +NodeBuilder::Ptr AccelTreeBuilder::create(const QUrl &baseURI) const +{ + Q_UNUSED(baseURI); + return NodeBuilder::Ptr(new AccelTreeBuilder(QUrl(), baseURI, m_namePool, m_context)); +} + +template +void AccelTreeBuilder::startOfSequence() +{ +} + +template +void AccelTreeBuilder::endOfSequence() +{ +} + +template +const SourceLocationReflection *AccelTreeBuilder::actualReflection() const +{ + return this; +} + +template +QSourceLocation AccelTreeBuilder::sourceLocation() const +{ + if(m_documentURI.isEmpty()) + return QSourceLocation(QUrl(QLatin1String("AnonymousNodeTree"))); + else + return QSourceLocation(m_documentURI); +} + diff --git a/src/xmlpatterns/acceltree/qacceltreebuilder_p.h b/src/xmlpatterns/acceltree/qacceltreebuilder_p.h new file mode 100644 index 0000000..747099f --- /dev/null +++ b/src/xmlpatterns/acceltree/qacceltreebuilder_p.h @@ -0,0 +1,204 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_AccelTreeBuilder_H +#define Patternist_AccelTreeBuilder_H + +#include +#include + +#include "private/qxmlutils_p.h" +#include "qacceltree_p.h" +#include "qbuiltintypes_p.h" +#include "qcompressedwhitespace_p.h" +#include "qnamepool_p.h" +#include "qnodebuilder_p.h" +#include "qreportcontext_p.h" +#include "qsourcelocationreflection_p.h" +#include "qpatternistlocale_p.h" +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Builds an AccelTree from a stream of XML/Item events + * received through the NodeBuilder interface. + * + * If FromDocument is @c true, it is assumed that AccelTreeBuilder is fed + * events from an XML document, otherwise it is assumed the events + * are from node constructor expressions. + * + * @author Frans Englich + */ + template + class AccelTreeBuilder : public NodeBuilder + , public SourceLocationReflection + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Describes the memory relevant features the builder shall support. + */ + enum Feature + { + NoneFeature, ///< No special features are enabled. + SourceLocationsFeature = 1 ///< The accel tree builder will store source locations for each start element. + }; + Q_DECLARE_FLAGS(Features, Feature) + + /** + * @param context may be @c null. + */ + AccelTreeBuilder(const QUrl &docURI, + const QUrl &baseURI, + const NamePool::Ptr &np, + ReportContext *const context, + Features features = NoneFeature); + virtual void startDocument(); + virtual void endDocument(); + virtual void startElement(const QXmlName &name); + void startElement(const QXmlName &name, qint64 line, qint64 column); + virtual void endElement(); + virtual void attribute(const QXmlName &name, const QStringRef &value); + virtual void characters(const QStringRef &ch); + virtual void whitespaceOnly(const QStringRef &ch); + virtual void processingInstruction(const QXmlName &target, + const QString &data); + virtual void namespaceBinding(const QXmlName &nb); + virtual void comment(const QString &content); + virtual void item(const Item &it); + + virtual QAbstractXmlNodeModel::Ptr builtDocument(); + virtual NodeBuilder::Ptr create(const QUrl &baseURI) const; + virtual void startOfSequence(); + virtual void endOfSequence(); + + inline AccelTree::Ptr builtDocument() const + { + return m_document; + } + + virtual void atomicValue(const QVariant &value); + + virtual const SourceLocationReflection *actualReflection() const; + virtual QSourceLocation sourceLocation() const; + + private: + inline void startStructure(); + + inline AccelTree::PreNumber currentDepth() const + { + return m_ancestors.count() -1; + } + + inline AccelTree::PreNumber currentParent() const + { + return m_ancestors.isEmpty() ? -1 : m_ancestors.top(); + } + + enum Constants + { + DefaultNodeStackSize = 10, + SizeIsEmpty = 0 + }; + + AccelTree::PreNumber m_preNumber; + bool m_isPreviousAtomic; + bool m_hasCharacters; + /** + * Whether m_characters has been run through + * CompressedWhitespace::compress(). + */ + bool m_isCharactersCompressed; + QString m_characters; + NamePool::Ptr m_namePool; + AccelTree::Ptr m_document; + QStack m_ancestors; + QStack m_size; + + /** If we have already commenced a document, we don't want to + * add more document nodes. We keep track of them with this + * counter, which ensures that startDocument() and endDocument() + * are skipped consistently. */ + AccelTree::PreNumber m_skippedDocumentNodes; + + /** + * All attribute values goes through this set such that we store only + * one QString for identical attribute values. + */ + QSet m_attributeCompress; + const QUrl m_documentURI; + /** + * We don't store a reference pointer here because then we get a + * circular reference with GenericDynamicContext, when it stores us as + * a member. + */ + ReportContext *const m_context; + + Features m_features; + }; + + Q_DECLARE_OPERATORS_FOR_FLAGS(AccelTreeBuilder::Features) + Q_DECLARE_OPERATORS_FOR_FLAGS(AccelTreeBuilder::Features) + +#include "qacceltreebuilder.cpp" +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/acceltree/qacceltreeresourceloader.cpp b/src/xmlpatterns/acceltree/qacceltreeresourceloader.cpp new file mode 100644 index 0000000..4fbfb65 --- /dev/null +++ b/src/xmlpatterns/acceltree/qacceltreeresourceloader.cpp @@ -0,0 +1,441 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include + +#include + +#include "qatomicstring_p.h" +#include "qautoptr_p.h" +#include "qcommonsequencetypes_p.h" + +#include "qacceltreeresourceloader_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +AccelTreeResourceLoader::AccelTreeResourceLoader(const NamePool::Ptr &np, + const NetworkAccessDelegator::Ptr &manager, + AccelTreeBuilder::Features features) + : m_namePool(np) + , m_networkAccessDelegator(manager) + , m_features(features) +{ + Q_ASSERT(m_namePool); + Q_ASSERT(m_networkAccessDelegator); +} + +bool AccelTreeResourceLoader::retrieveDocument(const QUrl &uri, + const ReportContext::Ptr &context) +{ + Q_ASSERT(uri.isValid()); + AccelTreeBuilder builder(uri, uri, m_namePool, context.data(), m_features); + + const AutoPtr reply(load(uri, m_networkAccessDelegator, context)); + + if(!reply) + return false; + + bool success = false; + success = streamToReceiver(reply.data(), &builder, m_namePool, context, uri); + + m_loadedDocuments.insert(uri, builder.builtDocument()); + return success; +} + +bool AccelTreeResourceLoader::retrieveDocument(QIODevice *source, const QUrl &documentUri, const ReportContext::Ptr &context) +{ + Q_ASSERT(source); + Q_ASSERT(source->isReadable()); + Q_ASSERT(documentUri.isValid()); + + AccelTreeBuilder builder(documentUri, documentUri, m_namePool, context.data(), m_features); + + bool success = false; + success = streamToReceiver(source, &builder, m_namePool, context, documentUri); + + m_loadedDocuments.insert(documentUri, builder.builtDocument()); + + return success; +} + +QNetworkReply *AccelTreeResourceLoader::load(const QUrl &uri, + const NetworkAccessDelegator::Ptr &networkDelegator, + const ReportContext::Ptr &context, ErrorHandling errorHandling) +{ + return load(uri, + networkDelegator->managerFor(uri), + context, errorHandling); +} + +QNetworkReply *AccelTreeResourceLoader::load(const QUrl &uri, + QNetworkAccessManager *const networkManager, + const ReportContext::Ptr &context, ErrorHandling errorHandling) + +{ + Q_ASSERT(networkManager); + Q_ASSERT(uri.isValid()); + + NetworkLoop networkLoop; + + QNetworkRequest request(uri); + QNetworkReply *const reply = networkManager->get(request); + networkLoop.connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(error(QNetworkReply::NetworkError))); + networkLoop.connect(reply, SIGNAL(finished()), SLOT(finished())); + + if(networkLoop.exec(QEventLoop::ExcludeUserInputEvents)) + { + const QString errorMessage(escape(reply->errorString())); + + /* Note, we delete reply before we exit this function with error(). */ + delete reply; + + const QSourceLocation location(uri); + + if(context && (errorHandling == FailOnError)) + context->error(errorMessage, ReportContext::FODC0002, location); + + return 0; + } + else + return reply; +} + +bool AccelTreeResourceLoader::streamToReceiver(QIODevice *const dev, + AccelTreeBuilder *const receiver, + const NamePool::Ptr &np, + const ReportContext::Ptr &context, + const QUrl &uri) +{ + Q_ASSERT(dev); + Q_ASSERT(receiver); + Q_ASSERT(np); + + QXmlStreamReader reader(dev); + + /* Optimize: change NamePool to take QStringRef such that we don't have to call toString() below. That + * will save us a gazillion of temporary QStrings. */ + + while(!reader.atEnd()) + { + reader.readNext(); + + switch(reader.tokenType()) + { + case QXmlStreamReader::StartElement: + { + /* Send the name. */ + receiver->startElement(np->allocateQName(reader.namespaceUri().toString(), reader.name().toString(), + reader.prefix().toString()), reader.lineNumber(), reader.columnNumber()); + + /* Send namespace declarations. */ + const QXmlStreamNamespaceDeclarations &nss = reader.namespaceDeclarations(); + + /* The far most common case, is for it to be empty. */ + if(!nss.isEmpty()) + { + const int len = nss.size(); + + for(int i = 0; i < len; ++i) + { + const QXmlStreamNamespaceDeclaration &ns = nss.at(i); + receiver->namespaceBinding(np->allocateBinding(ns.prefix().toString(), ns.namespaceUri().toString())); + } + } + + /* Send attributes. */ + const QXmlStreamAttributes &attrs = reader.attributes(); + const int len = attrs.size(); + + for(int i = 0; i < len; ++i) + { + const QXmlStreamAttribute &attr = attrs.at(i); + + receiver->attribute(np->allocateQName(attr.namespaceUri().toString(), attr.name().toString(), + attr.prefix().toString()), + attr.value()); + } + + continue; + } + case QXmlStreamReader::EndElement: + { + receiver->endElement(); + continue; + } + case QXmlStreamReader::Characters: + { + if(reader.isWhitespace()) + receiver->whitespaceOnly(reader.text()); + else + receiver->characters(reader.text()); + + continue; + } + case QXmlStreamReader::Comment: + { + receiver->comment(reader.text().toString()); + continue; + } + case QXmlStreamReader::ProcessingInstruction: + { + receiver->processingInstruction(np->allocateQName(QString(), reader.processingInstructionTarget().toString()), + reader.processingInstructionData().toString()); + continue; + } + case QXmlStreamReader::StartDocument: + { + receiver->startDocument(); + continue; + } + case QXmlStreamReader::EndDocument: + { + receiver->endDocument(); + continue; + } + case QXmlStreamReader::EntityReference: + /* Fallthrough. */ + case QXmlStreamReader::DTD: + { + /* We just ignore any DTD and entity references. */ + continue; + } + case QXmlStreamReader::Invalid: + { + if(context) + context->error(escape(reader.errorString()), ReportContext::FODC0002, QSourceLocation(uri, reader.lineNumber(), reader.columnNumber())); + + return false; + } + case QXmlStreamReader::NoToken: + { + Q_ASSERT_X(false, Q_FUNC_INFO, + "This token is never expected to be received."); + return false; + } + } + } + + return true; +} + +Item AccelTreeResourceLoader::openDocument(const QUrl &uri, + const ReportContext::Ptr &context) +{ + const AccelTree::Ptr doc(m_loadedDocuments.value(uri)); + + if(doc) + return doc->root(QXmlNodeModelIndex()); /* Pass in dummy object. We know AccelTree doesn't use it. */ + else + { + if(retrieveDocument(uri, context)) + return m_loadedDocuments.value(uri)->root(QXmlNodeModelIndex()); /* Pass in dummy object. We know AccelTree doesn't use it. */ + else + return Item(); + } +} + +Item AccelTreeResourceLoader::openDocument(QIODevice *source, const QUrl &documentUri, + const ReportContext::Ptr &context) +{ + const AccelTree::Ptr doc(m_loadedDocuments.value(documentUri)); + + if(doc) + return doc->root(QXmlNodeModelIndex()); /* Pass in dummy object. We know AccelTree doesn't use it. */ + else + { + if(retrieveDocument(source, documentUri, context)) + return m_loadedDocuments.value(documentUri)->root(QXmlNodeModelIndex()); /* Pass in dummy object. We know AccelTree doesn't use it. */ + else + return Item(); + } +} + +SequenceType::Ptr AccelTreeResourceLoader::announceDocument(const QUrl &uri, const Usage) +{ + // TODO deal with the usage thingy + Q_ASSERT(uri.isValid()); + Q_ASSERT(!uri.isRelative()); + Q_UNUSED(uri); /* Needed when compiling in release mode. */ + + return CommonSequenceTypes::ZeroOrOneDocumentNode; +} + +bool AccelTreeResourceLoader::isDocumentAvailable(const QUrl &uri) +{ + return retrieveDocument(uri, ReportContext::Ptr()); +} + +static inline uint qHash(const QPair &desc) +{ + /* Probably a lousy hash. */ + return qHash(desc.first) + qHash(desc.second); +} + +bool AccelTreeResourceLoader::retrieveUnparsedText(const QUrl &uri, + const QString &encoding, + const ReportContext::Ptr &context, + const SourceLocationReflection *const where) +{ + const AutoPtr reply(load(uri, m_networkAccessDelegator, context)); + + if(!reply) + return false; + + const QTextCodec * codec; + if(encoding.isEmpty()) + { + /* XSL Transformations (XSLT) Version 2.0 16.2 Reading Text Files: + * + * "if the media type of the resource is text/xml or application/xml + * (see [RFC2376]), or if it matches the conventions text/\*+xml or + * application/\*+xml (see [RFC3023] and/or its successors), then the + * encoding is recognized as specified in [XML 1.0]" + */ + codec = QTextCodec::codecForMib(106); + } + else + { + codec = QTextCodec::codecForName(encoding.toLatin1()); + if(codec && context) + { + context->error(QtXmlPatterns::tr("%1 is an unsupported encoding.").arg(formatURI(encoding)), + ReportContext::XTDE1190, + where); + } + else + return false; + } + + QTextCodec::ConverterState converterState; + const QByteArray inData(reply->readAll()); + const QString result(codec->toUnicode(inData.constData(), inData.length(), &converterState)); + + if(converterState.invalidChars) + { + if(context) + { + context->error(QtXmlPatterns::tr("%1 contains octets which are disallowed in " + "the requested encoding %2.").arg(formatURI(uri), + formatURI(encoding)), + ReportContext::XTDE1190, + where); + } + else + return false; + } + + const int len = result.length(); + /* This code is a candidate for threading. Divide and conqueror. */ + for(int i = 0; i < len; ++i) + { + if(!QXmlUtils::isChar(result.at(i))) + { + if(context) + { + context->error(QtXmlPatterns::tr("The codepoint %1, occurring in %2 using encoding %3, " + "is an invalid XML character.").arg(formatData(result.at(i)), + formatURI(uri), + formatURI(encoding)), + ReportContext::XTDE1190, + where); + } + else + return false; + } + } + + m_unparsedTexts.insert(qMakePair(uri, encoding), result); + return true; +} + +bool AccelTreeResourceLoader::isUnparsedTextAvailable(const QUrl &uri, + const QString &encoding) +{ + return retrieveUnparsedText(uri, encoding, ReportContext::Ptr(), 0); +} + +Item AccelTreeResourceLoader::openUnparsedText(const QUrl &uri, + const QString &encoding, + const ReportContext::Ptr &context, + const SourceLocationReflection *const where) +{ + const QString &text = m_unparsedTexts.value(qMakePair(uri, encoding)); + + if(text.isNull()) + { + if(retrieveUnparsedText(uri, encoding, context, where)) + return openUnparsedText(uri, encoding, context, where); + else + return Item(); + } + else + return AtomicString::fromValue(text); +} + +QSet AccelTreeResourceLoader::deviceURIs() const +{ + QHash::const_iterator it(m_loadedDocuments.constBegin()); + const QHash::const_iterator end(m_loadedDocuments.constEnd()); + QSet retval; + + while (it != end) + { + if(it.key().toString().startsWith(QLatin1String("tag:trolltech.com,2007:QtXmlPatterns:QIODeviceVariable:"))) + retval.insert(it.key()); + + ++it; + } + + return retval; +} + +void AccelTreeResourceLoader::clear(const QUrl &uri) +{ + m_loadedDocuments.remove(uri); +} + +QT_END_NAMESPACE + diff --git a/src/xmlpatterns/acceltree/qacceltreeresourceloader_p.h b/src/xmlpatterns/acceltree/qacceltreeresourceloader_p.h new file mode 100644 index 0000000..3768ebe --- /dev/null +++ b/src/xmlpatterns/acceltree/qacceltreeresourceloader_p.h @@ -0,0 +1,210 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_AccelTreeResourceLoader_H +#define Patternist_AccelTreeResourceLoader_H + +#include +#include + +#include "qabstractxmlreceiver.h" +#include "qacceltree_p.h" +#include "qacceltreebuilder_p.h" +#include "qdeviceresourceloader_p.h" +#include "qnamepool_p.h" +#include "qnetworkaccessdelegator_p.h" +#include "qreportcontext_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QIODevice; + +namespace QPatternist +{ + /** + * @short An helper class which enables QNetworkAccessManager + * to be used in a blocking manner. + * + * @see AccelTreeResourceLoader::load() + * @author Frans Englich + */ + class NetworkLoop : public QEventLoop + { + Q_OBJECT + public: + NetworkLoop() : m_hasReceivedError(false) + { + } + + public Q_SLOTS: + void error(QNetworkReply::NetworkError code) + { + Q_UNUSED(code); + m_hasReceivedError = true; + exit(1); + } + + void finished() + { + if(m_hasReceivedError) + exit(1); + else + exit(0); + } + private: + bool m_hasReceivedError; + }; + + /** + * @short Handles requests for documents, and instantiates + * them as AccelTree instances. + * + * @author Frans Englich + */ + class Q_AUTOTEST_EXPORT AccelTreeResourceLoader : public DeviceResourceLoader + { + public: + /** + * Describes the behaviour of the resource loader in case of an + * error. + */ + enum ErrorHandling + { + FailOnError, ///< The resource loader will report the error via the report context. + ContinueOnError ///< The resource loader will report no error and return an empty QNetworkReply. + }; + + /** + * AccelTreeResourceLoader does not own @p context. + */ + AccelTreeResourceLoader(const NamePool::Ptr &np, + const NetworkAccessDelegator::Ptr &networkDelegator, AccelTreeBuilder::Features = AccelTreeBuilder::NoneFeature); + + virtual Item openDocument(const QUrl &uri, + const ReportContext::Ptr &context); + virtual Item openDocument(QIODevice *source, const QUrl &documentUri, + const ReportContext::Ptr &context); + virtual SequenceType::Ptr announceDocument(const QUrl &uri, const Usage usageHint); + virtual bool isDocumentAvailable(const QUrl &uri); + + virtual bool isUnparsedTextAvailable(const QUrl &uri, + const QString &encoding); + + virtual Item openUnparsedText(const QUrl &uri, + const QString &encoding, + const ReportContext::Ptr &context, + const SourceLocationReflection *const where); + + /** + * @short Helper function that do NetworkAccessDelegator::get(), but + * does it blocked. + * + * The returned QNetworkReply has emitted QNetworkReply::finished(). + * + * The caller owns the return QIODevice instance. + * + * @p context may be @c null or valid. If @c null, no error reporting + * is done and @c null is returned. + * + * @see NetworkAccessDelegator + */ + static QNetworkReply *load(const QUrl &uri, + QNetworkAccessManager *const networkManager, + const ReportContext::Ptr &context, ErrorHandling handling = FailOnError); + + /** + * @overload + */ + static QNetworkReply *load(const QUrl &uri, + const NetworkAccessDelegator::Ptr &networkDelegator, + const ReportContext::Ptr &context, ErrorHandling handling = FailOnError); + + /** + * @short Returns the URIs this AccelTreeResourceLoader has loaded + * which are for devices through variable bindings. + */ + virtual QSet deviceURIs() const; + + virtual void clear(const QUrl &uri); + + private: + static bool streamToReceiver(QIODevice *const dev, + AccelTreeBuilder *const receiver, + const NamePool::Ptr &np, + const ReportContext::Ptr &context, + const QUrl &uri); + bool retrieveDocument(const QUrl &uri, + const ReportContext::Ptr &context); + bool retrieveDocument(QIODevice *source, const QUrl &documentUri, + const ReportContext::Ptr &context); + /** + * If @p context is @c null, no error reporting should be done. + */ + bool retrieveUnparsedText(const QUrl &uri, + const QString &encoding, + const ReportContext::Ptr &context, + const SourceLocationReflection *const where); + + QHash m_loadedDocuments; + const NamePool::Ptr m_namePool; + const NetworkAccessDelegator::Ptr m_networkAccessDelegator; + QHash, QString> m_unparsedTexts; + AccelTreeBuilder::Features m_features; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/acceltree/qcompressedwhitespace.cpp b/src/xmlpatterns/acceltree/qcompressedwhitespace.cpp new file mode 100644 index 0000000..16c116c --- /dev/null +++ b/src/xmlpatterns/acceltree/qcompressedwhitespace.cpp @@ -0,0 +1,197 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qcompressedwhitespace_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +CompressedWhitespace::CharIdentifier CompressedWhitespace::toIdentifier(const QChar ch) +{ + switch(ch.unicode()) + { + case ' ': + return Space; + case '\n': + return LF; + case '\r': + return CR; + case '\t': + return Tab; + default: + { + Q_ASSERT_X(false, Q_FUNC_INFO, + "The caller must guarantee only whitespace is passed."); + return Tab; + } + } +} + +bool CompressedWhitespace::isEven(const int number) +{ + Q_ASSERT(number >= 0); + return number % 2 == 0; +} + +quint8 CompressedWhitespace::toCompressedChar(const QChar ch, const int len) +{ + Q_ASSERT(len > 0); + Q_ASSERT(len <= MaxCharCount); + + return len + toIdentifier(ch); +} + +QChar CompressedWhitespace::toChar(const CharIdentifier id) +{ + switch(id) + { + case Space: return QLatin1Char(' '); + case CR: return QLatin1Char('\r'); + case LF: return QLatin1Char('\n'); + case Tab: return QLatin1Char('\t'); + default: + { + Q_ASSERT_X(false, Q_FUNC_INFO, "Unexpected input"); + return QChar(); + } + } +} + +QString CompressedWhitespace::compress(const QStringRef &input) +{ + Q_ASSERT(!isEven(1) && isEven(0) && isEven(2)); + Q_ASSERT(!input.isEmpty()); + + QString result; + const int len = input.length(); + + /* The amount of compressed characters. For instance, if input is + * four spaces followed by one tab, compressedChars will be 2, and the resulting + * QString will have a length of 1, two compressedChars stored in one QChar. */ + int compressedChars = 0; + + for(int i = 0; i < len; ++i) + { + const QChar c(input.at(i)); + + int start = i; + + while(true) + { + if(i + 1 == input.length() || input.at(i + 1) != c) + break; + else + ++i; + } + + /* The length of subsequent whitespace characters in the input. */ + int wsLen = (i - start) + 1; + + /* We might get a sequence of whitespace that is so long, that we can't + * store it in one unit/byte. In that case we chop it into as many subsequent + * ones that is needed. */ + while(true) + { + const int unitLength = qMin(wsLen, int(MaxCharCount)); + wsLen -= unitLength; + + ushort resultCP = toCompressedChar(c, unitLength); + + if(isEven(compressedChars)) + result += QChar(resultCP); + else + { + resultCP = resultCP << 8; + resultCP |= result.at(result.size() - 1).unicode(); + result[result.size() - 1] = resultCP; + } + + ++compressedChars; + + if(wsLen == 0) + break; + } + } + + return result; +} + +QString CompressedWhitespace::decompress(const QString &input) +{ + Q_ASSERT(!input.isEmpty()); + const int len = input.length() * 2; + QString retval; + + for(int i = 0; i < len; ++i) + { + ushort cp = input.at(i / 2).unicode(); + + if(isEven(i)) + cp &= Lower8Bits; + else + { + cp = cp >> 8; + + if(cp == 0) + return retval; + } + + const quint8 wsLen = cp & Lower6Bits; + const quint8 id = cp & UpperTwoBits; + + /* Resize retval, and fill in on the top. */ + const int oldSize = retval.size(); + const int newSize = retval.size() + wsLen; + retval.resize(newSize); + const QChar ch(toChar(CharIdentifier(id))); + + for(int f = oldSize; f < newSize; ++f) + retval[f] = ch; + } + + return retval; +} + +QT_END_NAMESPACE + diff --git a/src/xmlpatterns/acceltree/qcompressedwhitespace_p.h b/src/xmlpatterns/acceltree/qcompressedwhitespace_p.h new file mode 100644 index 0000000..859811d --- /dev/null +++ b/src/xmlpatterns/acceltree/qcompressedwhitespace_p.h @@ -0,0 +1,186 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_CompressedWhitespace_H +#define Patternist_CompressedWhitespace_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QChar; +class QString; +class QStringRef; + +namespace QPatternist +{ + /** + * @short A compression facility for whitespace nodes. + * + * CompressedWhitespace compresses and decompresses strings that consists of + * whitespace only, and do so with a scheme that is designed to do this + * specialized task in an efficient way. The approach is simple: each + * sequence of equal whitespace in the input gets coded into one byte, + * where the first two bits signals the type, CharIdentifier, and the + * remininding six bits is the count. + * + * For instance, this scheme manages to compress a sequence of spaces + * followed by a new line into 16 bits(one QChar), and QString stores + * strings of one QChar quite efficiently, by avoiding a heap allocation. + * + * There is no way to tell whether a QString is compressed or not. + * + * The compression scheme originates from Saxon, by Michael Kay. + * + * @author Frans Englich + */ + class Q_AUTOTEST_EXPORT CompressedWhitespace + { + public: + /** + * @short Compresses @p input into a compressed format, returned + * as a QString. + * + * The caller guarantees that input is not empty + * and consists only of whitespace. + * + * The returned format is opaque. There is no way to find out + * whether a QString contains compressed data or not. + * + * @see decompress() + */ + static QString compress(const QStringRef &input); + + /** + * @short Decompresses @p input into a usual QString. + * + * @p input must be a QString as per returned from compress(). + * + * @see compress() + */ + static QString decompress(const QString &input); + + private: + /** + * We use the two upper bits for communicating what space it is. + */ + enum CharIdentifier + { + Space = 0x0, + + /** + * 0xA, \\r + * + * Binary: 10000000 + */ + CR = 0x80, + + /** + * 0xD, \\n + * + * Binary: 01000000 + */ + LF = 0x40, + + /** + * Binary: 11000000 + */ + Tab = 0xC0 + }; + + enum Constants + { + /* We can at maximum store this many consecutive characters + * of one type. We use 6 bits for the count. */ + MaxCharCount = (1 << 6) - 1, + + /** + * Binary: 11111111 + */ + Lower8Bits = (1 << 8) - 1, + + /** + * Binary: 111111 + */ + Lower6Bits = (1 << 6) - 1, + + /* + * Binary: 11000000 + */ + UpperTwoBits = 3 << 6 + }; + + static inline CharIdentifier toIdentifier(const QChar ch); + + static inline quint8 toCompressedChar(const QChar ch, const int len); + static inline QChar toChar(const CharIdentifier id); + + /** + * @short Returns @c true if @p number is an even number, otherwise + * @c false. + */ + static inline bool isEven(const int number); + + /** + * @short This class can only be used via its static members. + */ + inline CompressedWhitespace(); + Q_DISABLE_COPY(CompressedWhitespace) + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/api.pri b/src/xmlpatterns/api/api.pri new file mode 100644 index 0000000..a0adf75 --- /dev/null +++ b/src/xmlpatterns/api/api.pri @@ -0,0 +1,57 @@ +HEADERS += $$PWD/qabstractxmlforwarditerator_p.h \ + $$PWD/qabstractmessagehandler.h \ + $$PWD/qabstracturiresolver.h \ + $$PWD/qabstractxmlnodemodel.h \ + $$PWD/qabstractxmlnodemodel_p.h \ + $$PWD/qabstractxmlpullprovider_p.h \ + $$PWD/qabstractxmlreceiver.h \ + $$PWD/qabstractxmlreceiver_p.h \ + $$PWD/qdeviceresourceloader_p.h \ + $$PWD/qiodevicedelegate_p.h \ + $$PWD/qnetworkaccessdelegator_p.h \ + $$PWD/qpullbridge_p.h \ + $$PWD/qresourcedelegator_p.h \ + $$PWD/qsimplexmlnodemodel.h \ + $$PWD/qsourcelocation.h \ + $$PWD/quriloader_p.h \ + $$PWD/qvariableloader_p.h \ + $$PWD/qxmlformatter.h \ + $$PWD/qxmlname.h \ + $$PWD/qxmlnamepool.h \ + $$PWD/qxmlquery.h \ + $$PWD/qxmlquery_p.h \ + $$PWD/qxmlresultitems.h \ + $$PWD/qxmlresultitems_p.h \ + $$PWD/qxmlschema.h \ + $$PWD/qxmlschema_p.h \ + $$PWD/qxmlschemavalidator.h \ + $$PWD/qxmlschemavalidator_p.h \ + $$PWD/qxmlserializer.h \ + $$PWD/qxmlserializer_p.h \ + $$PWD/qcoloringmessagehandler_p.h \ + $$PWD/qcoloroutput_p.h \ + $$PWD/qxmlpatternistcli_p.h +SOURCES += $$PWD/qvariableloader.cpp \ + $$PWD/qabstractmessagehandler.cpp \ + $$PWD/qabstracturiresolver.cpp \ + $$PWD/qabstractxmlnodemodel.cpp \ + $$PWD/qabstractxmlpullprovider.cpp \ + $$PWD/qabstractxmlreceiver.cpp \ + $$PWD/qiodevicedelegate.cpp \ + $$PWD/qnetworkaccessdelegator.cpp \ + $$PWD/qpullbridge.cpp \ + $$PWD/qresourcedelegator.cpp \ + $$PWD/qsimplexmlnodemodel.cpp \ + $$PWD/qsourcelocation.cpp \ + $$PWD/quriloader.cpp \ + $$PWD/qxmlformatter.cpp \ + $$PWD/qxmlname.cpp \ + $$PWD/qxmlnamepool.cpp \ + $$PWD/qxmlquery.cpp \ + $$PWD/qxmlresultitems.cpp \ + $$PWD/qxmlschema.cpp \ + $$PWD/qxmlschema_p.cpp \ + $$PWD/qxmlschemavalidator.cpp \ + $$PWD/qxmlserializer.cpp \ + $$PWD/qcoloringmessagehandler.cpp \ + $$PWD/qcoloroutput.cpp diff --git a/src/xmlpatterns/api/qabstractmessagehandler.cpp b/src/xmlpatterns/api/qabstractmessagehandler.cpp new file mode 100644 index 0000000..63a963b --- /dev/null +++ b/src/xmlpatterns/api/qabstractmessagehandler.cpp @@ -0,0 +1,149 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "private/qobject_p.h" +#include "qabstractmessagehandler.h" + +QT_BEGIN_NAMESPACE + +class QAbstractMessageHandlerPrivate : public QObjectPrivate +{ +public: + QMutex mutex; +}; + +/*! + \class QAbstractMessageHandler + \threadsafe + \since 4.4 + \ingroup xml-tools + + \brief The QAbstractMessageHandler class provides a callback interface for handling messages. + + QAbstractMessageHandler is an abstract base class that provides a + callback interface for handling messages. For example, class + QXmlQuery parses and runs an XQuery. When it detects a compile + or runtime error, it generates an appropriate error message, + but rather than output the message itself, it passes the message to + the message() function of its QAbstractMessageHandler. + See QXmlQuery::setMessageHandler(). + + You create a message handler by subclassing QAbstractMessageHandler + and implementing handleMessage(). You then pass a pointer to an + instance of your subclass to any classes that must generate + messages. The messages are sent to the message handler via the + message() function, which forwards them to your handleMessge(). + The effect is to serialize the handling of all messages, which + means your QAbstractMessageHandler subclass is thread safe. + + A single instance of QAbstractMessageHandler can be called on to + handle messages from multiple sources. Hence, the content of a + message, which is the \e description parameter passed to message() + and handleMessage(), must be interpreted in light of the context + that required the message to be sent. That context is specified by + the \e identifier and \e sourceLocation parameters to message() + handleMessage(). + */ + +/*! + Constructs a QAbstractMessageHandler. The \a parent is passed + to the QObject base class constructor. + */ +QAbstractMessageHandler::QAbstractMessageHandler(QObject *parent) : QObject(*new QAbstractMessageHandlerPrivate(), parent) +{ +} + +/*! + Destructs this QAbstractMessageHandler. + */ +QAbstractMessageHandler::~QAbstractMessageHandler() +{ +} + +/*! + Sends a message to this message handler. \a type is the kind of + message being sent. \a description is the message content. The \a + identifier is a URI that identifies the message and is the key to + interpreting the other arguments. + + Typically, this class is used for reporting errors, as is the case + for QXmlQuery, which uses a QAbstractMessageHandler to report + compile and runtime XQuery errors. Hence, using a QUrl as the + message \a identifier is was inspired by the explanation of \l{error + handling in the XQuery language}. Because the \a identifier is + composed of a namespace URI and a local part, identifiers with the + same local part are unique. The caller is responsible for ensuring + that \a identifier is either a valid QUrl or a default constructed + QUrl. + + \a sourceLocation identifies a location in a resource (i.e., file or + document) where the need for reporting a message was detected. + + This function unconditionally calls handleMessage(), passing all + its parameters unmodified. + + \sa {http://www.w3.org/TR/xquery/#errors} + */ +void QAbstractMessageHandler::message(QtMsgType type, + const QString &description, + const QUrl &identifier, + const QSourceLocation &sourceLocation) +{ + Q_D(QAbstractMessageHandler); + QMutexLocker(&d->mutex); + handleMessage(type, description, identifier, sourceLocation); +} + +/*! + \fn void QAbstractMessageHandler::handleMessage(QtMsgType type, + const QString &description, + const QUrl &identifier = QUrl(), + const QSourceLocation &sourceLocation = QSourceLocation()) = 0 + + This function must be implemented by the sub-class. message() will + call this function, passing in its parameters, \a type, + \a description, \a identifier and \a sourceLocation unmodified. + */ + +QT_END_NAMESPACE + diff --git a/src/xmlpatterns/api/qabstractmessagehandler.h b/src/xmlpatterns/api/qabstractmessagehandler.h new file mode 100644 index 0000000..a5fe0ff --- /dev/null +++ b/src/xmlpatterns/api/qabstractmessagehandler.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QABSTRACTMESSAGEHANDLER_H +#define QABSTRACTMESSAGEHANDLER_H + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(XmlPatterns) + +class QAbstractMessageHandlerPrivate; +class Q_XMLPATTERNS_EXPORT QAbstractMessageHandler : public QObject +{ + Q_OBJECT +public: + QAbstractMessageHandler(QObject *parent = 0); + virtual ~QAbstractMessageHandler(); + + void message(QtMsgType type, + const QString &description, + const QUrl &identifier = QUrl(), + const QSourceLocation &sourceLocation = QSourceLocation()); + +protected: + virtual void handleMessage(QtMsgType type, + const QString &description, + const QUrl &identifier, + const QSourceLocation &sourceLocation) = 0; +private: + Q_DECLARE_PRIVATE(QAbstractMessageHandler) + Q_DISABLE_COPY(QAbstractMessageHandler) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qabstracturiresolver.cpp b/src/xmlpatterns/api/qabstracturiresolver.cpp new file mode 100644 index 0000000..baa65b3 --- /dev/null +++ b/src/xmlpatterns/api/qabstracturiresolver.cpp @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qabstracturiresolver.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QAbstractUriResolver + \brief The QAbstractUriResolver class is a callback interface for resolving Uniform Resource Identifiers. + \since 4.4 + \reentrant + \ingroup xml-tools + + A Uniform Resource Identifier (URI) is a string that uniquely + identifies a resource. URIs are versatile global identifiers. It is + often useful to transform a URI that identifies something logical + into a URI that locates something physical (a URL), or to simply map + a URI to a different URI. QAbstractUriResolver::resolve() provides + this functionality. + + For example, one could write a QAbstractUriResolver subclass that + rewrites library ISBN number URIs as book title URLs, e.g., + \e{urn:isbn:0-345-33973-8} would be rewritten as + \e{file:///books/returnOfTheKing.doc}. Or a QAbstractUriResolver + subclass could be written for a web browser to let the web browser + protect the user's private files by mapping incoming requests for + them to null URIs. + + \sa {http://en.wikipedia.org/wiki/Uniform_Resource_Identifier} +*/ + +/*! + Constructs a QAbstractUriResolver with the specified \a parent. + */ +QAbstractUriResolver::QAbstractUriResolver(QObject *parent) : QObject(parent) +{ +} + +/*! + Destructor. + */ +QAbstractUriResolver::~QAbstractUriResolver() +{ +} + +/*! + \fn QUrl QAbstractUriResolver::resolve(const QUrl &relative, const QUrl &baseURI) const + + Returns the \a relative URI resolved using the \a baseURI. + + The caller guarantees that both \a relative and \a baseURI are + valid, and that \a baseURI is absolute. \a relative can be relative, + absolute, or empty. + + The returned QUrl can be a default constructed QUrl. If it is not a + default constructed QUrl, it will be absolute and valid. If a default + constructed QUrl is returned, it means the \a relative URI was not + accepted to be resolved. + + If the reimplemented resolve() function decides it has nothing to do + about resolving the \a relative URI, it should simply return the \a + relative URI resolved against the \a baseURI, i.e.: + + \snippet doc/src/snippets/code/src_xmlpatterns_api_qabstracturiresolver.cpp 0 + + \sa QUrl::isRelative(), QUrl::isValid() + */ + +QT_END_NAMESPACE + diff --git a/src/xmlpatterns/api/qabstracturiresolver.h b/src/xmlpatterns/api/qabstracturiresolver.h new file mode 100644 index 0000000..bbe4a90 --- /dev/null +++ b/src/xmlpatterns/api/qabstracturiresolver.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QABSTRACTURIRESOLVER_H +#define QABSTRACTURIRESOLVER_H + +#include + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +QT_MODULE(XmlPatterns) + +class QUrl; +class QAbstractUriResolverPrivate; + +class Q_XMLPATTERNS_EXPORT QAbstractUriResolver : public QObject +{ + Q_OBJECT +public: + QAbstractUriResolver(QObject *parent = 0); + virtual ~QAbstractUriResolver(); + + virtual QUrl resolve(const QUrl &relative, + const QUrl &baseURI) const = 0; + +private: + Q_DISABLE_COPY(QAbstractUriResolver) + Q_DECLARE_PRIVATE(QAbstractUriResolver) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qabstractxmlforwarditerator.cpp b/src/xmlpatterns/api/qabstractxmlforwarditerator.cpp new file mode 100644 index 0000000..046b9e4 --- /dev/null +++ b/src/xmlpatterns/api/qabstractxmlforwarditerator.cpp @@ -0,0 +1,269 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \class QAbstractXmlForwardIterator + \brief The QAbstractXmlForwardIterator class is a base class for forward iterators. + \reentrant + \since 4.4 + \ingroup xml-tools + \internal + + This abstract base class is for creating iterators for + traversing custom data structures modeled to look like XML. + An item can be instantiated in QAbstractXmlForwardIterator if: + \list + + \o It has a default constructor, a copy constructor, and an + assignment operator, and + + \o It has an appropriate qIsForwardIteratorEnd() function. + \endlist + + @ingroup Patternist_iterators + @author Frans Englich + */ + +/*! + \typedef QAbstractXmlForwardIterator::Ptr + + A smart pointer wrapping an instance of a QAbstractXmlForwardIterator subclass. + */ + +/*! + \typedef QAbstractXmlForwardIterator::List + A QList containing QAbstractXmlForwardIterator::Ptr instances. + */ + +/*! + \typedef QAbstractXmlForwardIterator::Vector + A QVector containing QAbstractXmlForwardIterator::Ptr instances. + */ + +/*! + \fn QAbstractXmlForwardIterator::QAbstractXmlForwardIterator() + + Default constructor. + */ + +/*! + \fn QAbstractXmlForwardIterator::~QAbstractXmlForwardIterator() + + Destructor. + */ + +/*! + \fn T QAbstractXmlForwardIterator::next() = 0; + + Returns the next item in the sequence, or + a null object if the end has been reached. + */ + +/*! + \fn T QAbstractXmlForwardIterator::current() const = 0; + + Returns the current item in the sequence. If this function is called + before the first call to next(), a null object is returned. If the + end of the sequence has been reached, a null object is returned. + */ + +/*! + \fn qint64 QAbstractXmlForwardIterator::position() const = 0; + + Returns the current position in the sequence represented + by \e this. + + The first position is 1, not 0. If next() hasn't been called, 0 is + returned. If \e this has reached the end, -1 is returned. + */ + +/*! + \fn bool qIsForwardIteratorEnd(const T &unit) + \since 4.4 + \relates QAbstractXmlForwardIterator + + The Callback QAbstractXmlForwardIterator uses for determining + whether \a unit is the end of a sequence. + + If \a unit is a value that would signal the end of a sequence + (typically a default constructed value), this function returns \c + true, otherwise \c false. + + This implementation works for any type that has a boolean operator. + For example, this function should work satisfactory for pointers. + */ + +/*! + \fn qint64 QAbstractXmlForwardIterator::count() + \internal + + Determines the number of items this QAbstractXmlForwardIterator + represents. + + Note that this function is not \c const. It modifies the + QAbstractXmlForwardIterator. The reason for this is efficiency. If + this QAbstractXmlForwardIterator must not be changed, get a copy() + before performing the count. + + The default implementation simply calls next() until the end is + reached. Hence, it may be of interest to override this function if + the sub-class knows a better way of computing its count. + + The number of items in the sequence is returned. + */ + +/*! + \fn QAbstractXmlForwardIterator::Ptr QAbstractXmlForwardIterator::toReversed(); + \internal + + Returns a reverse iterator for the sequence. + + This function may modify the iterator, it can be considered a + function that evaluates this QAbstractXmlForwardIterator. It is not + a \e getter, but potentially alters the iterator in the same way the + next() function does. If this QAbstractXmlForwardIterator must not + be modified, such that it can be used for evaluation with next(), + use a copy(). + */ + +/*! + \fn QList QAbstractXmlForwardIterator::toList(); + \internal + + Performs a copy of this QAbstractXmlForwardIterator(with copy()), + and returns its items in a QList. Thus, this function acts as a + conversion function, converting the sequence to a QList. + + This function may modify the iterator. It is not a \e getter, but + potentially alters the iterator in the same way the next() function + does. If this QAbstractXmlForwardIterator must not be modified, + such that it can be used for evaluation with next(), use a copy(). + */ + +/*! + \fn T QAbstractXmlForwardIterator::last(); + \internal + + Returns the item at the end of this QAbstractXmlForwardIterator. + The default implementation calls next() until the end is reached. + */ + +/*! + \fn T QAbstractXmlForwardIterator::isEmpty(); + \internal + Returns true if the sequence is empty. + */ + +/*! + \fn qint64 QAbstractXmlForwardIterator::sizeHint() const; + \internal + + Gives a hint to the size of the contained sequence. The hint is + assumed to be as close as possible to the actual size. + + If no sensible estimate can be computed, -1 should be returned. + */ + +/*! + \fn typename QAbstractXmlForwardIterator::Ptr QAbstractXmlForwardIterator::copy() const; + \internal + + Copies this QAbstractXmlForwardIterator and returns the copy. + + A copy and the original instance are completely independent of each + other. Because evaluating an QAbstractXmlForwardIterator modifies + it, one should always use a copy when an + QAbstractXmlForwardIterator needs to be used several times. + */ + +/*! + \class QPatternist::ListIteratorPlatform + \brief Helper class for ListIterator, and should only be instantiated through sub-classing. + \reentrant + \since 4.4 + \internal + \ingroup xml-tools + + ListIteratorPlatform iterates an InputList with instances + of InputType. For every item in it, it returns an item from it, + that is converted to OutputType by calling a function on Derived + that has the following signature: + + \snippet doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlforwarditerator.cpp 0 + + TODO Document why this class doesn't duplicate ItemMappingIterator. + */ + +/*! + \fn QPatternist::ListIteratorPlatform::ListIteratorPlatform(const ListType &list); + + Constructs a ListIteratorPlatform that walks the given \a list. + */ + +/*! + \class QPatternist::ListIterator + \brief Bridges values in Qt's QList container class into an QAbstractXmlForwardIterator. + \reentrant + \since 4.4 + \internal + \ingroup xml-tools + + ListIterator takes a reference to a QList instance and allows + access to that list via its QAbstractXmlForwardIterator interface. + ListIterator is parameterized with the type to iterate over, e.g., + Item or Expression::Ptr. + + ListIterator is used by the ExpressionSequence to create an + iterator over its operands. The iterator will be passed to a + MappingIterator. + */ + +/*! + \fn QPatternist::makeListIterator(const QList &qList) + \relates QPatternist::ListIterator + + An object generator for ListIterator. + + makeListIterator() is a convenience function to avoid specifying + the full template instantiation for ListIterator. Conceptually, it + is identical to Qt's qMakePair(). + + */ diff --git a/src/xmlpatterns/api/qabstractxmlforwarditerator_p.h b/src/xmlpatterns/api/qabstractxmlforwarditerator_p.h new file mode 100644 index 0000000..3e222e8 --- /dev/null +++ b/src/xmlpatterns/api/qabstractxmlforwarditerator_p.h @@ -0,0 +1,341 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QABSTRACTXMLFORWARDITERATOR_H +#define QABSTRACTXMLFORWARDITERATOR_H + +#include +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(XmlPatterns) + +template class QVector; + +/* In this file we in some cases do not use QAbstractXmlForwardIterator's Ptr typedef. + * This is a compiler workaround for MS VS 6.0. */ + +template +inline bool qIsForwardIteratorEnd(const T &unit) +{ + return !unit; +} + +/** + * @short Helper class for StringSplitter + * + * Needed by the QAbstractXmlForwardIterator sub-class. + * + * @relates StringSplitter + */ +template<> +inline bool qIsForwardIteratorEnd(const QString &unit) +{ + return unit.isNull(); +} + +template class QAbstractXmlForwardIterator; + +class QAbstractXmlForwardIteratorPrivate; + +template +class QAbstractXmlForwardIterator : public QSharedData +{ +public: + typedef QExplicitlySharedDataPointer > Ptr; + typedef QList > > List; + typedef QVector > > Vector; + + inline QAbstractXmlForwardIterator() : d_ptr(0) {} + virtual ~QAbstractXmlForwardIterator() {} + + virtual T next() = 0; + virtual T current() const = 0; + + virtual qint64 position() const = 0; + + virtual typename QAbstractXmlForwardIterator::Ptr toReversed(); + virtual QList toList(); + virtual typename QAbstractXmlForwardIterator::Ptr copy() const; + virtual T last(); + virtual bool isEmpty(); + virtual qint64 count(); + virtual qint64 sizeHint() const; + +private: + Q_DISABLE_COPY(QAbstractXmlForwardIterator) + + QAbstractXmlForwardIteratorPrivate *d_ptr; /* Currently not used. */ +}; + +/* The namespace QPatternist and its members are internal, not part of the public API, and + * unsupported. Using them leads to undefined behavior. */ +namespace QPatternist +{ + class DeduplicateIterator; + + template > + class ListIteratorPlatform : public QAbstractXmlForwardIterator + { + /* This declaration is a workaround for a set of GCC versions on OS X, + * amongst others powerpc-apple-darwin8-gcc-4.0.1 (GCC) 4.0.1. In + * DeduplicateIterator, it fails to see the protected inheritance. */ + friend class DeduplicateIterator; + + public: + virtual OutputType next() + { + if(m_position == -1) + return OutputType(); + + if(m_position == m_list.count()) + { + m_position = -1; + m_current = OutputType(); + return OutputType(); + } + + m_current = static_cast(this)->inputToOutputItem(m_list.at(m_position)); + ++m_position; + return m_current; + } + + virtual OutputType current() const + { + return m_current; + } + + virtual qint64 position() const + { + return m_position; + } + + virtual qint64 count() + { + return m_list.count(); + } + + virtual typename QAbstractXmlForwardIterator::Ptr copy() const + { + return QExplicitlySharedDataPointer >(new ListIteratorPlatform(m_list)); + } + + protected: + inline ListIteratorPlatform(const ListType &list) : m_list(list) + , m_position(0) + { + } + + const ListType m_list; + qint64 m_position; + OutputType m_current; + }; + + template > + class ListIterator : public ListIteratorPlatform, ListType> + { + /* + * This declaration is needed for MSVC 2005, 14.00.50727.42 for 80x86. + */ + friend class IteratorVector; + + using ListIteratorPlatform, ListType>::m_list; + + static inline QVector toVector(const QVector &vector) + { + return vector; + } + + static inline QVector toVector(const QList &list) + { + return list.toVector(); + } + + static inline QList toList(const QVector &vector) + { + return vector.toList(); + } + + static inline QList toList(const QList &list) + { + return list; + } + + public: + inline ListIterator(const ListType &list) : ListIteratorPlatform, ListType>(list) + { + } + + virtual QList toList() + { + return toList(m_list); + } + + virtual QVector toVector() + { + return toVector(m_list); + } + + private: + inline const T &inputToOutputItem(const T &inputType) const + { + return inputType; + } + friend class ListIteratorPlatform, ListType>; + + // needed for MSVC 2005 + friend class DeduplicateIterator; + }; + + template + inline + typename QAbstractXmlForwardIterator::Ptr + makeListIterator(const QList &list) + { + return typename ListIterator::Ptr(new ListIterator(list)); + } + + template + inline + typename QAbstractXmlForwardIterator::Ptr + makeVectorIterator(const QVector &vector) + { + return typename ListIterator >::Ptr(new ListIterator >(vector)); + } +} + +template +QList QAbstractXmlForwardIterator::toList() +{ + QList result; + T item(next()); + + while(!qIsForwardIteratorEnd(item)) + { + result.append(item); + item = next(); + } + + return result; +} + +template +qint64 QAbstractXmlForwardIterator::count() +{ + qint64 retval = 0; + + while(!qIsForwardIteratorEnd(next())) + ++retval; + + return retval; +} + +template +typename QAbstractXmlForwardIterator::Ptr QAbstractXmlForwardIterator::toReversed() +{ + T item(next()); + QList result; + + while(!qIsForwardIteratorEnd(item)) + { + result.prepend(item); + item = next(); + } + + return QExplicitlySharedDataPointer >(new QPatternist::ListIterator(result)); +} + +template +T QAbstractXmlForwardIterator::last() +{ + T item(next()); + + while(!qIsForwardIteratorEnd(item)) + item = next(); + + return item; +} + +template +typename QAbstractXmlForwardIterator::Ptr QAbstractXmlForwardIterator::copy() const +{ + Q_ASSERT_X(false, Q_FUNC_INFO, + "This function is internal, unsupported, and should never be called."); + return typename QAbstractXmlForwardIterator::Ptr(); +} + +template +bool QAbstractXmlForwardIterator::isEmpty() +{ + return qIsForwardIteratorEnd(next()); +} + +template +qint64 QAbstractXmlForwardIterator::sizeHint() const +{ + Q_ASSERT_X(false, Q_FUNC_INFO, "This function is currently not expected to be used."); + return -1; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qabstractxmlnodemodel.cpp b/src/xmlpatterns/api/qabstractxmlnodemodel.cpp new file mode 100644 index 0000000..c2000bb --- /dev/null +++ b/src/xmlpatterns/api/qabstractxmlnodemodel.cpp @@ -0,0 +1,1683 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qabstractxmlnodemodel_p.h" +#include "qabstractxmlreceiver.h" +#include "qcommonvalues_p.h" +#include "qemptyiterator_p.h" +#include "qitemmappingiterator_p.h" +#include "qitem_p.h" +#include "qnamespaceresolver_p.h" +#include "qsequencemappingiterator_p.h" +#include "qsingletoniterator_p.h" + +#include "qabstractxmlnodemodel.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +typedef QExplicitlySharedDataPointer > QXmlNodeModelIndexIteratorPointer; + +/** + * @file + * @short Contains the implementation of QAbstractXmlNodeModel. + */ + +bool QAbstractXmlNodeModel::isIgnorableInDeepEqual(const QXmlNodeModelIndex &n) +{ + Q_ASSERT(!n.isNull()); + const QXmlNodeModelIndex::NodeKind nk = n.kind(); + return nk == QXmlNodeModelIndex::ProcessingInstruction || + nk == QXmlNodeModelIndex::Comment; +} + + +/*! + \class QAbstractXmlNodeModel + \brief The QAbstractXmlNodeModel class is an abstract base class for modeling non-XML data to look like XML for QXmlQuery. + \threadsafe + \since 4.4 + \ingroup xml-tools + + The QAbstractXmlNodeModel specifies the interface that a node model + must implement for that node model be accessible to the query engine + for processing XQuery queries. A node model represents data as a + structure that can be queried as if the data were XML. + + The node model represented by a subclass of QAbstractXmlNodeModel is + meant to be accessed by the QtXmlPatterns query engine. If the API + seems a little strange in a few places, it is because the member + functions are called by the query engine as it evaluates an + XQuery. They aren't meant to be used programatically. + + \section1 Usage + + QAbstractXmlNodeModel bridges the gap between the arbitrary structure + of the non-XML data to be queried and the well-defined structure of + XML data understood by QXmlQuery. + + Consider a chemistry application that reads the file \c + chemistryData, which contains non-XML data that represents a + chemical structure composed of molecules and atoms. The application + will query this chemistry data with an XQuery it reads from file \c + queryFile. We write a custom subclass of QAbstractXmlNodeModel (\c + ChemistryNodeModel) that reads \c chemistryData and builds a data + structure, perhaps composed of objects of our own classes \c + molecule and \c atom. Clearly, this data structure is not XML. Our + custom subclass will know how to traverse this non-XML structure and + present it through the \l + {http://www.w3.org/TR/xpath-datamodel/}{XPath Data Model interface}. + + \snippet doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlnodemodel.cpp 1 + + The application first creates an instance of QXmlQuery and calls \l + {QXmlQuery::setQuery()}{setQuery()} to read \c queryFile containing + the XQuery we want to run. Then it creates an instance of our custom + node model class, \c ChemistryNodeModel, which is a subclass of + QAbstractXmlNodeModel. Its constructor is called with the \l + {QXmlNamePool} {name pool} obtained from our QXmlQuery, and with the + \c chemistryFile containing the structure of molecules and atoms to + be queried. The \l {QXmlNamePool} {name pool} is required because + our custom node model has the member function \l + {QAbstractXmlNodeModel::name()} {name()}, which returns the \l + {QXmlName} {name} of any node in the model. The \l {QXmlQuery} + {query} and the custom node model must use the same name pool for + constructing these \l {QXmlName} {names}. The constructor would then + read \c chemistryFile and build the custom node model structure. + + To connect the \c query to the custom node model, we must bind a + variable name used in the query to a node in the model. The variable + can then be used in the query as a starting node. First, an \l + {QXmlNodeModelIndex} {index} for the desired starting node is + retrieved by calling QAbstractXmlNodeModel::createIndex(). Then the + index is bound to a variable name, in this case \c queryRoot, by + passing the name and the index to QXmlQuery::bindVariable(). The + query can then use a variable reference \c $queryRoot to refer to + the starting node. Note that if the \l {QXmlQuery} {query} uses + multiple variable references, a call to QXmlQuery::bindVariable() + is required to bind each different variable name to a node in the + model. + + The query is executed when the application calls one of the + QXmlQuery evaluation functions. The application uses + QXmlQuery::evaluateTo(QAbstractXmlReceiver *), because it then uses + a \l {QXmlSerializer} {serializer} to out the query result as XML to + \c stdout. We could have used QXmlQuery::evaluateTo(QXmlResultItems + *) to get a list of result items, or + QXmlQuery::evaluateTo(QStringList *) if the query evaluated to a + sequence of \c {xs:string} values. + + During query execution, the engine iterates over the node model + using nextFromSimpleAxis() to get the \l {QXmlNodeModelIndex} + {index} of the next node to be visited. The engine can get the name + of a node by calling name() with the node's \l {QXmlNodeModelIndex} + {index}. stringValue(), baseUri(), documentUri() and kind() are also + called as needed with a node \l {QXmlNodeModelIndex} {index}. + + The example demonstrates the standard pattern for using a subclass + of QAbstractXmlNodeModel in combination with QXmlQuery to perform + an XQuery. + + \list 1 + + \o Instantiate QXmlQuery and give it the XQuery to be run; + + \o Instantiate a subclass of QAbstractXmlNodeModel or + QSimpleXmlNodeModel; + + \o Retrieve a QXmlNodeModelIndex for the node in the model where + the QXmlQuery should start the query; + + \o Use QXmlQuery::bindVariable() to bind the QXmlNodeModelIndex + to \c {$variable name}; + + \o Call one of the QXmlQuery evaluation functions to run the + query. + + \endlist + + \section1 Subclassing + + Because the \l {http://www.w3.org/TR/xpath-datamodel/}{XPath Data Model + interface} presented by QAbstractXmlNodeModel allows QXmlQuery to + operate on non-XML data as if it were XML, implementing subclasses + of QAbstractXmlNodeModel can involve a significant amount of + work. The QSimpleXmlNodeModel class is provided to simplify the + implementation for many common use cases. + + \section1 Thread Safety + + Because the node model can be accessed concurrently by threads in + the QtXmlPatterns module, subclasses of QAbstractXmlNodeModel must + be written to be \l{Reentrancy and Thread-Safety}{thread-safe}. + Classes that simplify implementing thread-safety include QReadLocker + and QWriteLocker. + + See the example \l{File System Example} for a demonstration. + */ + +/*! + \enum QXmlNodeModelIndex::Constants + + \value ForwardAxis All forward axes include this flag. + \value ReverseAxis All reverse axes include this flag. + */ + +/*! + \enum QXmlNodeModelIndex::DocumentOrder + + Identifies the specific node comparison operator that should be + used. + + \value Precedes Signifies the \c \<\< operator. Test whether the + first operand precedes the second in the document. + + \value Follows Signifies the \c \>\> operator. Test whether the + first operand follows the second in the document. + + \value Is Signifies the \c is operator. Test whether two nodes have + the same node identity. + */ + +/*! + \enum QAbstractXmlNodeModel::SimpleAxis + + Four axes that each contain one node only. + + \value Parent The parent of the context node + \value FirstChild The first child of the context node + \value PreviousSibling The previous child of the context node + \value NextSibling The next child of the context node +*/ + +/*! + \enum QXmlNodeModelIndex::Axis + \internal + + Identify the axes emanating from a node. + + The axes AxisChild, AxisDescendant, AxisAttribute, AxisSelf, + AxisDescendantOrSelf, AxisFollowingSibling, and AxisFollowing are + forward axes. + + The axes AxisParent, AxisAncestor, AxisPrecedingSibling, + AxisPreceding and AxisAncestorOrSelf are reverse axes. + + \sa {http://www.w3.org/TR/xquery/#axes}{XQuery 1.0: An XML Query Language, 3.2.1.1 Axes} + + \value AxisChild The \c child axis. + + \value AxisDescendant The \c descendant axis. + + \value AxisAttribute The \c attribute axis. Note: There + is a node kind named \c{Attribute}. + + \value AxisSelf The \c self axis. + + \value AxisDescendantOrSelf The \c descendant-or-self axis. + + \value AxisFollowingSibling The \c following-sibling axis. + + \value AxisNamespace The \c namespace axis. Note: Does + not exist in XQuery; deprecated in + XPath 2.0 (optionally supported); + mandatory in XPath 1.0. + + \value AxisFollowing The \c following axis. + + \value AxisParent The \c parent axis. + + \value AxisAncestor The \c ancestor axis. + + \value AxisPrecedingSibling The \c preceding-sibling axis. + + \value AxisPreceding The \c preceding axis. + + \value AxisAncestorOrSelf The \c ancestor-or-self axis. +*/ + +using namespace QPatternist; + +/*! + Default constructor. + */ +QAbstractXmlNodeModel::QAbstractXmlNodeModel() : d_ptr(0) +{ +} + +/*! + \internal + + Takes the d-pointer. + + */ +QAbstractXmlNodeModel::QAbstractXmlNodeModel(QAbstractXmlNodeModelPrivate *d) : d_ptr(d) +{ +} + +/*! + Destructor. + */ +QAbstractXmlNodeModel::~QAbstractXmlNodeModel() +{ +} + +/*! + \typedef QAbstractXmlNodeModel::List + + A \l{QList}{list} of \l{QExplicitlySharedDataPointer} {smart + pointers} to instances of QAbstractXmlNodeModel. + + \sa QExplicitlySharedDataPointer + */ + +/*! + \typedef QAbstractXmlNodeModel::Ptr + + A \l {QExplicitlySharedDataPointer} {smart pointer} to an + instance of QAbstractXmlNodeModel. + + \sa QExplicitlySharedDataPointer + */ + +/*! + \fn QUrl QAbstractXmlNodeModel::baseUri(const QXmlNodeModelIndex &n) const + + Returns the base URI for the node whose index is \a n. The caller + guarantees that \a n is not \c null and that it belongs to a node + in this node model. + + The base URI of a node can be extracted using the \c fn:base-uri() + function. The base URI is typically used for resolving relative URIs + that appear in the node or its children. It is conformant to just + return the document URI, although that might not properly reflect + the underlying data. + + This function maps to the \c dm:base-uri accessor, which returns + a base URI according to the following: + + \list + + \o For document nodes, the base URI and the document URI are the same. + + \o For elements, the base URI is the URI appearing in the element's + \c xml:base attribute, if present, or it is resolved to the + parent element's base URI. + + \o Namespace nodes have no base URI. + + \o The base URI for a processing instruction, comment, attribute, + or text node is the base URI of the node's parent element. + + \endlist + + The implementation guarantees to return a valid QUrl, or a default + constructed QUrl. If a node has no base URI, as in the case where a + comment has no parent, a default constructed QUrl is returned. + + \sa {http://www.w3.org/TR/xpath-datamodel/#dm-base-uri}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 5.2 base-uri Accessor} + */ + +/*! + \fn QUrl QAbstractXmlNodeModel::documentUri(const QXmlNodeModelIndex &n) const + + Returns the document URI of \a n. The document URI identifies the + resource which is the document. For example, the document could be a + regular file, e.g., \c{file:/}, or it could be the \c{http://} URL of + the location of a file. The document URI is used for resolving URIs + and to simply know where the document is. + + If the node model maps to a URI in a natural way, return that URI. + Otherwise, return the company or product URI. The document URI can + be any URI as long as its valid and absolute. + + The caller guarantees that \a n is not \c null and that it belongs + to this QAbstractXmlNodeModel. + + This function maps to the \c dm:document-uri accessor, which + returns a document URI according to the following: + + \list + + \o If \a n is a document node, return an absolute QUrl containing + the document URI, or a default constructed QUrl. The latter + signals that no document URI is available for the document node. + + \o For all other nodes, return a default constructed QUrl. + + \endlist + + \sa {http://www.w3.org/TR/xpath-datamodel/#dm-document-uri}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 5.4 document-uri Accessor} + \sa QUrl::isValid(), QUrl::isRelative() + */ + +/* +### Qt 5: + +Add the function: + + virtual QSourceLocation sourceLocation(const QXmlNodeModelIndex &nodeIndex) const = 0; + +Such that the data model can communicate back source locations. + */ + +/*! + \fn QXmlNodeModelIndex::NodeKind QAbstractXmlNodeModel::kind(const QXmlNodeModelIndex &ni) const + + Returns a value indicating the kind of node identified by \a ni. + The caller guarantees that \a ni is not null and that it identifies + a node in this node model. This function maps to the \c + dm:node-kind() accessor. + + \sa {http://www.w3.org/TR/xpath-datamodel/#dm-node-kind}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 5.10 node-kind Accessor} + */ + +/*! + \fn QXmlNodeModelIndex::DocumentOrder QAbstractXmlNodeModel::compareOrder(const QXmlNodeModelIndex &ni1, const QXmlNodeModelIndex &ni2) const + + This function returns the relative document order for the + nodes indexed by \a ni1 and \a ni2. It is used for the \c Is + operator and for sorting nodes in document order. + + The caller guarantees that \a ni1 and \a ni2 are not \c null and + that both identify nodes in this node model. + + If \a ni1 is identical to \a ni2, QXmlNodeModelIndex::Is is returned. + If \a ni1 precedes \a ni2 in document order, QXmlNodeModelIndex::Precedes + is returned. If \a ni1 follows \a ni2 in document order, + QXmlNodeModelIndex::Follows is returned. + + \sa {http://www.w3.org/TR/xpath-datamodel/#document-order}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 2.4 Document Order} + */ + +/*! + \fn QXmlNodeModelIndex QAbstractXmlNodeModel::root(const QXmlNodeModelIndex &n) const + + Returns the root node of the tree that contains the node whose index + is \a n. The caller guarantees that \a n is not \c null and that it + identifies a node in this node model. + + If \a n identifies a node that is a direct child of the root, + parent() would return the same QXmlNodeModelIndex returned by + this function. + */ + +namespace QPatternist +{ + class MergeIterator + { + public: + inline MergeIterator() + { + } + + inline + QXmlNodeModelIndexIteratorPointer + mapToSequence(const QXmlNodeModelIndexIteratorPointer &it, + const DynamicContext::Ptr &) const + { + return it; + } + + private: + Q_DISABLE_COPY(MergeIterator) + }; + + static const MergeIterator mergeIterator; + + /** + * One might wonder, why not use makeVectorIterator() directly on a QVector + * with iterators? + * + * A problem emerges QAbstractXmlForwardIterator::copy(). All "meta + * iterators" that contain other iterators and so forth, propagate the + * copy() call such that all involved iterators are copied. However, if we + * have a ListIterator of iterators it isn't aware of that it contains + * iterators. Hence, we have this class which is specialized(not in the + * template sense) on iterators, and hence copies them appropriately. + */ + class IteratorVector : public ListIterator > + { + typedef QVector ItVector; + public: + typedef QAbstractXmlForwardIterator::Ptr Ptr; + + IteratorVector(const ItVector &in) : ListIterator >(in) + { + } + + virtual QAbstractXmlForwardIterator::Ptr copy() const + { + ItVector result; + + for(int i = 0; i < m_list.count(); ++i) + result.append(m_list.at(i)->copy()); + + return Ptr(new IteratorVector(result)); + } + }; +} + +/*! + \internal + This function is not a private member of QAbstractXmlNodeModel + because it would be messy to forward declare the required types. +*/ +static inline QXmlNodeModelIndexIteratorPointer mergeIterators(const QXmlNodeModelIndex &node, + const QXmlNodeModelIndexIteratorPointer &it2) +{ + QVector iterators; + iterators.append(makeSingletonIterator(node)); + iterators.append(it2); + + return makeSequenceMappingIterator(&mergeIterator, + IteratorVector::Ptr(new IteratorVector(iterators)), + DynamicContext::Ptr()); +} + +inline QAbstractXmlForwardIterator::Ptr +QAbstractXmlNodeModel::mapToSequence(const QXmlNodeModelIndex &ni, + const DynamicContext::Ptr &) const +{ + Q_ASSERT(!ni.isNull()); + /* Since we pass in this here, mapToSequence is used recursively. */ + return mergeIterators(ni, makeSequenceMappingIterator(this, + ni.iterate(QXmlNodeModelIndex::AxisChild), + DynamicContext::Ptr())); +} + +/*! + \fn QVector QAbstractXmlNodeModel::attributes(const QXmlNodeModelIndex &element) const + + Returns the attributes of \a element. The caller guarantees + that \a element is an element in this node model. + */ + +/*! + \internal + + Performs navigation, starting from \a ni, by returning an + QAbstractXmlForwardIterator that returns nodes the \a axis emanating + from \a ni. + + The implementation returns the nodes on the \a axis, without + duplicates and in \a axis order. This means that if \a axis is a + reverse axis, which is the case for the \c parent, \c ancestor, \c + ancestor-or-self, \c preceding, and \c preceding-sibling, the nodes + are delivered in reverse document order. Otherwise the nodes are + delivered in document order. + + The implementor guarantees that the nodes delivered for the axes are + consistent with the XPath Data Model. This just implies common + sense, e.g., The child axis for a comment node can't contain any + children; a document node can't be a child of an element, etc. + Attributes aren't considered children of an element, but are only + available on AxisAttribute. + + The value past in \a axis is not guaranteed based on what is used in + a query. QtXmlPatterns may call this function arbitrarily with any + value for \a axis. This is because QtXmlPatterns may rewrite queries + to be more efficient, using axes in different ways from the original + query. + + QAbstractXmlNodeModel::Axis has a good overview of the axes and what + they select. + + The caller guarantees that \a ni is not \c null and that it belongs + to this QAbstractXmlNodeModel instance. + + Implementing iterate() can involve significant work, since it + requires different iterators for all the axes used. In the worst + case, it could require writing as many QAbstractXmlForwardIterator + subclasses as there are axes, but the number can often be reduced + with clever use of lists and template classes. It is better to use + or subclass QSimpleXmlNodeModel, which makes it easier to write the + node navigation code without loss of efficiency or flexibility. + + \sa QSimpleXmlNodeModel + \sa QXmlNodeModelIndex::Axis + \sa {http://www.w3.org/TR/xquery/#axes}{XQuery 1.0: An XML Query Language, 3.2.1.1 Axes} + \sa {http://www.w3.org/TR/xpath-datamodel/}{W3CXQuery 1.0 and XPath 2.0 Data Model (XDM)} + */ +QExplicitlySharedDataPointer > +QAbstractXmlNodeModel::iterate(const QXmlNodeModelIndex &ni, + QXmlNodeModelIndex::Axis axis) const +{ + /* Returns iterators that track state and calls nextFromSimpleAxis() + * iteratively. Typically, when sub-classing QSimpleXmlNodeModel, + * you don't reimplement this function, but instead implement + * nextFromSimpleAxis(). */ + + switch(axis) + { + case QXmlNodeModelIndex::AxisSelf: + return makeSingletonIterator(ni); + case QXmlNodeModelIndex::AxisParent: + { + if(kind(ni) == QXmlNodeModelIndex::Document) + return makeEmptyIterator(); + else + return makeSingletonIterator(nextFromSimpleAxis(Parent, ni)); + } + case QXmlNodeModelIndex::AxisNamespace: + return makeEmptyIterator(); + case QXmlNodeModelIndex::AxisAncestor: + { + QList ancestors; + QXmlNodeModelIndex ancestor = nextFromSimpleAxis(Parent, ni); + + while(!ancestor.isNull()) + { + ancestors.append(ancestor); + ancestor = nextFromSimpleAxis(Parent, ancestor); + } + + return makeListIterator(ancestors); + } + case QXmlNodeModelIndex::AxisAncestorOrSelf: + { + QList ancestors; + ancestors.append(ni); + QXmlNodeModelIndex ancestor = nextFromSimpleAxis(Parent, ni); + + while(!ancestor.isNull()) + { + ancestors.append(ancestor); + ancestor = nextFromSimpleAxis(Parent, ancestor); + } + + return makeListIterator(ancestors); + } + case QXmlNodeModelIndex::AxisPrecedingSibling: + { + QList preceding; + QXmlNodeModelIndex sibling = nextFromSimpleAxis(PreviousSibling, ni); + + while(!sibling.isNull()) + { + preceding.append(sibling); + sibling = nextFromSimpleAxis(PreviousSibling, sibling); + } + + return makeListIterator(preceding); + } + case QXmlNodeModelIndex::AxisFollowingSibling: + { + QList preceding; + QXmlNodeModelIndex sibling = nextFromSimpleAxis(NextSibling, ni); + + while(!sibling.isNull()) + { + preceding.append(sibling); + sibling = nextFromSimpleAxis(NextSibling, sibling); + } + + return makeListIterator(preceding); + } + case QXmlNodeModelIndex::AxisChildOrTop: + { + if(nextFromSimpleAxis(Parent, ni).isNull()) + { + switch(kind(ni)) + { + case QXmlNodeModelIndex::Comment: + /* Fallthrough. */ + case QXmlNodeModelIndex::ProcessingInstruction: + /* Fallthrough. */ + case QXmlNodeModelIndex::Element: + /* Fallthrough. */ + case QXmlNodeModelIndex::Text: + return makeSingletonIterator(ni); + case QXmlNodeModelIndex::Attribute: + /* Fallthrough. */ + case QXmlNodeModelIndex::Document: + /* Fallthrough. */ + case QXmlNodeModelIndex::Namespace: + /* Do nothing. */; + } + } + + /* Else, fallthrough to AxisChild. */ + } + case QXmlNodeModelIndex::AxisChild: + { + QList children; + QXmlNodeModelIndex child = nextFromSimpleAxis(FirstChild, ni); + + while(!child.isNull()) + { + children.append(child); + child = nextFromSimpleAxis(NextSibling, child); + } + + return makeListIterator(children); + } + case QXmlNodeModelIndex::AxisDescendant: + { + return makeSequenceMappingIterator(this, + ni.iterate(QXmlNodeModelIndex::AxisChild), + DynamicContext::Ptr()); + } + case QXmlNodeModelIndex::AxisAttributeOrTop: + { + if(kind(ni) == QXmlNodeModelIndex::Attribute && nextFromSimpleAxis(Parent, ni).isNull()) + return makeSingletonIterator(ni); + + /* Else, fallthrough to AxisAttribute. */ + } + case QXmlNodeModelIndex::AxisAttribute: + return makeVectorIterator(attributes(ni)); + case QXmlNodeModelIndex::AxisDescendantOrSelf: + return mergeIterators(ni, iterate(ni, QXmlNodeModelIndex::AxisDescendant)); + case QXmlNodeModelIndex::AxisFollowing: + /* Fallthrough. */ + case QXmlNodeModelIndex::AxisPreceding: + { + /* We walk up along the ancestors, and for each parent, we grab its preceding/following + * siblings, and evaluate the descendant axis. The descendant axes gets added + * to a list and we then merge those iterators. */ + QVector descendantIterators; + + QXmlNodeModelIndex current(ni); + while(!current.isNull()) + { + QXmlNodeModelIndex candidate(nextFromSimpleAxis(axis == QXmlNodeModelIndex::AxisPreceding ? PreviousSibling : NextSibling, current)); + if(candidate.isNull()) + { + /* current is an ancestor. We don't want it, so next iteration we + * will grab its preceding sibling. */ + current = nextFromSimpleAxis(Parent, current); + } + else + { + current = candidate; + descendantIterators.append(iterate(current, QXmlNodeModelIndex::AxisDescendantOrSelf)->toReversed()); + } + } + + return makeSequenceMappingIterator(&mergeIterator, + IteratorVector::Ptr(new IteratorVector(descendantIterators)), + DynamicContext::Ptr()); + } + } + + Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown axis, internal error."); + return makeEmptyIterator(); +} + +/*! + \fn QXmlNodeModelIndex QAbstractXmlNodeModel::nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &origin) const + + When QtXmlPatterns evaluate path expressions, it emulate them through a + combination of calls with QSimpleXmlNodeModel::SimpleAxis values. Therefore, + the implementation of this function must return the node, if any, that + appears on the \a axis emanating from the \a origin. + + If no such node is available, a default constructed + QXmlNodeModelIndex is returned. + + QSimpleXmlNodeModel eliminates the need to handle redundant corner + cases by guaranteeing that it will never ask for: + + \list + \o Children or siblings for attributes. + \o Children for comments, processing instructions, and text nodes. + \o Siblings or parents for document nodes. + \endlist + + A typical implementation performs a \c switch on the value of \a + axis: + + \code + QXmlNodeModelIndex MyTreeModel::nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &origin) const + { + // Convert the QXmlNodeModelIndex to a value that is specific to what we represent. + const MyValue value = toMyValue(ni); + + switch(axis) + { + case Parent: + return toNodeIndex(value.parent()); + case FirstChild: + case PreviousSibling: + case NextSibling: + // and so on + } + } + \endcode + + */ + +/*! + \fn QXmlNodeModelIndex QAbstractXmlNodeModel::createIndex(qint64 data) const + + Creates a node index with \a data as its internal data. \a data is + not constrained. + */ + +/*! + \fn QXmlNodeModelIndex QAbstractXmlNodeModel::createIndex(void *pointer, qint64 additionalData) const + + Creates a node index with \a pointer and \a additionalData as + its internal data. + + What \a pointer and \a additionalData is, is not constrained. + */ + +/*! + \fn QXmlNodeModelIndex QAbstractXmlNodeModel::createIndex(qint64 data, qint64 additionalData) const; + \overload + + Creates a QXmlNodeModelIndex containing \a data and \a + additionalData. + */ + +/*! + \fn QXmlName QAbstractXmlNodeModel::name(const QXmlNodeModelIndex &ni) const + + Returns the name of \a ni. The caller guarantees that \a ni is not + \c null and that it belongs to this QAbstractXmlNodeModel. + + If a node does not have a name, e.g., comment nodes, a null QXmlName + is returned. QXmlNames must be created with the instance of + QXmlQuery that is being used for evaluating queries using this + QAbstractXmlNodeModel. + + This function maps to the \c dm:node-name() accessor. + + If \a ni is a processing instruction, a QXmlName is returned with + the local name as the target name and the namespace URI and prefix + both empty. + + \sa {http://www.w3.org/TR/xpath-datamodel/#dm-node-name}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 5.11 node-name Accessor} + \sa QXmlName + */ + +/*! + \fn QVector QAbstractXmlNodeModel::namespaceBindings(const QXmlNodeModelIndex &n) const + + Returns the in-scope namespaces of \a n. The caller guarantees that + \a n is not \c null and that it belongs to this QAbstractXmlNodeModel. + + This function corresponds to the \c dm:namespace-nodes accessor. + + The returned vector of namespace declarations includes namespaces + of the ancestors of \a n. + + The caller guarantees that \a n is an Element that belongs to this + QAbstractXmlNodeModel. + */ + +/*! + \internal + Sends the namespaces declared on \a n to \a receiver. + + As a consequence, no namespaces are sent unless this node is an + element and has namespaces declared. + + The caller guarantees that \a n is not \c null and that it belongs + to this QAbstractXmlNodeModel instance. + + Note that it is not the namespaces that are in scope on \a n, but + only the namespaces that are specifically declared on \a n. + + \a receiver is the receiver that this node is supposed to send its + namespaces to. This is guaranteed by the caller to be a valid + pointer. \a n is the index of the node whose namespaces are to + be sent. + */ +void QAbstractXmlNodeModel::sendNamespaces(const QXmlNodeModelIndex &n, + QAbstractXmlReceiver *const receiver) const +{ + Q_ASSERT(receiver); + const QVector nss(namespaceBindings(n)); + + /* This is by far the most common case. */ + if(nss.isEmpty()) + return; + + const int len = nss.size(); + for(int i = 0; i < len; ++i) + receiver->namespaceBinding(nss.at(i)); +} + +/*! + \fn QString QAbstractXmlNodeModel::stringValue(const QXmlNodeModelIndex &n) const + + Returns the string value for node \a n. + + The caller guarantees that \a n is not \c null and that it belong to + this QAbstractXmlNodeModel instance. + + This function maps to the \c dm:string-value() accessor, which the + specification completely specifies. Here's a summary: + + \list + + \o For processing instructions, the string value is the data + section(excluding any whitespace appearing between the name and the + data). + + \o For text nodes, the string value equals the text node. + + \o For comments, the content of the comment + + \o For elements, the concatenation of all text nodes that are + descendants. Note, this is not only the children, but the + childrens' childrens' text nodes, and so forth. + + \o For document nodes, the concatenation of all text nodes in the + document. + + \endlist + + \sa {http://www.w3.org/TR/xpath-datamodel/#dm-string-value}{XQuery 1.0 and XPath 2.0 Data Model (XDM), 5.13 string-value Accessor} + */ + +/*! + \fn QVariant QAbstractXmlNodeModel::typedValue(const QXmlNodeModelIndex &node) const + + Returns the typed value for node \a node. + + The typed value is an atomic value, which an element or attribute + contains. + + The caller guarantees that \a node is either an element or an + attribute. The implementor guarantees that the returned QVariant has + a value which is supported in XQuery. It cannot be an arbitrary + QVariant value. The implementor also guarantees that stringValue() + returns a lexical representation of typedValue()(this is guaranteed + by QSimpleXmlNodeModel::stringValue()). + + If the return QVariant is a default constructed variant, it signals + that \a node has no typed value. +*/ + +/*! + \internal + */ +QPatternist::ItemIteratorPtr QAbstractXmlNodeModel::sequencedTypedValue(const QXmlNodeModelIndex &ni) const +{ + const QVariant &candidate = typedValue(ni); + if(candidate.isNull()) + return QPatternist::CommonValues::emptyIterator; + else + return makeSingletonIterator(AtomicValue::toXDM(candidate)); +} + +/*! + \internal + */ +QPatternist::ItemTypePtr QAbstractXmlNodeModel::type(const QXmlNodeModelIndex &) const +{ + Q_ASSERT_X(false, Q_FUNC_INFO, + "This function is internal and must not be called."); + return QPatternist::ItemTypePtr(); +} + +/*! + \internal + + Returns the namespace URI on \a ni that corresponds to \a prefix. + + If \a prefix is StandardPrefixes::empty, the namespace URI for the + default namespace is returned. + + The default implementation use namespaceBindings(), in a straight + forward manner. + + If no namespace exists for \a prefix, NamespaceResolver::NoBinding + is returned. + + The caller guarantees to only call this function for element nodes. + */ +QXmlName::NamespaceCode QAbstractXmlNodeModel::namespaceForPrefix(const QXmlNodeModelIndex &ni, + const QXmlName::PrefixCode prefix) const +{ + Q_ASSERT(kind(ni) == QXmlNodeModelIndex::Element); + + const QVector nbs(namespaceBindings(ni)); + const int len = nbs.size(); + + for(int i = 0; i < len; ++i) + { + if(nbs.at(i).prefix() == prefix) + return nbs.at(i).namespaceURI(); + } + + return NamespaceResolver::NoBinding; +} + + +/*! + \internal + + Determines whether \a ni1 is deep equal to \a ni2. + + isDeepEqual() is defined as evaluating the expression \c + fn:deep-equal($n1, $n2) where \c $n1 is \a ni1 and \c $n1 is \a + ni2. This function is associative, meaning the same value is + returned regardless of if isDeepEqual() is invoked with \a ni1 as + first argument or second. It is guaranteed that \a ni1 and \a ni2 + are nodes, as opposed to the definition of \c fn:deep-equal(). + + Returns true if \a ni1 is deep-equal to \a ni2, otherwise false + + \sa {"http://www.w3.org/TR/xpath-functions/#func-deep-equal"}{XQuery 1.0 and XPath 2.0 Functions and Operators, 15.3.1 fn:deep-equal} + */ +bool QAbstractXmlNodeModel::isDeepEqual(const QXmlNodeModelIndex &n1, + const QXmlNodeModelIndex &n2) const +{ + Q_ASSERT(!n1.isNull()); + Q_ASSERT(!n2.isNull()); + + const QXmlNodeModelIndex::NodeKind nk = n1.kind(); + + if(nk != n2.kind()) + return false; + + if(n1.name() != n2.name()) + return false; + + switch(nk) + { + case QXmlNodeModelIndex::Element: + { + QXmlNodeModelIndexIteratorPointer atts1(n1.iterate(QXmlNodeModelIndex::AxisAttribute)); + QXmlNodeModelIndex node(atts1->next()); + + const QXmlNodeModelIndex::List atts2(n2.iterate(QXmlNodeModelIndex::AxisAttribute)->toList()); + const QXmlNodeModelIndex::List::const_iterator end(atts2.constEnd()); + + while(!node.isNull()) + { + bool equal = false; + for(QXmlNodeModelIndex::List::const_iterator it = atts2.constBegin(); it != end; ++it) + { + if(isDeepEqual(node, (*it))) + equal = true; + } + + if(!equal) + return false; + + node = atts1->next(); + } + + /* Fallthrough, so we check the children. */ + } + case QXmlNodeModelIndex::Document: + { + QXmlNodeModelIndexIteratorPointer itn1(n1.iterate(QXmlNodeModelIndex::AxisChild)); + QXmlNodeModelIndexIteratorPointer itn2(n2.iterate(QXmlNodeModelIndex::AxisChild)); + + while(true) + { + QXmlNodeModelIndex no1(itn1->next()); + QXmlNodeModelIndex no2(itn2->next()); + + while(!no1.isNull() && isIgnorableInDeepEqual(no1)) + no1 = itn1->next(); + + while(!no2.isNull() && isIgnorableInDeepEqual(no2)) + no2 = itn2->next(); + + if(!no1.isNull() && !no2.isNull()) + { + if(!isDeepEqual(no1, no2)) + return false; + } + else + return no1.isNull() && no2.isNull(); + } + + return true; + } + case QXmlNodeModelIndex::Attribute: + /* Fallthrough */ + case QXmlNodeModelIndex::ProcessingInstruction: + /* Fallthrough. */ + case QXmlNodeModelIndex::Text: + /* Fallthrough. */ + case QXmlNodeModelIndex::Comment: + return n1.stringValue() == n2.stringValue(); + case QXmlNodeModelIndex::Namespace: + { + Q_ASSERT_X(false, Q_FUNC_INFO, "Not implemented"); + return false; + } + } + + return false; +} + +/*! + \class QXmlItem + \reentrant + \since 4.4 + \brief The QXmlItem class contains either an XML node or an atomic value. + \ingroup xml-tools + + In XQuery, all expressions evaluate to a sequence of items, where + each item is either an XML node or an atomic value. The query in the + following snippet evaluates to sequence of five items. + + \quotefile doc/src/snippets/patternist/items.xq + + The five items are: An element, an atomic value (binary data encoded + in base64), a date, a float, and an attribute. + + QXmlItem is the class that represents these XQuery items in the + QtXmlPatterns API. A non-null instance of QXmlItem is either a node + or an atomic value. Calling isNode() or isAtomicValue() tells you + which it is. Atomic values are represented elsewhere in the Qt API + as instances of QVariant, and an instance of QXmlItem that + represents an atomic value can be converted to a QVariant by calling + toAtomicValue(). A QXmlItem that wraps a node is represented + elsewhere as an instance of QXmlNodeModelIndex. A node QXmlItem can + be converted to a QXmlNodeModelIndex by calling toNodeModelIndex(). + + A default constructed QXmlItem instance is neither a node nor an + atomic value. It is considered null, in which case isNull() returns + true. + + An instance of QXmlItem will be left dangling if the + \l{QAbstractXmlNodeModel} {XML node model} it + refers to is deleted, if it is a QXmlNodeModelIndex. + */ + +/*! + \typedef QXmlItem::Iterator + A QAbstractXmlForwardIterator over QXmlItem. + */ + +/*! + Constructs a null QXmlItem that is neither a node nor an atomic + value. isNull() returns true for a default constructed instance. + */ +QXmlItem::QXmlItem() +{ + m_node.model = 0; + m_node.data = 0; + m_node.additionalData = 0; +} + +bool QXmlItem::internalIsAtomicValue() const +{ + return m_node.model == reinterpret_cast(~0); +} + +/*! + The copy constructor constructs a copy of \a other. + */ +QXmlItem::QXmlItem(const QXmlItem &other) : m_node(other.m_node) +{ + if(internalIsAtomicValue()) + m_atomicValue->ref.ref(); +} + +/*! + Constructs an atomic value QXmlItem with \a atomicValue. + + \sa isAtomicValue() + */ +QXmlItem::QXmlItem(const QVariant &atomicValue) +{ + if(atomicValue.isNull()) + { + /* Then we behave just like the default constructor. */ + m_node.model = 0; + m_node.data = 0; + m_node.additionalData = 0; + return; + } + + /* + We can't assign directly to m_atomicValue, because the + temporary will self-destruct before we've ref'd it. + */ + const QPatternist::Item temp(QPatternist::AtomicValue::toXDM(atomicValue)); + + if(temp) + { + temp.asAtomicValue()->ref.ref(); + m_node.model = reinterpret_cast(~0); + m_atomicValue = temp.asAtomicValue(); + } + else + { + m_atomicValue = 0; + m_node.model = 0; + } + + m_node.additionalData = 0; +} + +/*! + Constructs a node QXmlItem that is a copy of \a node. + + \sa isNode() + */ +QXmlItem::QXmlItem(const QXmlNodeModelIndex &node) : m_node(node.m_storage) +{ +} + + +/*! + Destructor. + */ +QXmlItem::~QXmlItem() +{ + if(internalIsAtomicValue() && !m_atomicValue->ref.deref()) + delete m_atomicValue; +} + +bool QPatternist::NodeIndexStorage::operator!=(const NodeIndexStorage &other) const +{ + return data != other.data + || additionalData != other.additionalData + || model != other.model; +} + +/*! + Assigns \a other to \c this. + */ +QXmlItem &QXmlItem::operator=(const QXmlItem &other) +{ + if(m_node != other.m_node) + { + if(internalIsAtomicValue() && !m_atomicValue->ref.deref()) + delete m_atomicValue; + + m_node = other.m_node; + + if(internalIsAtomicValue()) + m_atomicValue->ref.ref(); + } + + return *this; +} + +/*! + Returns true if this item is a Node. Returns false if it + is an atomic value or null. + + \sa isNull(), isAtomicValue() + */ +bool QXmlItem::isNode() const +{ + return QPatternist::Item::fromPublic(*this).isNode(); +} + +/*! + Returns true if this item is an atomic value. Returns false + if it is a node or null. + + \sa isNull(), isNode() + */ +bool QXmlItem::isAtomicValue() const +{ + return internalIsAtomicValue(); +} + +/*! + If this QXmlItem represents an atomic value, it is converted + to an appropriate QVariant and returned. If this QXmlItem is + not an atomic value, the return value is a default constructed + QVariant. You can call isAtomicValue() to test whether the + item is an atomic value. + + \sa isAtomicValue() + */ +QVariant QXmlItem::toAtomicValue() const +{ + if(isAtomicValue()) + return QPatternist::AtomicValue::toQt(m_atomicValue); + else + return QVariant(); +} + +/*! + If this QXmlItem represents a node, it returns the item as a + QXmlNodeModelIndex. If this QXmlItem is not a node, the return + value is undefined. You can call isNode() to test whether the + item is a node. + + \sa isNode() + */ +QXmlNodeModelIndex QXmlItem::toNodeModelIndex() const +{ + if(isNode()) + return reinterpret_cast(m_node); + else + return QXmlNodeModelIndex(); +} + +/*! + Returns true if this QXmlItem is neither a node nor an + atomic value. Default constructed instances of QXmlItem + are null. + */ +bool QXmlItem::isNull() const +{ + return !m_node.model; +} + +/*! + \class QXmlNodeModelIndex + \brief The QXmlNodeModelIndex class identifies a node in an XML node model subclassed from QAbstractXmlNodeModel. + \reentrant + \since 4.4 + \ingroup xml-tools + + QXmlNodeModelIndex is an index into an \l{QAbstractXmlNodeModel} + {XML node model}. It contains: + + \list + \o A pointer to an \l{QAbstractXmlNodeModel} {XML node model}, + which is returned by model(), and + \o Some data, which is returned by data(), internalPointer(), + and additionalData(). + \endlist + + Because QXmlNodeModelIndex is intentionally a simple class, it + doesn't have member functions for accessing the properties of + nodes. For example, it doesn't have functions for getting a + node's name or its list of attributes or child nodes. If you find + that you need to retrieve this kind of information from your + query results, there are two ways to proceed. + + \list + + \o Send the output of your XQuery to an \l{QAbstractXmlReceiver} + {XML receiver}, or + + \o Let your XQuery do all the work to produce the desired result. + + \endlist + + The second case is explained by example. Suppose you want to + populate a list widget with the values of certain attributes from a + set of result elements. You could write an XQuery to return the set + of elements, and then you would write the code to iterate over the + result elements, get their attributes, and extract the desired + string values. But the simpler way is to just augment your XQuery to + finding the desired attribute values. Then all you have to do is + evaluate the XQuery using the version of QXmlQuery::evaluateTo() + that populates a QStringList, which you can send directly to your + widget. + + QXmlNodeModelIndex doesn't impose any restrictions on the \c data + value an QXmlNodeModelIndex should contain. The meaning of the data + left to the associated \l {QAbstractXmlNodeModel} {node model}. + Because QXmlNodeModelIndex depends on a particular subclass of + QAbstractXmlNodeModel for its existence, the only way you can create + an instance of QXmlNodeModelIndex is by asking the node model to + create one for you with QAbstractXmlNodeModel::createIndex(). Since + that function is protected, it is usually a good idea to write a + public function that creates a QXmlNodeModelIndex from arguments that + are appropriate for your particular node model. + + A default constructed node index is said to be null, i.e., isNull() + returns true. + + QXmlNodeModelIndex and QAbstractXmlNodeModel follow the same design + pattern used for QModelIndex and QAbstractItemModel. + */ + +/*! + \since 4.4 + \relates QHash + + Computes a hash key from the QXmlNodeModelIndex \a index, and + returns it. This function would be used by QHash if you wanted + to build a hash table for instances of QXmlNodeModelIndex. + + The hash is computed on QXmlNodeModelIndex::data(), + QXmlNodeModelIndex::additionalData(), and + QXmlNodeModelIndex::model(). This means the hash key can be used for + node indexes from different node models. + */ +uint qHash(const QXmlNodeModelIndex &index) +{ + return uint(index.data() + index.additionalData() + quintptr(index.model())); +} + +/*! + \enum QXmlNodeModelIndex::NodeKind + + Identifies a kind of node. + + \value Attribute Identifies an attribute node + \value Text Identifies a text node + \value Comment Identifies a comment node + \value Document Identifies a document node + \value Element Identifies an element node + \value Namespace Identifies a namespace node + \value ProcessingInstruction Identifies a processing instruction. + + Note that the optional XML declaration at very beginning of the XML + document is not a processing instruction + + \sa QAbstractXmlNodeModel::kind() +*/ + +/*! + \typedef QXmlNodeModelIndex::List + + Typedef for QList. + */ + +/*! + Returns true if this node is the same as \a other. This operator + does not compare values, children, or names of nodes. It compares + node identities, i.e., whether two nodes are from the same document + and are found at the exact same place. + */ +bool QXmlNodeModelIndex::operator==(const QXmlNodeModelIndex &other) const +{ + return !(m_storage != other.m_storage); +} + +/*! + Returns true if \a other is the same node as this. + */ +bool QXmlNodeModelIndex::operator!=(const QXmlNodeModelIndex &other) const +{ + return !(operator==(other)); +} + +/*! + \fn QXmlNodeModelIndex::QXmlNodeModelIndex() + + Default constructor. Creates an item that is \c null. + + \sa isNull() + */ + +/*! + \fn QXmlNodeModelIndex::QXmlNodeModelIndex(const QXmlNodeModelIndex &other) + + Standard copy constructor. Creates a QXmlNodeModelIndex instance that + is a copy of \a other. + */ + +/*! + \fn bool QXmlNodeModelIndex::isNull() const + + Returns true if this QXmlNodeModelIndex is a default constructed + value, otherwise false. + + A null QXmlNodeModelIndex doesn't represent any node and cannot + be used in conjunction with QAbstractXmlNodeModel. + */ + +/*! + \fn const QAbstractXmlNodeModel *QXmlNodeModelIndex::model() const + + Returns the QAbstractXmlNodeModel that this node index refers to. + QXmlNodeModelIndex does not own QAbstractXmlNodeModel and does not + keep track of its lifetime, so this pointer will dangle if the + QAbstractXmlNodeModel is deallocated first. + + There is no setter for the node model because instances of + QXmlNodeModelIndex instances are only created with + QAbstractXmlNodeModel::createIndex(). +*/ + +/*! + \fn qint64 QXmlNodeModelIndex::data() const + + Returns the first data value. The node index holds two data values. + additionalData() returns the second one. + + \sa additionalData() +*/ + +/*! + \fn void *QXmlNodeModelIndex::internalPointer() const + + Returns the first data value as a void* pointer. + + \sa additionalData() +*/ + +/*! + \fn qint64 QXmlNodeModelIndex::additionalData() const + + Returns the second data value. The node index holds two data values. + data() returns the first one. + + \sa data() +*/ + +/*! + \fn void QXmlNodeModelIndex::reset() + \internal + + Resets this QXmlNodeModelIndex to be null. It is equivalent to + writing: + + \snippet doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlnodemodel.cpp 0 + */ + +/*! + \fn QXmlName QXmlNodeModelIndex::name() const + \internal +*/ + +/*! + \typedef QXmlNodeModelIndex::Iterator + \internal + + Typedef for QAbstractXmlForwardIterator. + */ +/*! + \fn QXmlNodeModelIndex QXmlNodeModelIndex::root() const + \internal +*/ + +/*! + \fn QExplicitlySharedDataPointer > QXmlNodeModelIndex::iterate(const Axis axis) const + \internal +*/ + +/*! + \fn QExplicitlySharedDataPointer > QXmlNodeModelIndex::sequencedTypedValue() const + \internal +*/ + +/*! + \fn QUrl QXmlNodeModelIndex::documentUri() const + \internal +*/ + +/*! + \fn QUrl QXmlNodeModelIndex::baseUri() const + \internal +*/ + +/*! + \fn NodeKind QXmlNodeModelIndex::kind() const + \internal +*/ + +/*! + \fn bool QXmlNodeModelIndex::isDeepEqual(const QXmlNodeModelIndex &other) const + \internal +*/ + +/*! + \fn DocumentOrder QXmlNodeModelIndex::compareOrder(const QXmlNodeModelIndex &other) const + \internal +*/ + +/*! + \fn void QXmlNodeModelIndex::sendNamespaces(QAbstractXmlReceiver *const receiver) const + \internal +*/ + +/*! + \fn QVector QXmlNodeModelIndex::namespaceBindings() const + \internal +*/ + +/*! + \fn QXmlNodeModelIndex QAbstractXmlNodeModel::elementById(const QXmlName &id) const + + Returns the index of the element identified as \a id. XQuery's \c + id() function calls this function. + + The node index returned will be the element node whose value is of + type \c ID and equals \a id, or it will be the element node that has + an attribute whose typed value is of type \c ID and equals \a id. If + there is no such element, a default constructed QXmlNodeModelIndex + instance is returned. The implementor guarantees that if the returned + node index is not null, it identifies an element. + + It is not sufficient for an attribute or element to merely be called + \c id. Its value type must also be \c ID. However, the reserved name + \c xml:id is sufficient. + + In \a id, the \c{namespace URI} and the \c{prefix} are undefined, and + the \c{local name} is the ID that should be looked up. + + \sa {http://www.w3.org/TR/xpath-functions/#func-id}{XQuery 1.0 and XPath 2.0 Functions and Operators, 15.5.2 fn:id} + */ + +/*! + \fn QVector QAbstractXmlNodeModel::nodesByIdref(const QXmlName &idref) const + + Returns the elements and/or attributes that have an \c IDREF value + equal to \a idref. XQuery's \c idref() function calls this function. + + The implementor guarantees that the nodes identified by the returned + indexes are elements or attributes. + + It is not sufficient for an attribute or element to merely be called + \c idref. It must also be of type \c IDREF. Elements must be typed as + \c xs:IDREF or \c xs:IDREFS, or, in the case of attributes, as \c + IDREF or \c IDREFS in the schema. + + In \a idref, the \c{namespace URI} and the \c{prefix} are undefined, + and the \c{local name} is the ID that should be looked up. + + \sa {http://www.w3.org/TR/xpath-functions/#func-idref}{XQuery 1.0 and XPath 2.0 Functions and Operators, 15.5.3 fn:idref} + */ + +/*! + \fn QXmlName::NamespaceCode QXmlNodeModelIndex::namespaceForPrefix(const QXmlName::PrefixCode prefix) const + \internal +*/ + +/*! + \fn QString QXmlNodeModelIndex::stringValue() const + \internal +*/ + +/*! + \fn QPatternist::ItemTypePtr QXmlNodeModelIndex::type() const + \internal +*/ + +/*! + \fn bool QXmlNodeModelIndex::is(const QXmlNodeModelIndex &other) const + \internal +*/ + +/*! + \enum QAbstractXmlNodeModel::NodeCopySetting + \internal + + Controls how nodes are copied with copyNodeTo. + + \value InheritNamespaces Copies the node with the \c copy-namespaces + setting being \c inherit. If not set, \c no-inherit is assumed. + \value PreserveNamespaces Copies the node with the \c copy-namespaces + settings being \c preserve. If not set, \c no-preserve is assumed. + */ + +/*! + \typedef QAbstractXmlNodeModel::NodeCopySettings + \internal + */ + +/*! + \internal + + Copies node \a node to \a receiver, steered by \a copySettings. + + The caller guarantees that \a node is not \c null, and that is + belongs to this QAbstractXmlNodeModel instance. + + The caller guarantees that \a receiver is not \c null. +*/ +void QAbstractXmlNodeModel::copyNodeTo(const QXmlNodeModelIndex &node, + QAbstractXmlReceiver *const receiver, + const NodeCopySettings ©Settings) const +{ + Q_UNUSED(node); + Q_UNUSED(receiver); + Q_UNUSED(copySettings); + Q_ASSERT_X(false, Q_FUNC_INFO, + "This function is not expected to be called."); +} + +/*! + Returns the source location for the object with the given \a index + or a default constructed QSourceLocation in case no location + information is available. + + \since 4.6 +*/ +QSourceLocation QAbstractXmlNodeModel::sourceLocation(const QXmlNodeModelIndex &index) const +{ + // TODO: make this method virtual in Qt5 to allow source location support in custom models + if (d_ptr) + return d_ptr->sourceLocation(index); + else + return QSourceLocation(); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/api/qabstractxmlnodemodel.h b/src/xmlpatterns/api/qabstractxmlnodemodel.h new file mode 100644 index 0000000..808e752 --- /dev/null +++ b/src/xmlpatterns/api/qabstractxmlnodemodel.h @@ -0,0 +1,429 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QABSTRACTXMLNODEMODEL_H +#define QABSTRACTXMLNODEMODEL_H + +#include +#include +#include + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +QT_MODULE(XmlPatterns) + +/* This file contains the classes QXmlNodeModelIndex, QAbstractXmlNodeModel, + * QXmlItem and QPatternist::NodeIndexStorage. */ + +class QAbstractXmlNodeModel; +class QAbstractXmlNodeModelPrivate; +class QAbstractXmlReceiver; +class QSourceLocation; +class QUrl; +class QXmlName; +class QXmlNodeModelIndex; +template class QAbstractXmlForwardIterator; +template class QVector; + +/* The members in the namespace QPatternist are internal, not part of the public API, and + * unsupported. Using them leads to undefined behavior. */ +namespace QPatternist +{ + class DynamicContext; + class Item; + class ItemType; + class XsdValidatedXmlNodeModel; + template class ItemMappingIterator; + template class SequenceMappingIterator; + typedef QExplicitlySharedDataPointer ItemTypePtr; + typedef QExplicitlySharedDataPointer > ItemIteratorPtr; + typedef QVector QXmlNameVector; + + class NodeIndexStorage + { + public: + typedef qint64 Data; + + /*! + \note Changing merely the order of these two members, ptr and data, + is a binary incompatible change on Mac Power PC. + */ + union + { + void *ptr; // Do not use ptr directy, use pointer() instead. + Data data; + }; + void *pointer() const + { + /* Constructing to qptrdiff means we avoid the warning "cast to pointer + * from integer of different size." + */ + return (void *)qptrdiff(data); + } + + Data additionalData; + const QAbstractXmlNodeModel *model; + + /* Implementation is in qabstractxmlnodemodel.cpp. */ + inline bool operator!=(const NodeIndexStorage &other) const; + }; +} + +class Q_XMLPATTERNS_EXPORT QXmlNodeModelIndex +{ + enum Constants + { + ForwardAxis = 8192, + ReverseAxis = 16384 + }; + +public: + inline QXmlNodeModelIndex() + { + reset(); + } + + inline QXmlNodeModelIndex(const QXmlNodeModelIndex &other) : m_storage(other.m_storage) + { + } + + bool operator==(const QXmlNodeModelIndex &other) const; + bool operator!=(const QXmlNodeModelIndex &other) const; + + typedef QAbstractXmlForwardIterator Iterator; + typedef QList List; + + enum NodeKind + { + Attribute = 1, + Comment = 2, + Document = 4, + Element = 8, + Namespace = 16, + ProcessingInstruction = 32, + Text = 64 + }; + + enum DocumentOrder + { + Precedes = -1, + Is = 0, + Follows = 1 + }; + + enum Axis + { + AxisChild = 1 | ForwardAxis, + AxisDescendant = 2 | ForwardAxis, + AxisAttribute = 4 | ForwardAxis, + AxisSelf = 8 | ForwardAxis, + AxisDescendantOrSelf = 16 | ForwardAxis, + AxisFollowingSibling = 32 | ForwardAxis, + AxisNamespace = 64 | ForwardAxis, + AxisFollowing = 128 | ReverseAxis, + AxisParent = 256 | ReverseAxis, + AxisAncestor = 512 | ReverseAxis, + AxisPrecedingSibling = 1024 | ReverseAxis, + AxisPreceding = 2048 | ReverseAxis, + AxisAncestorOrSelf = 4096 | ReverseAxis, + /* Note that we cannot clash with the values of ForwardAxis and + * ReverseAxis. */ + AxisChildOrTop = 32768 | ForwardAxis, + AxisAttributeOrTop = 65536 | ForwardAxis + }; + + inline qint64 data() const + { + return m_storage.data; + } + + inline void *internalPointer() const + { + return m_storage.pointer(); + } + + inline const QAbstractXmlNodeModel *model() const + { + return m_storage.model; + } + + inline qint64 additionalData() const + { + return m_storage.additionalData; + } + + inline bool isNull() const + { + return !m_storage.model; + } + + /* The members below are internal, not part of the public API, and + * unsupported. Using them leads to undefined behavior. */ + + inline QXmlName name() const; + inline QXmlNodeModelIndex root() const; + inline QExplicitlySharedDataPointer > iterate(const Axis axis) const; + inline QExplicitlySharedDataPointer > sequencedTypedValue() const; + inline QUrl documentUri() const; + inline QUrl baseUri() const; + inline NodeKind kind() const; + inline bool isDeepEqual(const QXmlNodeModelIndex &other) const; + inline DocumentOrder compareOrder(const QXmlNodeModelIndex &other) const; + inline void sendNamespaces(QAbstractXmlReceiver *const receiver) const; + inline QVector namespaceBindings() const; + inline QXmlName::NamespaceCode namespaceForPrefix(const QXmlName::PrefixCode prefix) const; + inline QString stringValue() const; + inline QPatternist::ItemTypePtr type() const; + inline bool is(const QXmlNodeModelIndex &other) const; + + inline void reset() + { + m_storage.data = 0; + m_storage.additionalData = 0; + m_storage.model = 0; + } + +private: + static inline QXmlNodeModelIndex create(const qint64 d, + const QAbstractXmlNodeModel *const nm) + { + QXmlNodeModelIndex n; + n.m_storage.data = d; + n.m_storage.model = nm; + n.m_storage.additionalData = 0; + return n; + } + + static inline QXmlNodeModelIndex create(const qint64 data, + const QAbstractXmlNodeModel *const nm, + const qint64 addData) + { + QXmlNodeModelIndex n; + n.m_storage.data = data; + n.m_storage.model = nm; + n.m_storage.additionalData = addData; + return n; + } + + inline QXmlNodeModelIndex(const QPatternist::NodeIndexStorage &storage) : m_storage(storage) + { + } + + friend class QAbstractXmlNodeModel; + friend class QPatternist::Item; + friend class QXmlItem; + inline operator int() const; // Disable + + QPatternist::NodeIndexStorage m_storage; +}; + +Q_XMLPATTERNS_EXPORT uint qHash(const QXmlNodeModelIndex &index); + +inline bool qIsForwardIteratorEnd(const QXmlNodeModelIndex &item) +{ + return item.isNull(); +} + +class Q_XMLPATTERNS_EXPORT QAbstractXmlNodeModel : public QSharedData +{ +public: + enum SimpleAxis + { + Parent, + FirstChild, + PreviousSibling, + NextSibling + }; + + typedef QExplicitlySharedDataPointer Ptr; + typedef QList List; + + QAbstractXmlNodeModel(); + virtual ~QAbstractXmlNodeModel(); + + virtual QUrl baseUri(const QXmlNodeModelIndex &ni) const = 0; + virtual QUrl documentUri(const QXmlNodeModelIndex &ni) const = 0; + virtual QXmlNodeModelIndex::NodeKind kind(const QXmlNodeModelIndex &ni) const = 0; + virtual QXmlNodeModelIndex::DocumentOrder compareOrder(const QXmlNodeModelIndex &ni1, + const QXmlNodeModelIndex &ni2) const = 0; + virtual QXmlNodeModelIndex root(const QXmlNodeModelIndex &n) const = 0; + virtual QXmlName name(const QXmlNodeModelIndex &ni) const = 0; + virtual QString stringValue(const QXmlNodeModelIndex &n) const = 0; + virtual QVariant typedValue(const QXmlNodeModelIndex &n) const = 0; + + /* The members below are internal, not part of the public API, and + * unsupported. Using them leads to undefined behavior. */ + virtual QExplicitlySharedDataPointer > iterate(const QXmlNodeModelIndex &ni, QXmlNodeModelIndex::Axis axis) const; + virtual QPatternist::ItemIteratorPtr sequencedTypedValue(const QXmlNodeModelIndex &ni) const; + virtual QPatternist::ItemTypePtr type(const QXmlNodeModelIndex &ni) const; + virtual QXmlName::NamespaceCode namespaceForPrefix(const QXmlNodeModelIndex &ni, + const QXmlName::PrefixCode prefix) const; + virtual bool isDeepEqual(const QXmlNodeModelIndex &ni1, + const QXmlNodeModelIndex &ni2) const; + virtual void sendNamespaces(const QXmlNodeModelIndex &n, + QAbstractXmlReceiver *const receiver) const; + virtual QVector namespaceBindings(const QXmlNodeModelIndex &n) const = 0; + + + virtual QXmlNodeModelIndex elementById(const QXmlName &NCName) const = 0; + virtual QVector nodesByIdref(const QXmlName &NCName) const = 0; + + enum NodeCopySetting + { + InheritNamespaces = 0x1, + PreserveNamespaces = 0x2 + }; + + typedef QFlags NodeCopySettings; + virtual void copyNodeTo(const QXmlNodeModelIndex &node, + QAbstractXmlReceiver *const receiver, + const NodeCopySettings &) const; + + QSourceLocation sourceLocation(const QXmlNodeModelIndex &index) const; + +protected: + + virtual QXmlNodeModelIndex nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &origin) const = 0; + virtual QVector attributes(const QXmlNodeModelIndex &element) const = 0; + + QAbstractXmlNodeModel(QAbstractXmlNodeModelPrivate *d); + + inline QXmlNodeModelIndex createIndex(qint64 data) const + { + return QXmlNodeModelIndex::create(data, this); + } + + inline QXmlNodeModelIndex createIndex(void * pointer, + qint64 additionalData = 0) const + { + return QXmlNodeModelIndex::create(qptrdiff(pointer), this, additionalData); + } + + inline QXmlNodeModelIndex createIndex(qint64 data, + qint64 additionalData) const + { + return QXmlNodeModelIndex::create(data, this, additionalData); + } + + QScopedPointer d_ptr; +private: + friend class QPatternist::ItemMappingIterator >; + friend class QPatternist::SequenceMappingIterator; + friend class QPatternist::XsdValidatedXmlNodeModel; + + inline QExplicitlySharedDataPointer > mapToSequence(const QXmlNodeModelIndex &ni, + const QExplicitlySharedDataPointer &) const; + + static inline bool isIgnorableInDeepEqual(const QXmlNodeModelIndex &n); + Q_DISABLE_COPY(QAbstractXmlNodeModel) +}; + +Q_DECLARE_TYPEINFO(QXmlNodeModelIndex, Q_MOVABLE_TYPE); + +template class QAbstractXmlForwardIterator; +class QVariant; +class QXmlItemPrivate; + +namespace QPatternist +{ + class AtomicValue; + class VariableLoader; + class IteratorBridge; + class ToQXmlItemMapper; + class ToItemMapper; +} + +class Q_XMLPATTERNS_EXPORT QXmlItem +{ +public: + typedef QAbstractXmlForwardIterator Iterator; + + QXmlItem(); + QXmlItem(const QXmlItem &other); + QXmlItem(const QXmlNodeModelIndex &node); + QXmlItem(const QVariant &atomicValue); + ~QXmlItem(); + QXmlItem &operator=(const QXmlItem &other); + + bool isNull() const; + bool isNode() const; + bool isAtomicValue() const; + + QVariant toAtomicValue() const; + QXmlNodeModelIndex toNodeModelIndex() const; + +private: + friend class QPatternist::IteratorBridge; + friend class QPatternist::VariableLoader; + friend class QPatternist::ToQXmlItemMapper; + friend class QPatternist::ToItemMapper; + friend class QPatternist::Item; + + inline bool internalIsAtomicValue() const; + + inline QXmlItem(const QPatternist::Item &i); + + union + { + QPatternist::NodeIndexStorage m_node; + + /* These two sits at the position of NodeIndexStorage::data. + * NodeIndexStorage::{additionalData,model} are free. */ + const QPatternist::AtomicValue *m_atomicValue; + QXmlItemPrivate * m_ptr; /* Not currently used. */ + }; +}; + +inline bool qIsForwardIteratorEnd(const QXmlItem &item) +{ + return item.isNull(); +} + +Q_DECLARE_TYPEINFO(QXmlItem, Q_MOVABLE_TYPE); + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QXmlItem) /* This macro must appear after QT_END_NAMESPACE. */ + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qabstractxmlnodemodel_p.h b/src/xmlpatterns/api/qabstractxmlnodemodel_p.h new file mode 100644 index 0000000..d4c2060 --- /dev/null +++ b/src/xmlpatterns/api/qabstractxmlnodemodel_p.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QABSTRACTXMLNODEMODEL_P_H +#define QABSTRACTXMLNODEMODEL_P_H + +#include "qabstractxmlnodemodel.h" +#include "qsourcelocation.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QAbstractXmlNodeModelPrivate +{ +public: + virtual ~QAbstractXmlNodeModelPrivate() + { + } + + virtual QSourceLocation sourceLocation(const QXmlNodeModelIndex &index) const + { + Q_UNUSED(index); + + return QSourceLocation(); + } +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qabstractxmlpullprovider.cpp b/src/xmlpatterns/api/qabstractxmlpullprovider.cpp new file mode 100644 index 0000000..6dbd50b --- /dev/null +++ b/src/xmlpatterns/api/qabstractxmlpullprovider.cpp @@ -0,0 +1,177 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qxmlname.h" +#include "qnamepool_p.h" +#include "qabstractxmlpullprovider_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +// TODO have example where query selects, and the events for the result are indented + +/*! + \internal + \class AbstractXmlPullProvider + \brief The AbstractXmlPullProvider class provides a pull-based stream interface for the XPath Data Model. + \reentrant + \ingroup xml-tools + + AbstractXmlPullProvider allows a stream of items from the XPath Data Model -- essentially XML -- + to be iterated over. The subclass of AbstractXmlPullProvider provides the events, and the + user calling next() and so on, consumes them. AbstractXmlPullProvider can be considered + a forward-only, non-reversible iterator. + + Note that the content the events describes, are not necessarily a well-formed XML document, but + rather an instance of the XPath Data model, to be specific. For instance, maybe a pull provider + returns two atomic values, followed by an element tree, and at the end two document nodes. + + If you are subclassing AbstractXmlPullProvider, be careful to correctly implement + the behaviors, as described for the individual members and events. + + \sa AbstractXmlPullProvider::Event + */ + +/*! + \enum AbstractXmlPullProvider::Event + \value StartOfInput The value AbstractXmlPullProvider::current() returns before the first call to next(). + \value AtomicValue an atomic value such as an \c xs:integer, \c xs:hexBinary, or \c xs:dateTime. Atomic values + can only be top level items. + \value StartDocument Signals the start of a document node. Note that a AbstractXmlPullProvider can provide + a sequence of document nodes. + \value EndDocument Signals the end of a document node. StartDocument and EndDocument are always balanced + and always top-level events. For instance, StartDocument can never appear after any StartElement + events that hasn't been balanced by the corresponding amount of EndElement events. + \value StartElement Signals an element start tag. + \value EndElement Signals the end of an element. StartElement and EndElement events are always balanced. + \value Text Signals a text node. Adjacent text nodes cannot occur. + \value ProcessingInstruction A processing instruction. Its name is returned from name(), and its value in stringValue(). + \value Comment a comment node. Its value can be retrieved with stingValue(). + \value Attribute Signals an attribute node. Attribute events can only appear after Namespace events, or + if no such are sent, after the StartElement. In addition they must appear sequentially, + and each name must be unique. The ordering of attribute events is undefined and insignificant. + \value Namespace Signals a namespace binding. They occur very infrequently and are not needed for attributes + and elements. Namespace events can only appear after the StartElement event. The + ordering of namespace events is undefined and insignificant. + \value EndOfInput When next() is called after the last event, EndOfInput is returned. + + \sa AbstractXmlPullProvider::current() + */ + +/*! + Constucts a AbstractXmlPullProvider instance. + */ +AbstractXmlPullProvider::AbstractXmlPullProvider() +{ +} + +/*! + Destructs this AbstractXmlPullProvider. + */ +AbstractXmlPullProvider::~AbstractXmlPullProvider() +{ +} + +/*! + \fn Event AbstractXmlPullProvider::next() = 0; + Advances this AbstractXmlPullProvider, and returns the new event. + + \sa current() + */ + +/*! + \fn Event AbstractXmlPullProvider::current() const = 0; + Returns the event that next() returned the last time it was called. It doesn't + alter this AbstractXmlPullProvider. + + current() may not modify this AbstractXmlPullProvider's state. Subsequent calls to current() + must return the same value. + + \sa AbstractXmlPullProvider::Event + */ + +/*! + \fn QName AbstractXmlPullProvider::name() const = 0; + If the current event is StartElement, + EndElement, ProcessingInstruction, Attribute, or Namespace, the node's name is returned. + + If the current event is ProcessingInstruction, + the processing instruction target is in in the local name. + + If the current event is Namespace, the name's namespace URI is the namespace, and + the local name is the prefix the name is binding to. + + In all other cases, an invalid QName is returned. + */ + +/*! + \fn QVariant AbstractXmlPullProvider::atomicValue() const = 0; + + If current() event is AtomicValue, the atomic value is returned as a QVariant. + In all other cases, this function returns a null QVariant. + */ + +/*! + \fn QString AbstractXmlPullProvider::stringValue() const = 0; + + If current() is Text, the text node's value is returned. + + If the current() event is Comment, its value is returned. The subclasser guarantees + it does not contain the string "-->". + + If the current() event is ProcessingInstruction, its data is returned. The subclasser + guarantees the data does not contain the string "?>". + + In other cases, it returns a default constructed string. + */ + +/*! + \fn QHash AbstractXmlPullProvider::attributes() = 0; + + If the current() is Element, the attributes of the element are returned, + an empty list of attributes otherwise. + */ + +QT_END_NAMESPACE + diff --git a/src/xmlpatterns/api/qabstractxmlpullprovider_p.h b/src/xmlpatterns/api/qabstractxmlpullprovider_p.h new file mode 100644 index 0000000..547bf4b --- /dev/null +++ b/src/xmlpatterns/api/qabstractxmlpullprovider_p.h @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QABSTRACTXMLPULLPROVIDER_H +#define QABSTRACTXMLPULLPROVIDER_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QXmlItem; +class QXmlName; +class QString; +class QVariant; +template class QHash; + +namespace QPatternist +{ + class AbstractXmlPullProviderPrivate; + + class AbstractXmlPullProvider + { + public: + AbstractXmlPullProvider(); + virtual ~AbstractXmlPullProvider(); + + enum Event + { + StartOfInput = 1, + AtomicValue = 1 << 1, + StartDocument = 1 << 2, + EndDocument = 1 << 3, + StartElement = 1 << 4, + EndElement = 1 << 5, + Text = 1 << 6, + ProcessingInstruction = 1 << 7, + Comment = 1 << 8, + Attribute = 1 << 9, + Namespace = 1 << 10, + EndOfInput = 1 << 11 + }; + + virtual Event next() = 0; + virtual Event current() const = 0; + virtual QXmlName name() const = 0; + virtual QVariant atomicValue() const = 0; + virtual QString stringValue() const = 0; + + virtual QHash attributes() = 0; + virtual QHash attributeItems() = 0; + + /* *** The functions below are internal. */ + private: + Q_DISABLE_COPY(AbstractXmlPullProvider) + AbstractXmlPullProviderPrivate *d; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qabstractxmlreceiver.cpp b/src/xmlpatterns/api/qabstractxmlreceiver.cpp new file mode 100644 index 0000000..2b7c295 --- /dev/null +++ b/src/xmlpatterns/api/qabstractxmlreceiver.cpp @@ -0,0 +1,475 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qitem_p.h" + +#include "qabstractxmlreceiver_p.h" +#include "qabstractxmlreceiver.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QAbstractXmlReceiver + \brief The QAbstractXmlReceiver class provides a callback interface + for transforming the output of a QXmlQuery. + \reentrant + \since 4.4 + \ingroup xml-tools + + QAbstractXmlReceiver is an abstract base class that provides + a callback interface for receiving an \l {XQuery Sequence} + {XQuery sequence}, usually the output of an QXmlQuery, and + transforming that sequence into a structure of your choosing, + usually XML. Consider the example: + + \snippet doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlreceiver.cpp 0 + + First it constructs a \l {QXmlQuery} {query} that gets the + first paragraph from document \c index.html. Then it constructs + an \l {QXmlSerializer} {XML serializer} with the \l {QXmlQuery} + {query} and \l {QIODevice} {myOutputDevice} (Note the + \l {QXmlSerializer} {serializer} is an \e {XML receiver}, + ie a subclass of QAbstractXmlReceiver). Finally, it + \l {QXmlQuery::evaluateTo()} {evaluates} the + \l {QXmlQuery} {query}, producing an ordered sequence of calls + to the \l {QXmlSerializer} {serializer's} callback functions. + The sequence of callbacks transforms the query output to XML + and writes it to \l {QIODevice} {myOutputDevice}. + + Although the example uses \l {QXmlQuery} to produce the sequence + of callbacks to functions in QAbstractXmlReceiver, you can call + the callback functions directly as long as your sequence of + calls represents a valid \l {XQuery Sequence} {XQuery sequence}. + + \target XQuery Sequence + \section1 XQuery Sequences + + An XQuery \a sequence is an ordered collection of zero, one, + or many \e items. Each \e item is either an \e {atomic value} + or a \e {node}. An \e {atomic value} is a simple data value. + + There are six kinds of \e nodes. + + \list + + \o An \e {Element Node} represents an XML element. + + \o An \e {Attribute Node} represents an XML attribute. + + \o A \e {Document Node} represents an entire XML document. + + \o A \e {Text Node} represents character data (element content). + + \o A \e {Processing Instruction Node} represents an XML + processing instruction, which is used in an XML document + to tell the application reading the document to perform + some action. A typical example is to use a processing + instruction to tell the application to use a particular + XSLT stylesheet to display the document. + + \o And a \e {Comment node} represents an XML comment. + + \endlist + + The \e sequence of \e nodes and \e {atomic values} obeys + the following rules. Note that \e {Namespace Node} refers + to a special \e {Attribute Node} with name \e {xmlns}. + + \list + + \o Each \e node appears in the \e sequence before its children + and their descendants appear. + + \o A \e node's descendants appear in the \e sequence before + any of its siblings appear. + + \o A \e {Document Node} represents an entire document. Zero or + more \e {Document Nodes} can appear in a \e sequence, but they + can only be top level items (i.e., a \e {Document Node} can't + be a child of another \e node. + + \o \e {Namespace Nodes} immediately follow the \e {Element Node} + with which they are associated. + + \o \e {Attribute Nodes} immediately follow the \e {Namespace Nodes} + of the element with which they are associated, or... + + \o If there are no \e {Namespace Nodes} following an element, then + the \e {Attribute Nodes} immediately follow the element. + + \o An \e {atomic value} can only appear as a top level \e item, + i.e., it can't appear as a child of a \e node. + + \o \e {Processing Instruction Nodes} do not have children, and + their parent is either a \e {Document Node} or an \e {Element + Node}. + + \o \e {Comment Nodes} do not have children, and + their parent is either a \e {Document Node} or an \e {Element + Node}. + + \endlist + + The \e sequence of \e nodes and \e {atomic values} is sent to + an QAbstractXmlReceiver (QXmlSerializer in + the example above) as a sequence of calls to the receiver's + callback functions. The mapping of callback functions to + sequence items is as follows. + + \list + + \o startDocument() and endDocument() are called for each + \e {Document Node} in the \e sequence. endDocument() is not + called until all the \e {Document Node's} children have + appeared in the \e sequence. + + \o startElement() and endElement() are called for each + \e {Element Node}. endElement() is not called until all the + \e {Element Node's} children have appeared in the \e sequence. + + \o attribute() is called for each \e {Attribute Node}. + + \o comment() is called for each \e {Comment Node}. + + \o characters() is called for each \e {Text Node}. + + \o processingInstruction() is called for each \e {Processing + Instruction Node}. + + \o namespaceBinding() is called for each \e {Namespace Node}. + + \o atomicValue() is called for each \e {atomic value}. + + \endlist + + For a complete explanation of XQuery sequences, visit + \l {http://www.w3.org/TR/xpath-datamodel/}{XQuery Data Model}. + + \sa {http://www.w3.org/TR/xpath-datamodel/}{W3C XQuery 1.0 and XPath 2.0 Data Model (XDM)} + \sa QXmlSerializer + \sa QXmlResultItems + */ + +template +void QAbstractXmlReceiver::sendFromAxis(const QXmlNodeModelIndex &node) +{ + Q_ASSERT(!node.isNull()); + const QXmlNodeModelIndex::Iterator::Ptr it(node.iterate(axis)); + QXmlNodeModelIndex next(it->next()); + + while(!next.isNull()) + { + sendAsNode(next); + next = it->next(); + } +} + +/*! + \internal + */ +QAbstractXmlReceiver::QAbstractXmlReceiver(QAbstractXmlReceiverPrivate *d) + : d_ptr(d) +{ +} + +/*! + Constructs an abstract xml receiver. + */ +QAbstractXmlReceiver::QAbstractXmlReceiver() : d_ptr(0) +{ +} + +/*! + Destroys the xml receiver. + */ +QAbstractXmlReceiver::~QAbstractXmlReceiver() +{ +} + +/*! + \fn void QAbstractXmlReceiver::startElement(const QXmlName &name) + + This callback is called when a new element node appears + in the \l {XQuery Sequence} {sequence}. \a name is the + valid \l {QXmlName} {name} of the node element. + */ + +/* +### Qt 5: + +Consider how source locations should be communicated. Maybe every signature +should be extended by adding "qint64 line = -1, qint64 column = -1". + */ + +/*! + \fn void QAbstractXmlReceiver::endElement() + + This callback is called when the end of an element node + appears in the \l {XQuery Sequence} {sequence}. +*/ + +/*! + \fn void QAbstractXmlReceiver::attribute(const QXmlName &name, + const QStringRef &value) + This callback is called when an attribute node + appears in the \l {XQuery Sequence} {sequence}. + \a name is the \l {QXmlName} {attribute name} and + the \a value string contains the attribute value. + */ + +/*! + \fn void QAbstractXmlReceiver::comment(const QString &value) + + This callback is called when a comment node appears + in the \l {XQuery Sequence} {sequence}. The \a value + is the comment text, which must not contain the string + "--". + */ + +/*! + \fn void QAbstractXmlReceiver::characters(const QStringRef &value) + + This callback is called when a text node appears in the + \l {XQuery Sequence} {sequence}. The \a value contains + the text. Adjacent text nodes may not occur in the + \l {XQuery Sequence} {sequence}, i.e., this callback must not + be called twice in a row. + */ + +/*! + \fn void QAbstractXmlReceiver::startDocument() + + This callback is called when a document node appears + in the \l {XQuery Sequence} {sequence}. + */ + +/* +### Qt 5: + +Change + virtual void startDocument() = 0; + +To: + virtual void startDocument(const QUrl &uri) = 0; + +Such that it allows the document URI to be communicated. The contract would +allow null QUrls. +*/ + +/*! + \fn void QAbstractXmlReceiver::endDocument() + + This callback is called when the end of a document node + appears in the \l {XQuery Sequence} {sequence}. + */ + +/*! + \fn void QAbstractXmlReceiver::processingInstruction(const QXmlName &target, + const QString &value) + + This callback is called when a processing instruction + appears in the \l {XQuery Sequence} {sequence}. + A processing instruction is used in an XML document + to tell the application reading the document to + perform some action. A typical example is to use a + processing instruction to tell the application to use a + particular XSLT stylesheet to process the document. + + \quotefile doc/src/snippets/patternist/xmlStylesheet.xq + + \a target is the \l {QXmlName} {name} of the processing + instruction. Its \e prefix and \e {namespace URI} must both + be empty. Its \e {local name} is the target. In the above + example, the name is \e {xml-stylesheet}. + + The \a value specifies the action to be taken. Note that + the \a value must not contain the string "?>". In the above + example, the \a value is \e{type="test/xsl" href="formatter.xsl}. + + Generally, use of processing instructions should be avoided, + because they are not namespace aware and in many contexts + are stripped out anyway. Processing instructions can often + be replaced with elements from a custom namespace. + */ + +/*! + \fn void QAbstractXmlReceiver::atomicValue(const QVariant &value) + + This callback is called when an atomic value appears in the \l + {XQuery Sequence} {sequence}. The \a value is a simple \l {QVariant} + {data value}. It is guaranteed to be \l {QVariant::isValid()} + {valid}. + */ + +/*! + \fn virtual void QAbstractXmlReceiver::namespaceBinding(const QXmlName &name) + + This callback is called when a namespace binding is in scope of an + element. A namespace is defined by a URI. In the \l {QXmlName} + \a name, the value of \l {QXmlName::namespaceUri()} is that URI. The + value of \l {QXmlName::prefix()} is the prefix that the URI is bound + to. The local name is insignificant and can be an arbitrary value. + */ + +/*! + \internal + + Treats \a outputItem as a node and calls the appropriate function, + e.g., attribute() or comment(), depending on its + QXmlNodeModelIndex::NodeKind. + + This is a helper function that subclasses can use to multiplex + Nodes received via item(). + */ +void QAbstractXmlReceiver::sendAsNode(const QPatternist::Item &outputItem) +{ + Q_ASSERT(outputItem); + Q_ASSERT(outputItem.isNode()); + const QXmlNodeModelIndex asNode = outputItem.asNode(); + + switch(asNode.kind()) + { + case QXmlNodeModelIndex::Attribute: + { + const QString &v = outputItem.stringValue(); + attribute(asNode.name(), QStringRef(&v)); + return; + } + case QXmlNodeModelIndex::Element: + { + startElement(asNode.name()); + + /* First the namespaces, then attributes, then the children. */ + asNode.sendNamespaces(this); + sendFromAxis(asNode); + sendFromAxis(asNode); + + endElement(); + + return; + } + case QXmlNodeModelIndex::Text: + { + const QString &v = asNode.stringValue(); + characters(QStringRef(&v)); + return; + } + case QXmlNodeModelIndex::ProcessingInstruction: + { + processingInstruction(asNode.name(), outputItem.stringValue()); + return; + } + case QXmlNodeModelIndex::Comment: + { + comment(outputItem.stringValue()); + return; + } + case QXmlNodeModelIndex::Document: + { + startDocument(); + sendFromAxis(asNode); + endDocument(); + return; + } + case QXmlNodeModelIndex::Namespace: + Q_ASSERT_X(false, Q_FUNC_INFO, "Not implemented"); + } + + Q_ASSERT_X(false, Q_FUNC_INFO, + QString::fromLatin1("Unknown node type: %1").arg(asNode.kind()).toUtf8().constData()); +} + +/*! + \internal + + This function may be called instead of characters() if, and only if, + \a value consists only of whitespace. + + The caller gurantees that \a value is not empty. + + \e Whitespace refers to a sequence of characters that are either + spaces, tabs, or newlines, in any order. In other words, not all + the Unicode whitespace category is considered whitespace here. + + However, there is no guarantee or requirement that whitespaceOnly() + is called for text nodes containing whitespace only. characters() + may be called just as well. This is why the default implementation + for whitespaceOnly() calls characters(). + + \sa characters() + */ +void QAbstractXmlReceiver::whitespaceOnly(const QStringRef &value) +{ + Q_ASSERT_X(value.toString().trimmed().isEmpty(), Q_FUNC_INFO, + "The caller must guarantee only whitespace is passed. Use characters() in other cases."); + const QString &v = value.toString(); + characters(QStringRef(&v)); +} + +/*! + \internal + */ +void QAbstractXmlReceiver::item(const QPatternist::Item &item) +{ + if(item.isNode()) + return sendAsNode(item); + else + atomicValue(QPatternist::AtomicValue::toQt(item.asAtomicValue())); +} + +/*! + \fn void QAbstractXmlReceiver::startOfSequence() + + This callback is called once only, right before the + \l {XQuery Sequence} {sequence} begins. + */ + +/*! + \fn void QAbstractXmlReceiver::endOfSequence() + + This callback is called once only, right after the + \l {XQuery Sequence} {sequence} ends. + */ + +QT_END_NAMESPACE + diff --git a/src/xmlpatterns/api/qabstractxmlreceiver.h b/src/xmlpatterns/api/qabstractxmlreceiver.h new file mode 100644 index 0000000..0407730 --- /dev/null +++ b/src/xmlpatterns/api/qabstractxmlreceiver.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QABSTRACTXMLRECEIVER_H +#define QABSTRACTXMLRECEIVER_H + +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(XmlPatterns) + +class QAbstractXmlReceiverPrivate; +class QXmlName; + +namespace QPatternist +{ + class Item; +} + +class Q_XMLPATTERNS_EXPORT QAbstractXmlReceiver +{ +public: + QAbstractXmlReceiver(); + + virtual ~QAbstractXmlReceiver(); + + virtual void startElement(const QXmlName &name) = 0; + virtual void endElement() = 0; + virtual void attribute(const QXmlName &name, + const QStringRef &value) = 0; + virtual void comment(const QString &value) = 0; + virtual void characters(const QStringRef &value) = 0; + virtual void startDocument() = 0; + virtual void endDocument() = 0; + + virtual void processingInstruction(const QXmlName &target, + const QString &value) = 0; + + virtual void atomicValue(const QVariant &value) = 0; + virtual void namespaceBinding(const QXmlName &name) = 0; + virtual void startOfSequence() = 0; + virtual void endOfSequence() = 0; + + /* The members below are internal, not part of the public API, and + * unsupported. Using them leads to undefined behavior. */ + virtual void whitespaceOnly(const QStringRef &value); + virtual void item(const QPatternist::Item &item); + +protected: + QAbstractXmlReceiver(QAbstractXmlReceiverPrivate *d); + QScopedPointer d_ptr; + + void sendAsNode(const QPatternist::Item &outputItem); +private: + template + void sendFromAxis(const QXmlNodeModelIndex &node); + Q_DISABLE_COPY(QAbstractXmlReceiver) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qabstractxmlreceiver_p.h b/src/xmlpatterns/api/qabstractxmlreceiver_p.h new file mode 100644 index 0000000..34fd546 --- /dev/null +++ b/src/xmlpatterns/api/qabstractxmlreceiver_p.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QABSTRACTXMLRECEIVER_P_H +#define QABSTRACTXMLRECEIVER_P_H + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QAbstractXmlReceiverPrivate +{ +public: + virtual ~QAbstractXmlReceiverPrivate() + { + } +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qcoloringmessagehandler.cpp b/src/xmlpatterns/api/qcoloringmessagehandler.cpp new file mode 100644 index 0000000..83dbaee --- /dev/null +++ b/src/xmlpatterns/api/qcoloringmessagehandler.cpp @@ -0,0 +1,198 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qcoloringmessagehandler_p.h" +#include "qxmlpatternistcli_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +ColoringMessageHandler::ColoringMessageHandler(QObject *parent) : QAbstractMessageHandler(parent) +{ + m_classToColor.insert(QLatin1String("XQuery-data"), Data); + m_classToColor.insert(QLatin1String("XQuery-expression"), Keyword); + m_classToColor.insert(QLatin1String("XQuery-function"), Keyword); + m_classToColor.insert(QLatin1String("XQuery-keyword"), Keyword); + m_classToColor.insert(QLatin1String("XQuery-type"), Keyword); + m_classToColor.insert(QLatin1String("XQuery-uri"), Data); + m_classToColor.insert(QLatin1String("XQuery-filepath"), Data); + + /* If you're tuning the colors, take it easy laddie. Take into account: + * + * - Get over your own taste, there's others too on this planet + * - Make sure it works well on black & white + * - Make sure it works well on white & black + */ + insertMapping(Location, CyanForeground); + insertMapping(ErrorCode, RedForeground); + insertMapping(Keyword, BlueForeground); + insertMapping(Data, BlueForeground); + insertMapping(RunningText, DefaultColor); +} + +void ColoringMessageHandler::handleMessage(QtMsgType type, + const QString &description, + const QUrl &identifier, + const QSourceLocation &sourceLocation) +{ + const bool hasLine = sourceLocation.line() != -1; + + switch(type) + { + case QtWarningMsg: + { + if(hasLine) + { + writeUncolored(QXmlPatternistCLI::tr("Warning in %1, at line %2, column %3: %4").arg(QString::fromLatin1(sourceLocation.uri().toEncoded()), + QString::number(sourceLocation.line()), + QString::number(sourceLocation.column()), + colorifyDescription(description))); + } + else + { + writeUncolored(QXmlPatternistCLI::tr("Warning in %1: %2").arg(QString::fromLatin1(sourceLocation.uri().toEncoded()), + colorifyDescription(description))); + } + + break; + } + case QtFatalMsg: + { + const QString errorCode(identifier.fragment()); + Q_ASSERT(!errorCode.isEmpty()); + QUrl uri(identifier); + uri.setFragment(QString()); + + QString location; + + if(sourceLocation.isNull()) + location = QXmlPatternistCLI::tr("Unknown location"); + else + location = QString::fromLatin1(sourceLocation.uri().toEncoded()); + + QString errorId; + /* If it's a standard error code, we don't want to output the + * whole URI. */ + if(uri.toString() == QLatin1String("http://www.w3.org/2005/xqt-errors")) + errorId = errorCode; + else + errorId = QString::fromLatin1(identifier.toEncoded()); + + if(hasLine) + { + writeUncolored(QXmlPatternistCLI::tr("Error %1 in %2, at line %3, column %4: %5").arg(colorify(errorId, ErrorCode), + colorify(location, Location), + colorify(QString::number(sourceLocation.line()), Location), + colorify(QString::number(sourceLocation.column()), Location), + colorifyDescription(description))); + } + else + { + writeUncolored(QXmlPatternistCLI::tr("Error %1 in %2: %3").arg(colorify(errorId, ErrorCode), + colorify(location, Location), + colorifyDescription(description))); + } + break; + } + case QtCriticalMsg: + /* Fallthrough. */ + case QtDebugMsg: + { + Q_ASSERT_X(false, Q_FUNC_INFO, + "message() is not supposed to receive QtCriticalMsg or QtDebugMsg."); + return; + } + } +} + +QString ColoringMessageHandler::colorifyDescription(const QString &in) const +{ + QXmlStreamReader reader(in); + QString result; + result.reserve(in.size()); + ColorType currentColor = RunningText; + + while(!reader.atEnd()) + { + reader.readNext(); + + switch(reader.tokenType()) + { + case QXmlStreamReader::StartElement: + { + if(reader.name() == QLatin1String("span")) + { + Q_ASSERT(m_classToColor.contains(reader.attributes().value(QLatin1String("class")).toString())); + currentColor = m_classToColor.value(reader.attributes().value(QLatin1String("class")).toString()); + } + + continue; + } + case QXmlStreamReader::Characters: + { + result.append(colorify(reader.text().toString(), currentColor)); + continue; + } + case QXmlStreamReader::EndElement: + { + currentColor = RunningText; + continue; + } + /* Fallthrough, */ + case QXmlStreamReader::StartDocument: + /* Fallthrough, */ + case QXmlStreamReader::EndDocument: + continue; + default: + Q_ASSERT_X(false, Q_FUNC_INFO, + "Unexpected node."); + } + } + + Q_ASSERT_X(!reader.hasError(), Q_FUNC_INFO, + "The output from Patternist must be well-formed."); + return result; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/api/qcoloringmessagehandler_p.h b/src/xmlpatterns/api/qcoloringmessagehandler_p.h new file mode 100644 index 0000000..223bed6 --- /dev/null +++ b/src/xmlpatterns/api/qcoloringmessagehandler_p.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the XMLPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ColoringMessageHandler_h +#define Patternist_ColoringMessageHandler_h + +#include + +#include "qcoloroutput_p.h" +#include "qabstractmessagehandler.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + class ColoringMessageHandler : public QAbstractMessageHandler + , private ColorOutput + { + public: + ColoringMessageHandler(QObject *parent = 0); + + protected: + virtual void handleMessage(QtMsgType type, + const QString &description, + const QUrl &identifier, + const QSourceLocation &sourceLocation); + + private: + QString colorifyDescription(const QString &in) const; + + enum ColorType + { + RunningText, + Location, + ErrorCode, + Keyword, + Data + }; + + QHash m_classToColor; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qcoloroutput.cpp b/src/xmlpatterns/api/qcoloroutput.cpp new file mode 100644 index 0000000..9ba7430 --- /dev/null +++ b/src/xmlpatterns/api/qcoloroutput.cpp @@ -0,0 +1,377 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +#include "qcoloroutput_p.h" + +// TODO: rename insertMapping() to insertColorMapping() +// TODO: Use a smart pointer for managing ColorOutputPrivate *d; +// TODO: break out the C++ example into a snippet file + +/* This include must appear here, because if it appears at the beginning of the file for + * instance, it breaks build -- "qglobal.h:628: error: template with + * C linkage" -- on Mac OS X 10.4. */ +#ifndef Q_OS_WIN +#include +#endif + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +namespace QPatternist +{ + class ColorOutputPrivate + { + public: + ColorOutputPrivate() : currentColorID(-1) + + { + /* - QIODevice::Unbuffered because we want it to appear when the user actually calls, performance + * is considered of lower priority. + */ + m_out.open(stderr, QIODevice::WriteOnly | QIODevice::Unbuffered); + + coloringEnabled = isColoringPossible(); + } + + ColorOutput::ColorMapping colorMapping; + int currentColorID; + bool coloringEnabled; + + static const char *const foregrounds[]; + static const char *const backgrounds[]; + + inline void write(const QString &msg) + { + m_out.write(msg.toLocal8Bit()); + } + + static QString escapeCode(const QString &in) + { + QString result; + result.append(QChar(0x1B)); + result.append(QLatin1Char('[')); + result.append(in); + result.append(QLatin1Char('m')); + return result; + } + + private: + QFile m_out; + + /*! + Returns true if it's suitable to send colored output to \c stderr. + */ + inline bool isColoringPossible() const + { +# if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) + /* Windows doesn't at all support ANSI escape codes, unless + * the user install a "device driver". See the Wikipedia links in the + * class documentation for details. */ + return false; +# else + /* We use QFile::handle() to get the file descriptor. It's a bit unsure + * whether it's 2 on all platforms and in all cases, so hopefully this layer + * of abstraction helps handle such cases. */ + return isatty(m_out.handle()); +# endif + } + }; +} + +const char *const ColorOutputPrivate::foregrounds[] = +{ + "0;30", + "0;34", + "0;32", + "0;36", + "0;31", + "0;35", + "0;33", + "0;37", + "1;30", + "1;34", + "1;32", + "1;36", + "1;31", + "1;35", + "1;33", + "1;37" +}; + +const char *const ColorOutputPrivate::backgrounds[] = +{ + "0;40", + "0;44", + "0;42", + "0;46", + "0;41", + "0;45", + "0;43" +}; + +/*! + \class ColorOutput + \since 4.4 + \nonreentrant + \brief Outputs colored messages to \c stderr. + \internal + + ColorOutput is a convenience class for outputting messages to \c + stderr using color escape codes, as mandated in ECMA-48. ColorOutput + will only color output when it is detected to be suitable. For + instance, if \c stderr is detected to be attached to a file instead + of a TTY, no coloring will be done. + + ColorOutput does its best attempt. but it is generally undefined + what coloring or effect the various coloring flags has. It depends + strongly on what terminal software that is being used. + + When using `echo -e 'my escape sequence'`, \c{\033} works as an + initiator but not when printing from a C++ program, despite having + escaped the backslash. That's why we below use characters with + value 0x1B. + + It can be convenient to subclass ColorOutput with a private scope, + such that the functions are directly available in the class using + it. + + \section1 Usage + + To output messages, call write() or writeUncolored(). write() takes + as second argument an integer, which ColorOutput uses as a lookup + key to find the color it should color the text in. The mapping from + keys to colors is done using insertMapping(). Typically this is used + by having enums for the various kinds of messages, which + subsequently are registered. + + \code + enum MyMessage + { + Error, + Important + }; + + ColorOutput output; + output.insertMapping(Error, ColorOutput::RedForeground); + output.insertMapping(Import, ColorOutput::BlueForeground); + + output.write("This is important", Important); + output.write("Jack, I'm only the selected official!", Error); + \endcode + + \sa {http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html} {Bash Prompt HOWTO, 6.1. Colours} + {http://linuxgazette.net/issue51/livingston-blade.html} {Linux Gazette, Tweaking Eterm, Edward Livingston-Blade} + {http://www.ecma-international.org/publications/standards/Ecma-048.htm} {Standard ECMA-48, Control Functions for Coded Character Sets, ECMA International}, + {http://en.wikipedia.org/wiki/ANSI_escape_code} {Wikipedia, ANSI escape code} + {http://linuxgazette.net/issue65/padala.html} {Linux Gazette, So You Like Color!, Pradeep Padala} + */ + +/*! + \enum ColorOutput::ColorCodeComponent + \value BlackForeground + \value BlueForeground + \value GreenForeground + \value CyanForeground + \value RedForeground + \value PurpleForeground + \value BrownForeground + \value LightGrayForeground + \value DarkGrayForeground + \value LightBlueForeground + \value LightGreenForeground + \value LightCyanForeground + \value LightRedForeground + \value LightPurpleForeground + \value YellowForeground + \value WhiteForeground + \value BlackBackground + \value BlueBackground + \value GreenBackground + \value CyanBackground + \value RedBackground + \value PurpleBackground + \value BrownBackground + + \value DefaultColor ColorOutput performs no coloring. This typically + means black on white or white on black, depending + on the settings of the user's terminal. + */ + +/*! + Sets the color mapping to be \a cMapping. + + Negative values are disallowed. + + \sa colorMapping(), insertMapping() + */ +void ColorOutput::setColorMapping(const ColorMapping &cMapping) +{ + d->colorMapping = cMapping; +} + +/*! + Returns the color mappings in use. + + \sa setColorMapping(), insertMapping() + */ +ColorOutput::ColorMapping ColorOutput::colorMapping() const +{ + return d->colorMapping; +} + +/*! + Constructs a ColorOutput instance, ready for use. + */ +ColorOutput::ColorOutput() : d(new ColorOutputPrivate()) +{ +} + +/*! + Destructs this ColorOutput instance. + */ +ColorOutput::~ColorOutput() +{ + delete d; +} + +/*! + Sends \a message to \c stderr, using the color looked up in colorMapping() using \a colorID. + + If \a color isn't available in colorMapping(), result and behavior is undefined. + + If \a colorID is 0, which is the default value, the previously used coloring is used. ColorOutput + is initialized to not color at all. + + If \a message is empty, effects are undefined. + + \a message will be printed as is. For instance, no line endings will be inserted. + */ +void ColorOutput::write(const QString &message, int colorID) +{ + d->write(colorify(message, colorID)); +} + +/*! + Writes \a message to \c stderr as if for instance + QTextStream would have been used, and adds a line ending at the end. + + This function can be practical to use such that one can use ColorOutput for all forms of writing. + */ +void ColorOutput::writeUncolored(const QString &message) +{ + d->write(message + QLatin1Char('\n')); +} + +/*! + Treats \a message and \a colorID identically to write(), but instead of writing + \a message to \c stderr, it is prepared for being written to \c stderr, but is then + returned. + + This is useful when the colored string is inserted into a translated string(dividing + the string into several small strings prevents proper translation). + */ +QString ColorOutput::colorify(const QString &message, int colorID) const +{ + Q_ASSERT_X(colorID == -1 || d->colorMapping.contains(colorID), Q_FUNC_INFO, + qPrintable(QString::fromLatin1("There is no color registered by id %1").arg(colorID))); + Q_ASSERT_X(!message.isEmpty(), Q_FUNC_INFO, "It makes no sense to attempt to print an empty string."); + + if(colorID != -1) + d->currentColorID = colorID; + + if(d->coloringEnabled && colorID != -1) + { + const int color(d->colorMapping.value(colorID)); + + /* If DefaultColor is set, we don't want to color it. */ + if(color & DefaultColor) + return message; + + const int foregroundCode = (int(color) & ForegroundMask) >> ForegroundShift; + const int backgroundCode = (int(color) & BackgroundMask) >> BackgroundShift; + QString finalMessage; + bool closureNeeded = false; + + if(foregroundCode) + { + finalMessage.append(ColorOutputPrivate::escapeCode(QLatin1String(ColorOutputPrivate::foregrounds[foregroundCode - 1]))); + closureNeeded = true; + } + + if(backgroundCode) + { + finalMessage.append(ColorOutputPrivate::escapeCode(QLatin1String(ColorOutputPrivate::backgrounds[backgroundCode - 1]))); + closureNeeded = true; + } + + finalMessage.append(message); + + if(closureNeeded) + { + finalMessage.append(QChar(0x1B)); + finalMessage.append(QLatin1String("[0m")); + } + + return finalMessage; + } + else + return message; +} + +/*! + Adds a color mapping from \a colorID to \a colorCode, for this ColorOutput instance. + + This is a convenience function for creating a ColorOutput::ColorMapping instance and + calling setColorMapping(). + + \sa colorMapping(), setColorMapping() + */ +void ColorOutput::insertMapping(int colorID, const ColorCode colorCode) +{ + d->colorMapping.insert(colorID, colorCode); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/api/qcoloroutput_p.h b/src/xmlpatterns/api/qcoloroutput_p.h new file mode 100644 index 0000000..020cfc2 --- /dev/null +++ b/src/xmlpatterns/api/qcoloroutput_p.h @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the XMLPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ColorOutput_h +#define Patternist_ColorOutput_h + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + class ColorOutputPrivate; + + class ColorOutput + { + enum + { + ForegroundShift = 10, + BackgroundShift = 20, + SpecialShift = 20, + ForegroundMask = ((1 << ForegroundShift) - 1) << ForegroundShift, + BackgroundMask = ((1 << BackgroundShift) - 1) << BackgroundShift + }; + + public: + enum ColorCodeComponent + { + BlackForeground = 1 << ForegroundShift, + BlueForeground = 2 << ForegroundShift, + GreenForeground = 3 << ForegroundShift, + CyanForeground = 4 << ForegroundShift, + RedForeground = 5 << ForegroundShift, + PurpleForeground = 6 << ForegroundShift, + BrownForeground = 7 << ForegroundShift, + LightGrayForeground = 8 << ForegroundShift, + DarkGrayForeground = 9 << ForegroundShift, + LightBlueForeground = 10 << ForegroundShift, + LightGreenForeground = 11 << ForegroundShift, + LightCyanForeground = 12 << ForegroundShift, + LightRedForeground = 13 << ForegroundShift, + LightPurpleForeground = 14 << ForegroundShift, + YellowForeground = 15 << ForegroundShift, + WhiteForeground = 16 << ForegroundShift, + + BlackBackground = 1 << BackgroundShift, + BlueBackground = 2 << BackgroundShift, + GreenBackground = 3 << BackgroundShift, + CyanBackground = 4 << BackgroundShift, + RedBackground = 5 << BackgroundShift, + PurpleBackground = 6 << BackgroundShift, + BrownBackground = 7 << BackgroundShift, + DefaultColor = 1 << SpecialShift + }; + + typedef QFlags ColorCode; + typedef QHash ColorMapping; + + ColorOutput(); + ~ColorOutput(); + + void setColorMapping(const ColorMapping &cMapping); + ColorMapping colorMapping() const; + void insertMapping(int colorID, const ColorCode colorCode); + + void writeUncolored(const QString &message); + void write(const QString &message, int color = -1); + QString colorify(const QString &message, int color = -1) const; + + private: + ColorOutputPrivate *d; + Q_DISABLE_COPY(ColorOutput) + }; +} + +Q_DECLARE_OPERATORS_FOR_FLAGS(QPatternist::ColorOutput::ColorCode) + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qdeviceresourceloader_p.h b/src/xmlpatterns/api/qdeviceresourceloader_p.h new file mode 100644 index 0000000..fbea0a7 --- /dev/null +++ b/src/xmlpatterns/api/qdeviceresourceloader_p.h @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QPatternist_DeviceResourceLoader_p_H +#define QPatternist_DeviceResourceLoader_p_H + +template class QSet; +class QUrl; + +#include "qresourceloader_p.h" + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Base class for resource loaders that manage device variables. + * + * @author Frans Englich + * @since 4.5 + */ + class DeviceResourceLoader : public ResourceLoader + { + public: + typedef QExplicitlySharedDataPointer Ptr; + /** + * @short Returns the URIs for device variables that this + * ResourceLoader has loaded. + * + * The returned set may be empty. + */ + virtual QSet deviceURIs() const = 0; + }; +} + +QT_END_NAMESPACE +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qiodevicedelegate.cpp b/src/xmlpatterns/api/qiodevicedelegate.cpp new file mode 100644 index 0000000..ebd6e41 --- /dev/null +++ b/src/xmlpatterns/api/qiodevicedelegate.cpp @@ -0,0 +1,166 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qpatternistlocale_p.h" + +#include "qiodevicedelegate_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +QIODeviceDelegate::QIODeviceDelegate(QIODevice *const source) : m_source(source) +{ + Q_ASSERT(m_source); + + connect(source, SIGNAL(aboutToClose()), SIGNAL(aboutToClose())); + connect(source, SIGNAL(bytesWritten(qint64)), SIGNAL(bytesWritten(qint64))); + connect(source, SIGNAL(readChannelFinished()), SIGNAL(readChannelFinished())); + connect(source, SIGNAL(readyRead()), SIGNAL(readyRead())); + + /* According to Thiago these two signals are very similar, but QtNetworkAccess uses finished() + * instead for a minor but significant reason. */ + connect(source, SIGNAL(readChannelFinished()), SIGNAL(finished())); + + /* For instance QFile emits no signals, so how do we know if the device has all data available + * and it therefore is safe and correct to emit finished()? isSequential() tells us whether it's + * not random access, and whether it's safe to emit finished(). */ + if(m_source->isSequential()) + QMetaObject::invokeMethod(this, "readyRead", Qt::QueuedConnection); + else + QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); + + setOpenMode(QIODevice::ReadOnly); + + /* Set up the timeout timer. */ + connect(&m_timeout, SIGNAL(timeout()), SLOT(networkTimeout())); + + m_timeout.setSingleShot(true); + m_timeout.start(Timeout); +} + +void QIODeviceDelegate::networkTimeout() +{ + setErrorString(QtXmlPatterns::tr("Network timeout.")); + error(QNetworkReply::TimeoutError); +} + +void QIODeviceDelegate::abort() +{ + /* Do nothing, just to please QNetworkReply's pure virtual. */ +} + +bool QIODeviceDelegate::atEnd() const +{ + return m_source->atEnd(); +} + +qint64 QIODeviceDelegate::bytesAvailable() const +{ + return m_source->bytesAvailable(); +} + +qint64 QIODeviceDelegate::bytesToWrite() const +{ + return m_source->bytesToWrite(); +} + +bool QIODeviceDelegate::canReadLine() const +{ + return m_source->canReadLine(); +} + +void QIODeviceDelegate::close() +{ + return m_source->close(); +} + +bool QIODeviceDelegate::isSequential() const +{ + return m_source->isSequential(); +} + +bool QIODeviceDelegate::open(OpenMode mode) +{ + const bool success = m_source->open(mode); + setOpenMode(m_source->openMode()); + return success; +} + +qint64 QIODeviceDelegate::pos() const +{ + return m_source->pos(); +} + +bool QIODeviceDelegate::reset() +{ + return m_source->reset(); +} + +bool QIODeviceDelegate::seek(qint64 pos) +{ + return m_source->seek(pos); +} + +qint64 QIODeviceDelegate::size() const +{ + return m_source->size(); +} + +bool QIODeviceDelegate::waitForBytesWritten(int msecs) +{ + return m_source->waitForBytesWritten(msecs); +} + +bool QIODeviceDelegate::waitForReadyRead(int msecs) +{ + return m_source->waitForReadyRead(msecs); +} + +qint64 QIODeviceDelegate::readData(char *data, qint64 maxSize) +{ + return m_source->read(data, maxSize); +} + +QT_END_NAMESPACE + diff --git a/src/xmlpatterns/api/qiodevicedelegate_p.h b/src/xmlpatterns/api/qiodevicedelegate_p.h new file mode 100644 index 0000000..456048e --- /dev/null +++ b/src/xmlpatterns/api/qiodevicedelegate_p.h @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QIODEVICEDELEGATE_P_H +#define QIODEVICEDELEGATE_P_H + +#include +#include + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * This is read-only currently. + */ + class QIODeviceDelegate : public QNetworkReply + { + Q_OBJECT + public: + QIODeviceDelegate(QIODevice *const source); + + virtual void abort(); + + virtual bool atEnd() const; + virtual qint64 bytesAvailable() const; + virtual qint64 bytesToWrite() const; + virtual bool canReadLine() const; + virtual void close(); + virtual bool isSequential() const; + virtual bool open(OpenMode mode); + virtual qint64 pos() const; + virtual bool reset(); + virtual bool seek(qint64 pos); + virtual qint64 size() const; + virtual bool waitForBytesWritten(int msecs); + virtual bool waitForReadyRead(int msecs); + + protected: + virtual qint64 readData(char *data, qint64 maxSize); + + private Q_SLOTS: + void networkTimeout(); + private: + enum + { + /** + * 20 seconds expressed in milliseconds. + */ + Timeout = 20000 + }; + + QIODevice *const m_source; + QTimer m_timeout; + }; +} + +QT_END_NAMESPACE + +#endif diff --git a/src/xmlpatterns/api/qnetworkaccessdelegator.cpp b/src/xmlpatterns/api/qnetworkaccessdelegator.cpp new file mode 100644 index 0000000..05c4b8e --- /dev/null +++ b/src/xmlpatterns/api/qnetworkaccessdelegator.cpp @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include + +#include "qnetworkaccessdelegator_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +NetworkAccessDelegator::NetworkAccessDelegator(QNetworkAccessManager *const genericManager, + QNetworkAccessManager *const variableURIManager) : m_genericManager(genericManager) + , m_variableURIManager(variableURIManager) +{ +} + +QNetworkAccessManager *NetworkAccessDelegator::managerFor(const QUrl &uri) +{ + /* Unfortunately we have to do it this way, QUrl::isParentOf() doesn't + * understand URI schemes like this one. */ + const QString requestedUrl(uri.toString()); + + /* On the topic of timeouts: + * + * Currently the schemes QNetworkAccessManager handles should/will do + * timeouts for 4.4, but we need to do timeouts for our own. */ + if(requestedUrl.startsWith(QLatin1String("tag:trolltech.com,2007:QtXmlPatterns:QIODeviceVariable:"))) + return m_variableURIManager; + else + { + if(!m_genericManager) + m_genericManager = new QNetworkAccessManager(this); + + return m_genericManager; + } +} + +QT_END_NAMESPACE + diff --git a/src/xmlpatterns/api/qnetworkaccessdelegator_p.h b/src/xmlpatterns/api/qnetworkaccessdelegator_p.h new file mode 100644 index 0000000..10c229a --- /dev/null +++ b/src/xmlpatterns/api/qnetworkaccessdelegator_p.h @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QNETWORKACCESSDELEGATOR_P_H +#define QNETWORKACCESSDELEGATOR_P_H + +#include +#include +#include + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +class QNetworkAccessManager; +class QUrl; + +namespace QPatternist +{ + /** + * @short A value based class that hands out QNetworkAccessManager + * appropriately for variable bindings. + * + * NetworkAccessDelegator is an indirection mechanism which takes care of + * the fact that QIODevice instances are injected into the data model by + * having them represented using a URI. managerFor() returns appropriately + * the right network access manager depending on whether the URI refers to + * a variable, or to something else. + * + * The constructor take a pointer to two NetworkAccessDelegator instances. + * First is a generic one, the second is the one which handles variable + * bindings. managerFor() then returns the appropriate one depending on the + * URI. + * + * @since 4.5 + * @see AccelTreeResourceLoader::load() + * @author Frans Englich + */ + class Q_AUTOTEST_EXPORT NetworkAccessDelegator : public QObject + , public QSharedData + { + public: + typedef QExplicitlySharedDataPointer Ptr; + NetworkAccessDelegator(QNetworkAccessManager *const genericManager, + QNetworkAccessManager *const variableURIManager); + + QNetworkAccessManager *managerFor(const QUrl &uri); + + QPointer m_genericManager; + QPointer m_variableURIManager; + private: + Q_DISABLE_COPY(NetworkAccessDelegator) + }; +} + +QT_END_NAMESPACE +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qpullbridge.cpp b/src/xmlpatterns/api/qpullbridge.cpp new file mode 100644 index 0000000..80dac38 --- /dev/null +++ b/src/xmlpatterns/api/qpullbridge.cpp @@ -0,0 +1,232 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qabstractxmlnodemodel_p.h" +#include "qitemmappingiterator_p.h" +#include "qitem_p.h" +#include "qxmlname.h" +#include "qxmlquery_p.h" + +#include "qpullbridge_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +/*! + \brief Bridges a QPatternist::SequenceIterator to QAbstractXmlPullProvider. + \class QPatternist::PullBridge + \internal + \reentrant + \ingroup xml-tools + + The approach of this class is rather straight forward since QPatternist::SequenceIterator + and QAbstractXmlPullProvider are conceptually similar. While QPatternist::SequenceIterator only + delivers top level items(since it's not an event stream, it's a list of items), PullBridge + needs to recursively iterate the children of nodes too, which is achieved through the + stack m_iterators. + */ + +AbstractXmlPullProvider::Event PullBridge::next() +{ + m_index = m_iterators.top().second->next(); + + if(!m_index.isNull()) + { + Item item(m_index); + + if(item && item.isAtomicValue()) + m_current = AtomicValue; + else + { + Q_ASSERT(item.isNode()); + + switch(m_index.kind()) + { + case QXmlNodeModelIndex::Attribute: + { + m_current = Attribute; + break; + } + case QXmlNodeModelIndex::Comment: + { + m_current = Comment; + break; + } + case QXmlNodeModelIndex::Element: + { + m_iterators.push(qMakePair(StartElement, m_index.iterate(QXmlNodeModelIndex::AxisChild))); + m_current = StartElement; + break; + } + case QXmlNodeModelIndex::Document: + { + m_iterators.push(qMakePair(StartDocument, m_index.iterate(QXmlNodeModelIndex::AxisChild))); + m_current = StartDocument; + break; + } + case QXmlNodeModelIndex::Namespace: + { + m_current = Namespace; + break; + } + case QXmlNodeModelIndex::ProcessingInstruction: + { + m_current = ProcessingInstruction; + break; + } + case QXmlNodeModelIndex::Text: + { + m_current = Text; + break; + } + } + } + } + else + { + if(m_iterators.isEmpty()) + m_current = EndOfInput; + else + { + switch(m_iterators.top().first) + { + case StartOfInput: + { + m_current = EndOfInput; + break; + } + case StartElement: + { + m_current = EndElement; + m_iterators.pop(); + break; + } + case StartDocument: + { + m_current = EndDocument; + m_iterators.pop(); + break; + } + default: + { + Q_ASSERT_X(false, Q_FUNC_INFO, + "Invalid value."); + m_current = EndOfInput; + } + } + } + + } + + return m_current; +} + +AbstractXmlPullProvider::Event PullBridge::current() const +{ + return m_current; +} + +QXmlNodeModelIndex PullBridge::index() const +{ + return m_index; +} + +QSourceLocation PullBridge::sourceLocation() const +{ + return m_index.model()->sourceLocation(m_index); +} + +QXmlName PullBridge::name() const +{ + return m_index.name(); +} + +QVariant PullBridge::atomicValue() const +{ + return QVariant(); +} + +QString PullBridge::stringValue() const +{ + return QString(); +} + +QHash PullBridge::attributes() +{ + Q_ASSERT(m_current == StartElement); + + QHash attributes; + + QXmlNodeModelIndex::Iterator::Ptr it = m_index.iterate(QXmlNodeModelIndex::AxisAttribute); + QXmlNodeModelIndex index = it->next(); + while (!index.isNull()) { + const Item attribute(index); + attributes.insert(index.name(), index.stringValue()); + + index = it->next(); + } + + return attributes; +} + +QHash PullBridge::attributeItems() +{ + Q_ASSERT(m_current == StartElement); + + QHash attributes; + + QXmlNodeModelIndex::Iterator::Ptr it = m_index.iterate(QXmlNodeModelIndex::AxisAttribute); + QXmlNodeModelIndex index = it->next(); + while (!index.isNull()) { + const Item attribute(index); + attributes.insert(index.name(), QXmlItem(index)); + + index = it->next(); + } + + return attributes; +} + +QT_END_NAMESPACE + diff --git a/src/xmlpatterns/api/qpullbridge_p.h b/src/xmlpatterns/api/qpullbridge_p.h new file mode 100644 index 0000000..1553a3e --- /dev/null +++ b/src/xmlpatterns/api/qpullbridge_p.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef PATTERNIST_PULLBRIDGE_P_H +#define PATTERNIST_PULLBRIDGE_P_H + +#include +#include + +#include "qabstractxmlforwarditerator_p.h" +#include "qabstractxmlpullprovider_p.h" +#include "qitem_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + class PullBridge : public AbstractXmlPullProvider + { + public: + inline PullBridge(const QXmlNodeModelIndex::Iterator::Ptr &it) : m_current(StartOfInput) + { + Q_ASSERT(it); + m_iterators.push(qMakePair(StartOfInput, it)); + } + + virtual Event next(); + virtual Event current() const; + virtual QXmlName name() const; + /** + * Returns always an empty QVariant. + */ + virtual QVariant atomicValue() const; + virtual QString stringValue() const; + virtual QHash attributes(); + virtual QHash attributeItems(); + + QXmlNodeModelIndex index() const; + QSourceLocation sourceLocation() const; + + private: + typedef QStack > IteratorStack; + IteratorStack m_iterators; + QXmlNodeModelIndex m_index; + Event m_current; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qreferencecountedvalue_p.h b/src/xmlpatterns/api/qreferencecountedvalue_p.h new file mode 100644 index 0000000..679660c --- /dev/null +++ b/src/xmlpatterns/api/qreferencecountedvalue_p.h @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QPatternist_ReferenceCountedValue_p_h +#define QPatternist_ReferenceCountedValue_p_h + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ +/*! + \class ReferenceCountedValue + \internal + \since 4.4 + \brief A template class that reference counts a value. + + This class is useful when an instance needs to have ownership semantics + as if it was value based. A typical examples is a QObject pointer, which + doesn't have a single owner. + + This is achieved through storing a copy of the object as + a member inside ReferenceCountedValue, which never is copied. It will + stay in scope until the last reference to the ReferenceCountedValue instance + is removed, and subsequently ReferenceCountedValue is deleted and hence also + the contained value. One should use ReferenceCountedValue by passing around + copies of Ptr, which is a typedef for the QExplicitlySharedDataPointer + smart pointer. +*/ + template + class ReferenceCountedValue : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer > Ptr; + + inline ReferenceCountedValue(T *const v) : value(v) + { + } + + inline ~ReferenceCountedValue() + { + delete value; + } + + T *const value; + private: + /*! + Disabled, no implementation provided. + */ + inline ReferenceCountedValue(); + Q_DISABLE_COPY(ReferenceCountedValue) + }; +} + +QT_END_NAMESPACE +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qresourcedelegator.cpp b/src/xmlpatterns/api/qresourcedelegator.cpp new file mode 100644 index 0000000..cb78666 --- /dev/null +++ b/src/xmlpatterns/api/qresourcedelegator.cpp @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qresourcedelegator_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +bool ResourceDelegator::isUnparsedTextAvailable(const QUrl &uri, + const QString &encoding) +{ + return m_parentLoader->isUnparsedTextAvailable(uri, encoding); +} + +ItemType::Ptr ResourceDelegator::announceUnparsedText(const QUrl &uri) +{ + return m_parentLoader->announceUnparsedText(uri); +} + +Item ResourceDelegator::openUnparsedText(const QUrl &uri, + const QString &encoding, + const ReportContext::Ptr &context, + const SourceLocationReflection *const where) +{ + return m_parentLoader->openUnparsedText(uri, encoding, context, where); +} + +Item ResourceDelegator::openDocument(const QUrl &uri, + const ReportContext::Ptr &context) +{ + if(m_needsOverride.contains(uri)) + return m_forDeviceLoader->openDocument(uri, context); + else + return m_parentLoader->openDocument(uri, context); +} + +SequenceType::Ptr ResourceDelegator::announceDocument(const QUrl &uri, const Usage usageHint) +{ + return m_parentLoader->announceDocument(uri, usageHint); +} + +bool ResourceDelegator::isDocumentAvailable(const QUrl &uri) +{ + return m_parentLoader->isDocumentAvailable(uri); +} + +Item::Iterator::Ptr ResourceDelegator::openCollection(const QUrl &uri) +{ + return m_parentLoader->openCollection(uri); +} + +SequenceType::Ptr ResourceDelegator::announceCollection(const QUrl &uri) +{ + return m_parentLoader->announceCollection(uri); +} + +QSet ResourceDelegator::deviceURIs() const +{ + QSet uris(m_needsOverride); + uris |= m_forDeviceLoader->deviceURIs(); + return uris; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/api/qresourcedelegator_p.h b/src/xmlpatterns/api/qresourcedelegator_p.h new file mode 100644 index 0000000..688a23f --- /dev/null +++ b/src/xmlpatterns/api/qresourcedelegator_p.h @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QPatternist_ResourceDelegator_p_H +#define QPatternist_ResourceDelegator_p_H + +#include +#include + +#include "qdeviceresourceloader_p.h" + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Delegates to another ResourceLoader, but in case a URI is in an + * exception list, it delegates to a different loader. + * + * This is used for handling device variables, since when a device variable + * is rebound, a resource loader needs to carry that binding, while the + * resource loader for the other query remains as is. + * + * @since 4.5 + * @author Frans Englich + */ + class ResourceDelegator : public DeviceResourceLoader + { + public: + ResourceDelegator(const QSet &needsOverride, + const ResourceLoader::Ptr &parentLoader, + const ResourceLoader::Ptr &forDeviceLoader) : m_needsOverride(needsOverride) + , m_parentLoader(parentLoader) + , m_forDeviceLoader(forDeviceLoader) + + { + Q_ASSERT(m_parentLoader); + } + + virtual bool isUnparsedTextAvailable(const QUrl &uri, + const QString &encoding); + virtual ItemType::Ptr announceUnparsedText(const QUrl &uri); + virtual Item openUnparsedText(const QUrl &uri, + const QString &encoding, + const ReportContext::Ptr &context, + const SourceLocationReflection *const where); + virtual Item openDocument(const QUrl &uri, + const ReportContext::Ptr &context); + virtual SequenceType::Ptr announceDocument(const QUrl &uri, const Usage usageHint); + virtual bool isDocumentAvailable(const QUrl &uri); + virtual Item::Iterator::Ptr openCollection(const QUrl &uri); + virtual SequenceType::Ptr announceCollection(const QUrl &uri); + + /** + * Returns the union of the deviceURIs() that ResourceDelegator's two + * resource loaders has. + */ + virtual QSet deviceURIs() const; + + private: + const QSet m_needsOverride; + const ResourceLoader::Ptr m_parentLoader; + const ResourceDelegator::Ptr m_forDeviceLoader; + }; +} + +QT_END_NAMESPACE +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qsimplexmlnodemodel.cpp b/src/xmlpatterns/api/qsimplexmlnodemodel.cpp new file mode 100644 index 0000000..40f99e5 --- /dev/null +++ b/src/xmlpatterns/api/qsimplexmlnodemodel.cpp @@ -0,0 +1,184 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +#include "qabstractxmlnodemodel_p.h" +#include "qemptyiterator_p.h" +#include "qitemmappingiterator_p.h" +#include "qsequencemappingiterator_p.h" +#include "qsimplexmlnodemodel.h" +#include "qsingletoniterator_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +class QSimpleXmlNodeModelPrivate : public QAbstractXmlNodeModelPrivate +{ +public: + QSimpleXmlNodeModelPrivate(const QXmlNamePool &np) : namePool(np) + { + } + + mutable QXmlNamePool namePool; +}; + +/*! + \class QSimpleXmlNodeModel + \brief The QSimpleXmlNodeModel class is an implementation of QAbstractXmlNodeModel sufficient for many common cases. + \reentrant + \since 4.4 + \ingroup xml-tools + + Subclassing QAbstractXmlNodeModel can be a significant task, because it + requires implementing several, complex member functions. QSimpleXmlNodeModel + provides default implementations of these member functions that are suitable + for a wide range of node models. + + Subclasses of QSimpleXmlNodeModel must be thread-safe. + */ + +/*! + Constructs a QSimpleXmlNodeModel for use with with the specified + \a namePool. + */ +QSimpleXmlNodeModel::QSimpleXmlNodeModel(const QXmlNamePool &namePool) + : QAbstractXmlNodeModel(new QSimpleXmlNodeModelPrivate(namePool)) +{ +} + +/*! + Destructor. + */ +QSimpleXmlNodeModel::~QSimpleXmlNodeModel() +{ +} + +/*! + If \a node is an element or attribute, typedValue() is called, and + the return value converted to a string, as per XQuery's rules. + + If \a node is another type of node, the empty string is returned. + + If this function is overridden for comments or processing + instructions, it is important to remember to call it (for elements + and attributes having values not of type \c xs:string) to ensure that + the values are formatted according to XQuery. + + */ +QString QSimpleXmlNodeModel::stringValue(const QXmlNodeModelIndex &node) const +{ + const QXmlNodeModelIndex::NodeKind k= kind(node); + if(k == QXmlNodeModelIndex::Element || k == QXmlNodeModelIndex::Attribute) + { + const QVariant &candidate = typedValue(node); + if(candidate.isNull()) + return QString(); + else + return AtomicValue::toXDM(candidate).stringValue(); + } + else + return QString(); +} + +/*! + Returns the base URI for \a node. This is always the document + URI. + + \sa documentUri() + */ +QUrl QSimpleXmlNodeModel::baseUri(const QXmlNodeModelIndex &node) const +{ + return documentUri(node); +} + +/*! + Returns the name pool associated with this model. The + implementation of name() will use this name pool to create + names. + */ +QXmlNamePool &QSimpleXmlNodeModel::namePool() const +{ + Q_D(const QSimpleXmlNodeModel); + + return d->namePool; +} + +/*! + Always returns an empty QVector. This signals that no namespace + bindings are in scope for \a node. + */ +QVector QSimpleXmlNodeModel::namespaceBindings(const QXmlNodeModelIndex &node) const +{ + Q_UNUSED(node); + return QVector(); +} + +/*! + Always returns a default constructed QXmlNodeModelIndex instance, + regardless of \a id. + + This effectively means the model has no elements that have an id. + */ +QXmlNodeModelIndex QSimpleXmlNodeModel::elementById(const QXmlName &id) const +{ + Q_UNUSED(id); + return QXmlNodeModelIndex(); +} + +/*! + Always returns an empty vector, regardless of \a idref. + + This effectively means the model has no elements or attributes of + type \c IDREF. + */ +QVector QSimpleXmlNodeModel::nodesByIdref(const QXmlName &idref) const +{ + Q_UNUSED(idref); + return QVector(); +} + +QT_END_NAMESPACE + + diff --git a/src/xmlpatterns/api/qsimplexmlnodemodel.h b/src/xmlpatterns/api/qsimplexmlnodemodel.h new file mode 100644 index 0000000..cfbe360 --- /dev/null +++ b/src/xmlpatterns/api/qsimplexmlnodemodel.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSIMPLEXMLNODEMODEL_H +#define QSIMPLEXMLNODEMODEL_H + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(XmlPatterns) + +template class QExplicitlySharedDataPointer; +class QSimpleXmlNodeModelPrivate; +class Q_XMLPATTERNS_EXPORT QSimpleXmlNodeModel : public QAbstractXmlNodeModel +{ +public: + QSimpleXmlNodeModel(const QXmlNamePool &namePool); + virtual ~QSimpleXmlNodeModel(); + + virtual QUrl baseUri(const QXmlNodeModelIndex &node) const; + QXmlNamePool &namePool() const; + virtual QVector namespaceBindings(const QXmlNodeModelIndex&) const; + virtual QString stringValue(const QXmlNodeModelIndex &node) const; + virtual QXmlNodeModelIndex elementById(const QXmlName &id) const; + virtual QVector nodesByIdref(const QXmlName &idref) const; + +private: + Q_DECLARE_PRIVATE(QSimpleXmlNodeModel) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qsourcelocation.cpp b/src/xmlpatterns/api/qsourcelocation.cpp new file mode 100644 index 0000000..392d84c --- /dev/null +++ b/src/xmlpatterns/api/qsourcelocation.cpp @@ -0,0 +1,240 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdebug_p.h" + +#include "qsourcelocation.h" + + +QT_BEGIN_NAMESPACE + +/*! + \class QSourceLocation + \reentrant + \since 4.4 + \brief The QSourceLocation class identifies a location in a resource by URI, line, and column. + \ingroup xml-tools + + QSourceLocation is a simple value based class that has three + properties, uri(), line(), and column(), that, taken together, + identify a certain point in a resource, e.g., a file or an in-memory + document. + + line() and column() refer to character counts (not byte counts), and + they both start from 1, as opposed to 0. + */ + +/*! + Construct a QSourceLocation that doesn't identify anything at all. + + For a default constructed QSourceLocation(), isNull() returns \c true. + */ +QSourceLocation::QSourceLocation() : m_line(-1), m_column(-1) +{ +} + +/*! + Constructs a QSourceLocation that is a copy of \a other. + */ +QSourceLocation::QSourceLocation(const QSourceLocation &other) + : m_line(other.m_line), m_column(other.m_column), m_uri(other.m_uri) +{ +} + +/*! + Constructs a QSourceLocation with URI \a u, line \a l and column \a c. + */ +QSourceLocation::QSourceLocation(const QUrl &u, int l, int c) + : m_line(l), m_column(c), m_uri(u) +{ +} + +/*! + Destructor. + */ +QSourceLocation::~QSourceLocation() +{ +} + +/*! + Returns true if this QSourceLocation is identical to \a other. + + Two QSourceLocation instances are equal if their uri(), line() and + column() are equal. + + QSourceLocation instances for which isNull() returns true are + considered equal. + */ +bool QSourceLocation::operator==(const QSourceLocation &other) const +{ + return m_line == other.m_line + && m_column == other.m_column + && m_uri == other.m_uri; +} + +/*! + Returns the opposite of applying operator==() for this QXmlName + and \a other. + */ +bool QSourceLocation::operator!=(const QSourceLocation &other) const +{ + return operator==(other); +} + +/*! + Assigns this QSourceLocation instance to \a other. + */ +QSourceLocation &QSourceLocation::operator=(const QSourceLocation &other) +{ + if(this != &other) + { + m_line = other.m_line; + m_column = other.m_column; + m_uri = other.m_uri; + } + + return *this; +} + +/*! + Returns the current column number. The column number refers to the + count of characters, not bytes. The first column is column 1, not 0. + The default value is -1, indicating the column number is unknown. + */ +qint64 QSourceLocation::column() const +{ + return m_column; +} + +/*! + Sets the column number to \a newColumn. 0 is an invalid column + number. The first column number is 1. + */ +void QSourceLocation::setColumn(qint64 newColumn) +{ + Q_ASSERT_X(newColumn != 0, Q_FUNC_INFO, + "0 is an invalid column number. The first column number is 1."); + m_column = newColumn; +} + +/*! + Returns the current line number. The first line number is 1, not 0. + The default value is -1, indicating the line number is unknown. + */ +qint64 QSourceLocation::line() const +{ + return m_line; +} + +/*! + Sets the line number to \a newLine. 0 is an invalid line + number. The first line number is 1. + */ +void QSourceLocation::setLine(qint64 newLine) +{ + m_line = newLine; +} + +/*! + Returns the resource that this QSourceLocation refers to. For + example, the resource could be a file in the local file system, + if the URI scheme is \c file. + */ +QUrl QSourceLocation::uri() const +{ + return m_uri; +} + +/*! + Sets the URI to \a newUri. + */ +void QSourceLocation::setUri(const QUrl &newUri) +{ + m_uri = newUri; +} + +/*! + \relates QSourceLocation + \since 4.4 + + Prints \a sourceLocation to the debug stream \a debug. + */ +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug debug, const QSourceLocation &sourceLocation) +{ + debug << "QSourceLocation(" + << sourceLocation.uri() + << ", line:" + << sourceLocation.line() + << ", column:" + << sourceLocation.column() + << ')'; + return debug; +} +#endif + +/*! + Returns \c true if this QSourceLocation doesn't identify anything. + + For a default constructed QSourceLocation, this function returns \c + true. The same applies for any other QSourceLocation whose uri() is + invalid. + */ +bool QSourceLocation::isNull() const +{ + return !m_uri.isValid(); +} + +/*! + \since 4.4 + + Computes a hash key for the QSourceLocation \a location. + + \relates QSourceLocation + */ +uint qHash(const QSourceLocation &location) +{ + /* Not the world's best hash function exactly. */ + return qHash(location.uri().toString()) + location.line() + location.column(); +} + +QT_END_NAMESPACE + diff --git a/src/xmlpatterns/api/qsourcelocation.h b/src/xmlpatterns/api/qsourcelocation.h new file mode 100644 index 0000000..80184fd --- /dev/null +++ b/src/xmlpatterns/api/qsourcelocation.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSOURCELOCATION_H +#define QSOURCELOCATION_H + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(XmlPatterns) + +class QSourceLocationPrivate; + +class Q_XMLPATTERNS_EXPORT QSourceLocation +{ +public: + QSourceLocation(); + QSourceLocation(const QSourceLocation &other); + QSourceLocation(const QUrl &uri, int line = -1, int column = -1); + ~QSourceLocation(); + QSourceLocation &operator=(const QSourceLocation &other); + bool operator==(const QSourceLocation &other) const; + bool operator!=(const QSourceLocation &other) const; + + qint64 column() const; + void setColumn(qint64 newColumn); + + qint64 line() const; + void setLine(qint64 newLine); + + QUrl uri() const; + void setUri(const QUrl &newUri); + bool isNull() const; + +private: + union + { + qint64 m_line; + QSourceLocationPrivate *m_ptr; + }; + qint64 m_column; + QUrl m_uri; +}; + +Q_XMLPATTERNS_EXPORT uint qHash(const QSourceLocation &location); + +#ifndef QT_NO_DEBUG_STREAM +Q_XMLPATTERNS_EXPORT QDebug operator<<(QDebug debug, const QSourceLocation &sourceLocation); +#endif + +Q_DECLARE_TYPEINFO(QSourceLocation, Q_MOVABLE_TYPE); + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QSourceLocation) /* This macro must appear after QT_END_NAMESPACE. */ + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/quriloader.cpp b/src/xmlpatterns/api/quriloader.cpp new file mode 100644 index 0000000..b8cb104 --- /dev/null +++ b/src/xmlpatterns/api/quriloader.cpp @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include "qiodevicedelegate_p.h" +#include "quriloader_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +URILoader::URILoader(QObject *const parent, + const NamePool::Ptr &np, + const VariableLoader::Ptr &l) : QNetworkAccessManager(parent) + , m_variableNS(QLatin1String("tag:trolltech.com,2007:QtXmlPatterns:QIODeviceVariable:")) + , m_namePool(np) + , m_variableLoader(l) +{ + Q_ASSERT(m_variableLoader); +} + +QNetworkReply *URILoader::createRequest(Operation op, const QNetworkRequest &req, QIODevice *outgoingData) +{ + const QString requestedUrl(req.url().toString()); + + /* We got a QIODevice variable. */ + const QString name(requestedUrl.right(requestedUrl.length() - m_variableNS.length())); + + const QVariant variant(m_variableLoader->valueFor(m_namePool->allocateQName(QString(), name, QString()))); + + if(!variant.isNull() && variant.userType() == qMetaTypeId()) + return new QIODeviceDelegate(qvariant_cast(variant)); + else + { + /* If we're entering this code path, the variable URI identified a variable + * which we don't have, which means we either have a bug, or the user had + * crafted an invalid URI manually. */ + + return QNetworkAccessManager::createRequest(op, req, outgoingData); + } +} + +QT_END_NAMESPACE + diff --git a/src/xmlpatterns/api/quriloader_p.h b/src/xmlpatterns/api/quriloader_p.h new file mode 100644 index 0000000..eaaca5f --- /dev/null +++ b/src/xmlpatterns/api/quriloader_p.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QURILOADER_P_H +#define QURILOADER_P_H + +#include +#include + +#include "qnamepool_p.h" +#include "qvariableloader_p.h" + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + class URILoader : public QNetworkAccessManager + { + public: + URILoader(QObject *const parent, + const NamePool::Ptr &np, + const VariableLoader::Ptr &variableLoader); + + virtual QNetworkReply *createRequest(Operation op, + const QNetworkRequest & req, + QIODevice *outgoingData = 0); + + private: + const QString m_variableNS; + const NamePool::Ptr m_namePool; + const VariableLoader::Ptr m_variableLoader; + + }; +} + +QT_END_NAMESPACE + +#endif diff --git a/src/xmlpatterns/api/qvariableloader.cpp b/src/xmlpatterns/api/qvariableloader.cpp new file mode 100644 index 0000000..9909508 --- /dev/null +++ b/src/xmlpatterns/api/qvariableloader.cpp @@ -0,0 +1,264 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include "qanyuri_p.h" +#include "qatomicstring_p.h" +#include "qbuiltintypes_p.h" +#include "qcommonsequencetypes_p.h" +#include "qgenericsequencetype_p.h" +#include "qinteger_p.h" +#include "qitem_p.h" +#include "qsequencetype_p.h" +#include "qvariableloader_p.h" +#include "qxmlquery_p.h" + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + class VariantListIterator : public ListIteratorPlatform + { + public: + inline VariantListIterator(const QVariantList &list) : ListIteratorPlatform(list) + { + } + + private: + friend class ListIteratorPlatform; + + inline Item inputToOutputItem(const QVariant &inputType) const + { + return AtomicValue::toXDM(inputType); + } + }; + + class StringListIterator : public ListIteratorPlatform + { + public: + inline StringListIterator(const QStringList &list) : ListIteratorPlatform(list) + { + } + + private: + friend class ListIteratorPlatform; + + static inline Item inputToOutputItem(const QString &inputType) + { + return AtomicString::fromValue(inputType); + } + }; + + /** + * Takes two DynamicContext instances, and redirects the storage of temporary trees + * to one of them. + * + * @since 4.5 + */ + class TemporaryTreesRedirectingContext : public DelegatingDynamicContext + { + public: + TemporaryTreesRedirectingContext(const DynamicContext::Ptr &other, + const DynamicContext::Ptr &modelStorage) : DelegatingDynamicContext(other) + , m_modelStorage(modelStorage) + { + Q_ASSERT(m_modelStorage); + } + + virtual void addNodeModel(const QAbstractXmlNodeModel::Ptr &nodeModel) + { + m_modelStorage->addNodeModel(nodeModel); + } + + private: + const DynamicContext::Ptr m_modelStorage; + }; +} + +using namespace QPatternist; + +SequenceType::Ptr VariableLoader::announceExternalVariable(const QXmlName name, + const SequenceType::Ptr &declaredType) +{ + Q_UNUSED(declaredType); + const QVariant &variant = m_bindingHash.value(name); + + + if(variant.isNull()) + return SequenceType::Ptr(); + else if(variant.userType() == qMetaTypeId()) + return CommonSequenceTypes::ExactlyOneAnyURI; + else if(variant.userType() == qMetaTypeId()) + { + const QXmlQuery variableQuery(qvariant_cast(variant)); + return variableQuery.d->expression()->staticType(); + } + else + { + return makeGenericSequenceType(AtomicValue::qtToXDMType(qvariant_cast(variant)), + Cardinality::exactlyOne()); + } +} + +Item::Iterator::Ptr VariableLoader::evaluateSequence(const QXmlName name, + const DynamicContext::Ptr &context) +{ + + const QVariant &variant = m_bindingHash.value(name); + Q_ASSERT_X(!variant.isNull(), Q_FUNC_INFO, + "We assume that we have a binding."); + + /* Same code as in the default clause below. */ + if(variant.userType() == qMetaTypeId()) + return makeSingletonIterator(itemForName(name)); + else if(variant.userType() == qMetaTypeId()) + { + const QXmlQuery variableQuery(qvariant_cast(variant)); + + return variableQuery.d->expression()->evaluateSequence(DynamicContext::Ptr(new TemporaryTreesRedirectingContext(variableQuery.d->dynamicContext(), context))); + } + + const QVariant v(qvariant_cast(variant).toAtomicValue()); + + switch(v.type()) + { + case QVariant::StringList: + return Item::Iterator::Ptr(new StringListIterator(v.toStringList())); + case QVariant::List: + return Item::Iterator::Ptr(new VariantListIterator(v.toList())); + default: + return makeSingletonIterator(itemForName(name)); + } +} + +Item VariableLoader::itemForName(const QXmlName &name) const +{ + const QVariant &variant = m_bindingHash.value(name); + + if(variant.userType() == qMetaTypeId()) + return Item(AnyURI::fromValue(QLatin1String("tag:trolltech.com,2007:QtXmlPatterns:QIODeviceVariable:") + m_namePool->stringForLocalName(name.localName()))); + + const QXmlItem item(qvariant_cast(variant)); + + if(item.isNode()) + return Item::fromPublic(item); + else + { + const QVariant atomicValue(item.toAtomicValue()); + /* If the atomicValue is null it means it doesn't exist in m_bindingHash, and therefore it must + * be a QIODevice, since Patternist guarantees to only ask for variables that announceExternalVariable() + * has accepted. */ + if(atomicValue.isNull()) + return Item(AnyURI::fromValue(QLatin1String("tag:trolltech.com,2007:QtXmlPatterns:QIODeviceVariable:") + m_namePool->stringForLocalName(name.localName()))); + else + return AtomicValue::toXDM(atomicValue); + } +} + +Item VariableLoader::evaluateSingleton(const QXmlName name, + const DynamicContext::Ptr &) +{ + return itemForName(name); +} + +bool VariableLoader::isSameType(const QVariant &v1, + const QVariant &v2) const +{ + /* Are both of type QIODevice *? */ + if(v1.userType() == qMetaTypeId() && v1.userType() == v2.userType()) + return true; + + /* Ok, we have two QXmlItems. */ + const QXmlItem i1(qvariant_cast(v1)); + const QXmlItem i2(qvariant_cast(v2)); + + if(i1.isNode()) + { + Q_ASSERT(false); + return false; + } + else if(i2.isAtomicValue()) + return i1.toAtomicValue().type() == i2.toAtomicValue().type(); + else + { + /* One is an atomic, the other is a node or they are null. */ + return false; + } +} + +void VariableLoader::removeBinding(const QXmlName &name) +{ + m_bindingHash.remove(name); +} + +bool VariableLoader::hasBinding(const QXmlName &name) const +{ + return m_bindingHash.contains(name) + || (m_previousLoader && m_previousLoader->hasBinding(name)); +} + +QVariant VariableLoader::valueFor(const QXmlName &name) const +{ + if(m_bindingHash.contains(name)) + return m_bindingHash.value(name); + else if(m_previousLoader) + return m_previousLoader->valueFor(name); + else + return QVariant(); +} + +void VariableLoader::addBinding(const QXmlName &name, + const QVariant &value) +{ + m_bindingHash.insert(name, value); +} + +bool VariableLoader::invalidationRequired(const QXmlName &name, + const QVariant &variant) const +{ + return hasBinding(name) && !isSameType(valueFor(name), variant); +} + +QT_END_NAMESPACE + diff --git a/src/xmlpatterns/api/qvariableloader_p.h b/src/xmlpatterns/api/qvariableloader_p.h new file mode 100644 index 0000000..cf050cb --- /dev/null +++ b/src/xmlpatterns/api/qvariableloader_p.h @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef PATTERNIST_VARIABLELOADER_P_H +#define PATTERNIST_VARIABLELOADER_P_H + +#include +#include +#include + +#include "qdynamiccontext_p.h" +#include "qexternalvariableloader_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + class VariableLoader : public ExternalVariableLoader + { + public: + typedef QHash BindingHash; + typedef QExplicitlySharedDataPointer Ptr; + + inline VariableLoader(const NamePool::Ptr &np, + const VariableLoader::Ptr &previousLoader = VariableLoader::Ptr()) : m_namePool(np) + , m_previousLoader(previousLoader) + + { + } + + virtual QPatternist::SequenceType::Ptr announceExternalVariable(const QXmlName name, + const QPatternist::SequenceType::Ptr &declaredType); + virtual QPatternist::Item::Iterator::Ptr evaluateSequence(const QXmlName name, + const QPatternist::DynamicContext::Ptr &); + + virtual QPatternist::Item evaluateSingleton(const QXmlName name, + const QPatternist::DynamicContext::Ptr &); + + void removeBinding(const QXmlName &name); + bool hasBinding(const QXmlName &name) const; + QVariant valueFor(const QXmlName &name) const; + void addBinding(const QXmlName &name, + const QVariant &value); + + bool isSameType(const QVariant &v1, + const QVariant &v2) const; + + bool invalidationRequired(const QXmlName &name, + const QVariant &variant) const; + + private: + + inline QPatternist::Item itemForName(const QXmlName &name) const; + + const NamePool::Ptr m_namePool; + VariableLoader::Ptr m_previousLoader; + BindingHash m_bindingHash; + }; +} + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QIODevice *) +Q_DECLARE_METATYPE(QXmlQuery) + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qxmlformatter.cpp b/src/xmlpatterns/api/qxmlformatter.cpp new file mode 100644 index 0000000..0925fe5 --- /dev/null +++ b/src/xmlpatterns/api/qxmlformatter.cpp @@ -0,0 +1,338 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qxmlformatter.h" +#include "qxpathhelper_p.h" +#include "qxmlserializer_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +class QXmlFormatterPrivate : public QXmlSerializerPrivate +{ +public: + inline QXmlFormatterPrivate(const QXmlQuery &q, + QIODevice *const outputDevice); + + int indentationDepth; + int currentDepth; + QString characterBuffer; + QString indentString; + + /** + * Whether we /have/ sent nodes like processing instructions and comments + * to QXmlSerializer. + */ + QStack canIndent; +}; + +QXmlFormatterPrivate::QXmlFormatterPrivate(const QXmlQuery &query, + QIODevice *const outputDevice) : QXmlSerializerPrivate(query, outputDevice) + , indentationDepth(4) + , currentDepth(0) +{ + indentString.reserve(30); + indentString.resize(1); + indentString[0] = QLatin1Char('\n'); + canIndent.push(false); +} + +/*! + \class QXmlFormatter + \brief The QXmlFormatter class is an implementation of QXmlSerializer for transforming XQuery output into formatted XML. + \reentrant + \since 4.4 + \ingroup xml-tools + + QXmlFormatter is a subclass of QXmlSerializer that formats the XML + output to make it easier for humans to read. + + QXmlSerializer outputs XML without adding unnecessary whitespace. + In particular, it does not add \e {newlines} and indentation. + To make the XML output easier to read, QXmlFormatter adds \e{newlines} + and indentation by adding, removing, and modifying + \l{XQuery Sequence}{sequence nodes} that only consist of whitespace. + It also modifies whitespace in other places where it is not + significant; e.g., between attributes and in the document prologue. + + For example, where the base class QXmlSerializer would + output this: + + \quotefile doc/src/snippets/patternist/notIndented.xml + + QXmlFormatter outputs this: + + \quotefile doc/src/snippets/patternist/indented.xml + + If you just want to serialize your XML in a human-readable + format, use QXmlFormatter as it is. The default indentation + level is 4 spaces, but you can set your own indentation value + setIndentationDepth(). + + The \e{newlines} and indentation added by QXmlFormatter are + suitable for common formats, such as XHTML, SVG, or Docbook, + where whitespace is not significant. However, if your XML will + be used as input where whitespace is significant, then you must + write your own subclass of QXmlSerializer or QAbstractXmlReceiver. + + Note that using QXmlFormatter instead of QXmlSerializer will + increase computational overhead and document storage size due + to the insertion of whitespace. + + Note also that the indentation style used by QXmlFormatter + remains loosely defined and may change in future versions of + Qt. If a specific indentation style is required then either + use the base class QXmlSerializer directly, or write your own + subclass of QXmlSerializer or QAbstractXmlReceiver. + Alternatively, you can subclass QXmlFormatter and reimplement + the callbacks there. + + \snippet doc/src/snippets/code/src_xmlpatterns_api_qxmlformatter.cpp 0 +*/ + +/*! + Constructs a formatter that uses the name pool and message + handler in \a query, and writes the result to \a outputDevice + as formatted XML. + + \a outputDevice is passed directly to QXmlSerializer's constructor. + + \sa QXmlSerializer + */ +QXmlFormatter::QXmlFormatter(const QXmlQuery &query, + QIODevice *outputDevice) : QXmlSerializer(new QXmlFormatterPrivate(query, outputDevice)) +{ +} + +/*! + \internal + */ +void QXmlFormatter::startFormattingContent() +{ + Q_D(QXmlFormatter); + + if(QPatternist::XPathHelper::isWhitespaceOnly(d->characterBuffer)) + { + if(d->canIndent.top()) + QXmlSerializer::characters(QStringRef(&d->indentString)); + } + else + { + if(!d->characterBuffer.isEmpty()) /* Significant data, we don't touch it. */ + QXmlSerializer::characters(QStringRef(&d->characterBuffer)); + } + + d->characterBuffer.clear(); +} + +/*! + \reimp + */ +void QXmlFormatter::startElement(const QXmlName &name) +{ + Q_D(QXmlFormatter); + startFormattingContent(); + ++d->currentDepth; + d->indentString.append(QString(d->indentationDepth, QLatin1Char(' '))); + d->canIndent.push(true); + + QXmlSerializer::startElement(name); +} + +/*! + \reimp + */ +void QXmlFormatter::endElement() +{ + Q_D(QXmlFormatter); + --d->currentDepth; + d->indentString.chop(d->indentationDepth); + + if(!d->hasClosedElement.top().second) + d->canIndent.top() = false; + + startFormattingContent(); + + d->canIndent.pop(); + d->canIndent.top() = true; + QXmlSerializer::endElement(); +} + +/*! + \reimp + */ +void QXmlFormatter::attribute(const QXmlName &name, + const QStringRef &value) +{ + QXmlSerializer::attribute(name, value); +} + +/*! + \reimp + */ +void QXmlFormatter::comment(const QString &value) +{ + Q_D(QXmlFormatter); + startFormattingContent(); + QXmlSerializer::comment(value); + d->canIndent.top() = true; +} + +/*! + \reimp + */ +void QXmlFormatter::characters(const QStringRef &value) +{ + Q_D(QXmlFormatter); + d->isPreviousAtomic = false; + d->characterBuffer += value.toString(); +} + +/*! + \reimp + */ +void QXmlFormatter::processingInstruction(const QXmlName &name, + const QString &value) +{ + Q_D(QXmlFormatter); + startFormattingContent(); + QXmlSerializer::processingInstruction(name, value); + d->canIndent.top() = true; +} + +/*! + \reimp + */ +void QXmlFormatter::atomicValue(const QVariant &value) +{ + Q_D(QXmlFormatter); + d->canIndent.top() = false; + QXmlSerializer::atomicValue(value); +} + +/*! + \reimp + */ +void QXmlFormatter::startDocument() +{ + QXmlSerializer::startDocument(); +} + +/*! + \reimp + */ +void QXmlFormatter::endDocument() +{ + QXmlSerializer::endDocument(); +} + +/*! + \reimp + */ +void QXmlFormatter::startOfSequence() +{ + QXmlSerializer::startOfSequence(); +} + +/*! + \reimp + */ +void QXmlFormatter::endOfSequence() +{ + Q_D(QXmlFormatter); + + /* Flush any buffered content. */ + if(!d->characterBuffer.isEmpty()) + QXmlSerializer::characters(QStringRef(&d->characterBuffer)); + + d->write('\n'); + QXmlSerializer::endOfSequence(); +} + +/*! + \internal + */ +void QXmlFormatter::item(const QPatternist::Item &item) +{ + Q_D(QXmlFormatter); + + if(item.isAtomicValue()) + { + if(QPatternist::XPathHelper::isWhitespaceOnly(item.stringValue())) + return; + else + { + d->canIndent.top() = false; + startFormattingContent(); + } + } + + QXmlSerializer::item(item); +} + +/*! + Returns the number of spaces QXmlFormatter will output for each + indentation level. The default is four. + + \sa setIndentationDepth() + */ +int QXmlFormatter::indentationDepth() const +{ + Q_D(const QXmlFormatter); + return d->indentationDepth; +} + +/*! + Sets \a depth to be the number of spaces QXmlFormatter will + output for level of indentation. The default is four. + + \sa indentationDepth() + */ +void QXmlFormatter::setIndentationDepth(int depth) +{ + Q_D(QXmlFormatter); + d->indentationDepth = depth; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/api/qxmlformatter.h b/src/xmlpatterns/api/qxmlformatter.h new file mode 100644 index 0000000..8ad3aa2 --- /dev/null +++ b/src/xmlpatterns/api/qxmlformatter.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QXMLFORMATTER_H +#define QXMLFORMATTER_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(XmlPatterns) + +class QIODevice; +class QTextCodec; +class QXmlQuery; +class QXmlFormatterPrivate; + +class Q_XMLPATTERNS_EXPORT QXmlFormatter : public QXmlSerializer +{ +public: + QXmlFormatter(const QXmlQuery &query, + QIODevice *outputDevice); + + virtual void characters(const QStringRef &value); + virtual void comment(const QString &value); + virtual void startElement(const QXmlName &name); + virtual void endElement(); + + virtual void attribute(const QXmlName &name, + const QStringRef &value); + virtual void processingInstruction(const QXmlName &name, + const QString &value); + virtual void atomicValue(const QVariant &value); + virtual void startDocument(); + virtual void endDocument(); + virtual void startOfSequence(); + virtual void endOfSequence(); + + int indentationDepth() const; + void setIndentationDepth(int depth); + + /* The members below are internal, not part of the public API, and + * unsupported. Using them leads to undefined behavior. */ + virtual void item(const QPatternist::Item &item); +private: + inline void startFormattingContent(); + Q_DECLARE_PRIVATE(QXmlFormatter) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qxmlname.cpp b/src/xmlpatterns/api/qxmlname.cpp new file mode 100644 index 0000000..8ff7411 --- /dev/null +++ b/src/xmlpatterns/api/qxmlname.cpp @@ -0,0 +1,511 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + * QXmlName is conceptually identical to QPatternist::QName. The + * difference is that the latter is elegant, powerful and fast. + * + * However, it is too powerful and too open and not at all designed + * for being public. QXmlName, in contrast, is only a public marker, + * that for instance uses a qint64 instead of qint32, such that we in + * the future can use that, if needed. + */ + +#include "qnamepool_p.h" +#include "qxmlname.h" +#include "qxmlnamepool.h" +#include "qxpathhelper_p.h" +#include "private/qxmlutils_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QXmlName + \brief The QXmlName class represents the name of an XML node, in an efficient, namespace-aware way. + \reentrant + \since 4.4 + \ingroup xml-tools + + QXmlName represents the name of an XML node in a way that + is both efficient and safe for comparing names. Normally, + an XML node represents an XML element or attribute, but + QXmlName can also represent the names of other kinds of + nodes, e.g., QAbstractXmlReceiver::processingInstruction() + and QAbstractXmlReceiver::namespaceBinding(). + + The name of an XML node has three components: The \e {namespace + URI}, the \e {local name}, and the \e {prefix}. To see what these + refer to in XML, consider the following snippet. + + \quotefile doc/src/snippets/patternist/mobeyDick.xml + + For the element named \e book, localName() returns \e book, + namespaceUri() returns \e http://example.com/MyDefault, + and prefix() returns an empty string. For the element named + \e title, localName() returns \e title, namespaceUri() returns + \e http://purl.org/dc/elements/1.1, and prefix() returns \e dc. + + To ensure that operations with QXmlName are efficient, e.g., + copying names and comparing them, each instance of QXmlName is + associated with a \l {QXmlNamePool} {name pool}, which must be + specified at QXmlName construction time. The three components + of the QXmlName, i.e., the namespace URI, the local name, and + the prefix, are stored in the name pool mapped to identifiers + so they can be shared. For this reason, the only way to create + a valid instance of QXmlName is to use the class constructor, + where the \l {QXmlNamePool} {name pool}, local name, namespace + URI, and prefix must all be specified. + + Note that QXmlName's default constructor constructs a null + instance. It is typically used for allocating unused entries + in collections of QXmlName. + + A side effect of associating each instance of QXmlName with + a \l {QXmlNamePool} {name pool} is that each instance of + QXmlName is tied to the QXmlNamePool with which it was created. + However, the QXmlName class does not keep track of the name pool, + so all the accessor functions, e.g., namespaceUri(), prefix(), + localName(), and toClarkName() require that the correct name + pool be passed to them. Failure to provide the correct name + pool to these accessor functions results in undefined behavior. + + Note that a \l {QXmlNamePool} {name pool} is \e not an XML + namespace. One \l {QXmlNamePool} {name pool} can represent + instances of QXmlName from different XML namespaces, and the + instances of QXmlName from one XML namespace can be distributed + over multiple \l {QXmlNamePool} {name pools}. + + \target Comparing QXmlNames + \section1 Comparing QXmlNames + + To determine what a QXmlName refers to, the \e {namespace URI} + and the \e {local name} are used. The \e prefix is not used + because the prefix is simply a shorthand name for use in place + of the normally much longer namespace URI. Nor is the prefix + used in name comparisons. For example, the following two element + nodes represent the same element and compare equal. + + \quotefile doc/src/snippets/patternist/svgDocumentElement.xml + + \quotefile doc/src/snippets/patternist/xsvgDocumentElement.xml + + Although the second name has the prefix \e x, the two names compare + equal as instances of QXmlName, because the prefix is not used in + the comparison. + + A local name can never be an empty string, although the prefix and + namespace URI can. If the prefix is not empty, the namespace URI + cannot be empty. Local names and prefixes must be valid + \l {http://www.w3.org/TR/REC-xml-names/#NT-NCName} {NCNames}, + e.g., \e abc.def or \e abc123. + + QXmlName represents what is sometimes called an \e {expanded QName}, + or simply a QName. + + \sa {http://www.w3.org/TR/REC-xml-names/#NT-NCName} {Namespaces in XML 1.0 (Second Edition), [4] NCName} + */ + +/*! + \enum QXmlName::Constant + \internal + Various constants used in the QPatternist::NamePool and QXmlName. + + Setting of the mask enums use essentially this: + + \quotefile doc/src/snippets/code/src_xmlpatterns_api_qxmlname.cpp + + The masks, such as LocalNameMask, are positive. That is, for the + area which the name resides, the bits are set. + */ + +/*! + Constructs a QXmlName instance that inserts \a localName, + \a namespaceURI and \a prefix into \a namePool if they aren't + already there. The accessor functions namespaceUri(), prefix(), + localName(), and toClarkName() must be passed the \a namePool + used here, so the \a namePool must remain in scope while the + accessor functions might be used. However, two instances can + be compared with \e {==} or \e {!=} and copied without the + \a namePool. + + The user guarantees that the string components are valid for a + QName. In particular, the local name, and the prefix (if present), + must be valid \l {http://www.w3.org/TR/REC-xml-names/#NT-NCName} + {NCNames}. The function isNCName() can be used to test validity + of these names. The namespace URI should be an absolute URI. + QUrl::isRelative() can be used to test whether the namespace URI + is relative or absolute. Finally, providing a prefix is not valid + when no namespace URI is provided. + + \a namePool is not copied. Nor is the reference to it retained + in this instance. This constructor inserts the three strings + into \a namePool. + */ +QXmlName::QXmlName(QXmlNamePool &namePool, + const QString &localName, + const QString &namespaceURI, + const QString &prefix) +{ + Q_ASSERT_X(prefix.isEmpty() || QXmlUtils::isNCName(prefix), Q_FUNC_INFO, + "The prefix is invalid, maybe the arguments were mixed up?"); + Q_ASSERT_X(QXmlUtils::isNCName(localName), Q_FUNC_INFO, + "The local name is invalid, maybe the arguments were mixed up?"); + + m_qNameCode = namePool.d->allocateQName(namespaceURI, localName, prefix).code(); +} + +/*! + \typedef QXmlName::Code + \internal + + Stores the \l {QXmlNamePool} {name pool} identifiers for + the namespace URI, local name, and prefix. + */ + +/*! + Returns true if this QXmlName is not initialized with a + valid combination of \e {namespace URI}, \e {local name}, + and \e {prefix}. + + A valid local name is always required. The prefix and + namespace URI can be empty, but if the prefix is not empty, + the namespace URI must not be empty. Local names and + prefixes must be valid + \l {http://www.w3.org/TR/REC-xml-names/#NT-NCName} {NCNames}, + e.g., \e abc.def or \e abc123. + */ +bool QXmlName::isNull() const +{ + return m_qNameCode == InvalidCode; +} + +/*! + Constructs an uninitialized QXmlName. To build + a valid QXmlName, you normally use the other constructor, which + takes a \l {QXmlNamePool} {name pool}, namespace URI, local name, + and prefix as parameters. But you can also use this constructor + to build a null QXmlName and then assign an existing QXmlName + to it. + + \sa isNull() + */ +QXmlName::QXmlName() : m_qNameCode(InvalidCode) +{ +} + +/*! + \fn QXmlName::QXmlName(const NamespaceCode uri, + const LocalNameCode ln, + const PrefixCode p = 0) + \internal + */ + +/*! + \fn QXmlName::hasPrefix() const + \internal + + Returns true if this QXmlName has a non-empty prefix. If this + function returns true, hasNamespace() will also return true, + because a QXmlName can't have a prefix if it doesn't have a + namespace URI. + */ + +/*! + \fn bool QXmlName::hasNamespace() const + \internal + + Returns true if this QXmlName has a non-empty namespace URI. + */ + +/*! + \fn Code QXmlName::code() const + \internal + + Returns the internal code that contains the id codes for the + local name, prefix and namespace URI. It is opaque when used + outside QXmlName, but it can be useful when one wants to put + a QXmlName in a hash, and the prefix is significant. + */ + +/*! + Returns true if this QXmlName is equal to \a other; otherwise false. + Two QXmlNames are equal if their namespace URIs are the same \e and + their local names are the same. The prefixes are ignored. + + Note that it is meaningless to compare two instances of QXmlName + that were created with different \l {QXmlNamePool} {name pools}, + but the attempt is not detected and the behavior is undefined. + + \sa operator!=() + */ +bool QXmlName::operator==(const QXmlName &other) const +{ + return (m_qNameCode & ExpandedNameMask) == (other.m_qNameCode & ExpandedNameMask); +} + +/*! + Returns true if this QXmlName is \e not equal to \a other; + otherwise false. Two QXmlNames are equal if their namespace + URIs are the same \e and their local names are the same. They + are not equal if either their namespace URIs differ or their + local names differ. Their prefixes are ignored. + + Note that it is meaningless to compare two instances of QXmlName + that were created with different \l {QXmlNamePool} {name pools}, + but the attempt is not detected and the behavior is undefined. + + \sa operator==() + */ +bool QXmlName::operator!=(const QXmlName &other) const +{ + return !operator==(other); +} + +/*! + \fn bool QXmlName::isLexicallyEqual(const QXmlName &other) const + \internal + + Returns true if this and \a other are lexically equal. Two + QXmlNames are lexically equal if their local names are equal + \e and their prefixes are equal. + */ + +/*! + \fn uint qHash(const QXmlName &name) + \since 4.4 + \relates QXmlName + + Computes a hash key from the local name and the namespace + URI in \a name. The prefix in \a name is not used in the computation. + */ +uint qHash(const QXmlName &name) +{ + return name.m_qNameCode & QXmlName::ExpandedNameMask; +} + +/*! + Returns the namespace URI. + + Note that for efficiency, the namespace URI string is not + stored in the QXmlName but in the \l {QXmlNamePool} that was + passed to the constructor. Hence, that same \a namePool must + be passed to this function, so it can be used for looking up + the namespace URI. + */ +QString QXmlName::namespaceUri(const QXmlNamePool &namePool) const +{ + if(isNull()) + return QString(); + else + return namePool.d->stringForNamespace(namespaceURI()); +} + +/*! + Returns the prefix. + + Note that for efficiency, the prefix string is not stored in + the QXmlName but in the \l {QXmlNamePool} that was passed to + the constructor. Hence, that same \a namePool must be passed + to this function, so it can be used for looking up the prefix. + */ +QString QXmlName::prefix(const QXmlNamePool &namePool) const +{ + if(isNull()) + return QString(); + else + return namePool.d->stringForPrefix(prefix()); +} + +/*! + Returns the local name. + + Note that for efficiency, the local name string is not stored + in the QXmlName but in the \l {QXmlNamePool} that was passed to + the constructor. Hence, that same \a namePool must be passed + to this function, so it can be used for looking up the + local name. + */ +QString QXmlName::localName(const QXmlNamePool &namePool) const +{ + if(isNull()) + return QString(); + else + return namePool.d->stringForLocalName(localName()); +} + +/*! + Returns this QXmlName formatted as a Clark Name. For example, + if the local name is \c html, the prefix is \c x, and the + namespace URI is \c {http://www.w3.org/1999/xhtml/}, + then the Clark Name returned is: + + \code + {http://www.w3.org/1999/xhtml/}x:html. + \endcode + + If the local name is \e {MyWidget} and the namespace is empty, + the Clark Name returned is: + + \code + MyWidget + \endcode + + Note that for efficiency, the namespace URI, local name, and + prefix strings are not stored in the QXmlName but in the + \l {QXmlNamePool} that was passed to the constructor. Hence, + that same \a namePool must be passed to this function, so it + can be used for looking up the three string components. + + This function can be useful for debugging. + + \sa {http://www.jclark.com/xml/xmlns.htm} {XML Namespaces, James Clark} + \sa fromClarkName() + */ +QString QXmlName::toClarkName(const QXmlNamePool &namePool) const +{ + return namePool.d->toClarkName(*this); +} + +/*! + Assigns \a other to \e this and returns \e this. + */ +QXmlName &QXmlName::operator=(const QXmlName &other) +{ + m_qNameCode = other.m_qNameCode; + return *this; +} + +/*! + Returns true if \a candidate is an \c NCName. An \c NCName + is a string that can be used as a name in XML and XQuery, + e.g., the prefix or local name in an element or attribute, + or the name of a variable. + + \sa {http://www.w3.org/TR/REC-xml-names/#NT-NCName} {Namespaces in XML 1.0 (Second Edition), [4] NCName} + */ +bool QXmlName::isNCName(const QString &candidate) +{ + return QXmlUtils::isNCName(candidate); +} + +/*! + Converts \a clarkName into a QXmlName, inserts into \a namePool, and + returns it. + + A clark name is a way to present a full QName with only one string, where + the namespace cannot contain braces. Here are a couple of examples: + + \table + \header + \o Clark Name + \o Description + \row + \o \c html + \o The local name \c html, in no namespace + \row + \o \c {http://www.w3.org/1999/xhtml}html + \o The local name \c html, in the XHTML namespace + \row + \o \c {http://www.w3.org/1999/xhtml}my:html + \o The local name \c html, in the XHTML namespace, with the prefix \c my + \endtable + + If the namespace contains braces, the returned value is either invalid or + has undefined content. + + If \a clarkName is an invalid name, a default constructed QXmlName is + returned. + + \since 4.5 + \sa toClarkName() + */ +QXmlName QXmlName::fromClarkName(const QString &clarkName, + const QXmlNamePool &namePool) +{ + return namePool.d->fromClarkName(clarkName); +} + +/*! + \typedef QXmlName::LocalNameCode + \internal + */ + +/*! + \typedef QXmlName::PrefixCode + \internal + */ + +/*! + \typedef QXmlName::NamespaceCode + \internal + */ + +/*! + \fn void QXmlName::setLocalName(const LocalNameCode c) + \internal +*/ + +/*! + \fn LocalNameCode QXmlName::localName() const + \internal +*/ + +/*! + \fn PrefixCode QXmlName::prefix() const + \internal +*/ + +/*! + \fn NamespaceCode QXmlName::namespaceURI() const + \internal +*/ + +/*! + \fn void QXmlName::setNamespaceURI(const NamespaceCode c) + \internal +*/ + +/*! + \fn void QXmlName::setPrefix(const PrefixCode c) + \internal +*/ +QT_END_NAMESPACE + diff --git a/src/xmlpatterns/api/qxmlname.h b/src/xmlpatterns/api/qxmlname.h new file mode 100644 index 0000000..8350302 --- /dev/null +++ b/src/xmlpatterns/api/qxmlname.h @@ -0,0 +1,142 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QXMLNAME_H +#define QXMLNAME_H + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(XmlPatterns) + +class QXmlName; +class QXmlNamePool; +Q_XMLPATTERNS_EXPORT uint qHash(const QXmlName &name); + +class Q_XMLPATTERNS_EXPORT QXmlName +{ +private: + enum Constant + { + LocalNameOffset = 0, + LocalNameLength = 12, + NamespaceOffset = LocalNameLength, + NamespaceLength = 9, + PrefixLength = 9, + InvalidCode = 1 << 31, + NamespaceMask = ((1 << ((NamespaceOffset + NamespaceLength) - NamespaceOffset)) - 1) << NamespaceOffset, + LocalNameMask = ((1 << ((LocalNameOffset + LocalNameLength) - LocalNameOffset)) - 1) << LocalNameOffset, + PrefixOffset = LocalNameLength + NamespaceLength, + PrefixMask = ((1 << ((PrefixOffset + PrefixLength) - PrefixOffset)) - 1) << PrefixOffset, + MaximumPrefixes = (PrefixMask >> PrefixOffset) - 1, + MaximumLocalNames = (LocalNameMask >> LocalNameOffset) - 1, + MaximumNamespaces = (NamespaceMask >> NamespaceOffset) - 1, + ExpandedNameMask = LocalNameMask | NamespaceMask, + LexicalQNameMask = LocalNameMask | PrefixMask + }; + +public: + + typedef qint16 NamespaceCode; + typedef NamespaceCode PrefixCode; + typedef NamespaceCode LocalNameCode; + + QXmlName(); + + QXmlName(QXmlNamePool &namePool, + const QString &localName, + const QString &namespaceURI = QString(), + const QString &prefix = QString()); + + QString namespaceUri(const QXmlNamePool &query) const; + QString prefix(const QXmlNamePool &query) const; + QString localName(const QXmlNamePool &query) const; + QString toClarkName(const QXmlNamePool &query) const; + bool operator==(const QXmlName &other) const; + bool operator!=(const QXmlName &other) const; + QXmlName &operator=(const QXmlName &other); + bool isNull() const; + static bool isNCName(const QString &candidate); + static QXmlName fromClarkName(const QString &clarkName, + const QXmlNamePool &namePool); + + /* The members below are internal, not part of the public API, and + * unsupported. Using them leads to undefined behavior. */ + typedef qint64 Code; + + inline QXmlName(const NamespaceCode uri, + const LocalNameCode ln, + const PrefixCode p = 0); + /* The implementation for these functions are in utils/qnamepool_p.h. */ + inline LocalNameCode localName() const; + inline PrefixCode prefix() const; + inline bool hasPrefix() const; + inline bool hasNamespace() const; + inline NamespaceCode namespaceURI() const; + inline bool isLexicallyEqual(const QXmlName &other) const; + inline void setPrefix(const PrefixCode c); + inline void setNamespaceURI(const NamespaceCode c); + inline void setLocalName(const LocalNameCode c); + inline Code code() const; + + friend Q_XMLPATTERNS_EXPORT uint qHash(const QXmlName &); + +private: + inline QXmlName(const int c) : m_qNameCode(c) + { + } + + Code m_qNameCode; +}; + +Q_DECLARE_TYPEINFO(QXmlName, Q_MOVABLE_TYPE); + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QXmlName) /* This macro must appear after QT_END_NAMESPACE. */ + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qxmlnamepool.cpp b/src/xmlpatterns/api/qxmlnamepool.cpp new file mode 100644 index 0000000..bd1f67f --- /dev/null +++ b/src/xmlpatterns/api/qxmlnamepool.cpp @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qnamepool_p.h" +#include "qxmlnamepool.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QXmlNamePool + \brief The QXmlNamePool class is a table of shared strings referenced by instances of QXmlName. + \reentrant + \since 4.4 + \ingroup xml-tools + + QXmlNamePool is used to optimize operations on instances of + QXmlName. An instance of QXmlName represents an XML name in + a way that allows the XML name to be compared and passed around + efficiently. The efficiency is achieved by storing the strings + comprising the XML names in an instance of QXmlNamePool, where + they are mapped to binary identifiers, which are then packed + into a key which is stored in the QXmlName. + + This means that each instance of QXmlName is tied to the name + pool it was created with, and that name pool should be kept in + scope and used to create all instances of QXmlName that might + be compared. Note also that the name pool is required if you + must reconstitute the QXmlName as text, or if you must access + any of its component strings, so although instances of + QXmlName can be compared without reference to a name pool, the + name pool must be kept in scope if the name's strings must be + accessed later. + + \sa QXmlName + \sa QXmlQuery::namePool() + */ + +/*! + Constructs an empty name pool. + */ +QXmlNamePool::QXmlNamePool() : d(new QPatternist::NamePool()) +{ +} + +/*! + Constructs a copy of the \a other name pool. + */ +QXmlNamePool::QXmlNamePool(const QXmlNamePool &other) : d(other.d) +{ +} + +/*! + Destroys the name pool. Instances of QXmlName constructed + with this name pool can still be compared after this destructor + is called, but their text strings cannot be accessed. + */ +QXmlNamePool::~QXmlNamePool() +{ +} + +QXmlNamePool::QXmlNamePool(QPatternist::NamePool *namePool) : d(QExplicitlySharedDataPointer(namePool)) +{ +} + +/*! + Assigns the \a other name pool to this one. + */ +QXmlNamePool &QXmlNamePool::operator=(const QXmlNamePool &other) +{ + d = other.d; + return *this; +} + +QT_END_NAMESPACE + diff --git a/src/xmlpatterns/api/qxmlnamepool.h b/src/xmlpatterns/api/qxmlnamepool.h new file mode 100644 index 0000000..df9285c --- /dev/null +++ b/src/xmlpatterns/api/qxmlnamepool.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QXMLNAMEPOOL_H +#define QXMLNAMEPOOL_H + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(XmlPatterns) + +namespace QPatternist +{ + class NamePool; + class XsdSchemaParser; + class XsdValidatingInstanceReader; +} + +namespace QPatternistSDK +{ + class Global; +} + +class QXmlQueryPrivate; +class QXmlName; + +class Q_XMLPATTERNS_EXPORT QXmlNamePool +{ +public: + QXmlNamePool(); + QXmlNamePool(const QXmlNamePool &other); + ~QXmlNamePool(); + QXmlNamePool &operator=(const QXmlNamePool &other); + +private: + QXmlNamePool(QPatternist::NamePool *namePool); + friend class QXmlQueryPrivate; + friend class QXmlQuery; + friend class QXmlSchemaPrivate; + friend class QXmlSchemaValidatorPrivate; + friend class QXmlSerializerPrivate; + friend class QXmlName; + friend class QPatternist::XsdSchemaParser; + friend class QPatternist::XsdValidatingInstanceReader; + friend class QPatternistSDK::Global; + QExplicitlySharedDataPointer d; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qxmlpatternistcli_p.h b/src/xmlpatterns/api/qxmlpatternistcli_p.h new file mode 100644 index 0000000..328adcf --- /dev/null +++ b/src/xmlpatterns/api/qxmlpatternistcli_p.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the XMLPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_Cli_h +#define Patternist_Cli_h + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QXmlPatternistCLI +{ +public: + Q_DECLARE_TR_FUNCTIONS(QXmlPatternistCLI) +private: + inline QXmlPatternistCLI(); + Q_DISABLE_COPY(QXmlPatternistCLI) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qxmlquery.cpp b/src/xmlpatterns/api/qxmlquery.cpp new file mode 100644 index 0000000..d74a536 --- /dev/null +++ b/src/xmlpatterns/api/qxmlquery.cpp @@ -0,0 +1,1209 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +#include "qacceltreeresourceloader_p.h" +#include "qcommonvalues_p.h" +#include "qxmlresultitems.h" +#include "qxmlresultitems_p.h" +#include "qxmlserializer.h" +#include "qxpathhelper_p.h" + +#include "qxmlquery.h" +#include "qxmlquery_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QXmlQuery + + \brief The QXmlQuery class performs XQueries on XML data, or on non-XML data modeled to look like XML. + + \reentrant + \since 4.4 + \ingroup xml-tools + + The QXmlQuery class compiles and executes queries written in the + \l {http://www.w3.org/TR/xquery/}{XQuery language}. QXmlQuery is + typically used to query XML data, but it can also query non-XML + data that has been modeled to look like XML. + + Using QXmlQuery to query XML data, as in the snippet below, is + simple because it can use the built-in \l {QAbstractXmlNodeModel} + {XML data model} as its delegate to the underlying query engine for + traversing the data. The built-in data model is specified in \l + {http://www.w3.org/TR/xpath-datamodel/} {XQuery 1.0 and XPath 2.0 + Data Model}. + + \snippet doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlreceiver.cpp 0 + + The example uses QXmlQuery to match the first paragraph of an XML + document and then \l {QXmlSerializer} {output the result} to a + device as XML. + + Using QXmlQuery to query \e {non-XML} data requires writing a + subclass of QAbstractXmlNodeModel to use as a replacement for the + built-in XML data model. The custom data model will be able to + traverse the non-XML data as required by the QAbstractXmlNodeModel + interface. An instance of this custom data model then becomes the + delegate used by the query engine to traverse the non-XML data. For + an example of how to use QXmlQuery to query non-XML data, see the + documentation for QAbstractXmlNodeModel. + + \section1 Running XQueries + + To run a query set up with QXmlQuery, call one of the evaluation + functions. + + \list + + \o evaluateTo(QAbstractXmlReceiver *) is called with a pointer to an + XML \l {QAbstractXmlReceiver} {receiver}, which receives the query + results as a sequence of callbacks. The receiver callback class is + like the callback class used for translating the output of a SAX + parser. QXmlSerializer, for example, is a receiver callback class + for translating the sequence of callbacks for output as unformatted + XML text. + + \endlist + + \list + + \o evaluateTo(QXmlResultItems *) is called with a pointer to an + iterator for an empty sequence of query \l {QXmlResultItems} {result + items}. The Java-like iterator allows the query results to be + accessed sequentially. + + \endlist + + \list + + \o evaluateTo(QStringList *) is like evaluateTo(QXmlResultItems *), + but the query must evaluate to a sequence of strings. + + \endlist + + \section1 Running XPath Expressions + + The XPath language is a subset of the XQuery language, so + running an XPath expression is the same as running an XQuery + query. Pass the XPath expression to QXmlQuery using setQuery(). + + \section1 Running XSLT stylesheets + + Running an XSLT stylesheet is like running an XQuery, except that + when you construct your QXmlQuery, you must pass QXmlQuery::XSLT20 + to tell QXmlQuery to interpret whatever it gets from setQuery() as + an XSLT stylesheet instead of as an XQuery. You must also set the + input document by calling setFocus(). + + \snippet doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp 7 + + \note Currently, setFocus() must be called \e before setQuery() when + using XSLT. + + Another way to run an XSLT stylesheet is to use the \c xmlpatterns + command line utility. + + \code + xmlpatterns myStylesheet.xsl myInput.xml + \endcode + + \note For the current release, XSLT support should be considered + experimental. See section \l{XQuery#XSLT 2.0} {XSLT conformance} for + details. + + Stylesheet parameters are bound using bindVariable(). + + \section1 Binding A Query To A Starting Node + + When a query is run on XML data, as in the snippet above, the + \c{doc()} function returns the node in the built-in data model where + the query evaluation will begin. But when a query is run on a custom + node model containing non-XML data, one of the bindVariable() + functions must be called to bind a variable name to a starting node + in the custom model. A $variable reference is used in the XQuery + text to access the starting node in the custom model. It is not + necessary to declare the variable name external in the query. See + the example in the documentation for QAbstractXmlNodeModel. + + \section1 Reentrancy and Thread-Safety + + QXmlQuery is reentrant but not thread-safe. It is safe to use the + QxmlQuery copy constructor to create a copy of a query and run the + same query multiple times. Behind the scenes, QXmlQuery will reuse + resources such as opened files and compiled queries to the extent + possible. But it is not safe to use the same instance of QXmlQuery + in multiple threads. + + \section1 Error Handling + + Errors can occur during query evaluation. Examples include type + errors and file loading errors. When an error occurs: + + \list + + \o The error message is sent to the messageHandler(). + + \o QXmlResultItems::hasError() will return \c{true}, or + evaluateTo() will return \c{false}; + + \o The results of the evaluation are undefined. + + \endlist + + \section1 Resource Management + + When a query runs, it parses documents, allocating internal data + structures to hold them, and it may load other resources over the + network. It reuses these allocated resources when possible, to + avoid having to reload and reparse them. + + When setQuery() is called, the query text is compiled into an + internal data structure and optimized. The optimized form can + then be reused for multiple evaluations of the query. Since the + compile-and-optimize process can be expensive, repeating it for + the same query should be avoided by using a separate instance of + QXmlQuery for each query text. + + Once a document has been parsed, its internal representation is + maintained in the QXmlQuery instance and shared among multiple + QXmlQuery instances. + + An instance of QCoreApplication must exist before QXmlQuery can be + used. + + \section1 Event Handling + + When QXmlQuery accesses resources (e.g., calling \c fn:doc() to load a file, + or accessing a device via a bound variable), the event loop is used, which + means events will be processed. To avoid processing events when QXmlQuery + accesses resources, create your QXmlQuery instance in a separate thread. + */ + +/*! + \enum QXmlQuery::QueryLanguage + \since 4.5 + + Specifies whether you want QXmlQuery to interpret the input to + setQuery() as an XQuery or as an XSLT stylesheet. + + \value XQuery10 XQuery 1.0. + \value XSLT20 XSLT 2.0 + \omitvalue XmlSchema11IdentityConstraintSelector The selector, the restricted + XPath pattern found in W3C XML Schema 1.1 for uniqueness + contraints. Apart from restricting the syntax, the type check stage + for the expression assumes a sequence of nodes to be the focus. + \omitvalue XmlSchema11IdentityConstraintField The field, the restricted + XPath pattern found in W3C XML Schema 1.1 for uniqueness + contraints. Apart from restricting the syntax, the type check stage + for the expression assumes a sequence of nodes to be the focus. + \omitvalue XPath20 Signifies XPath 2.0. Has no effect in the public API, it's + used internally. As With XmlSchema11IdentityConstraintSelector and + XmlSchema11IdentityConstraintField, the type check stage + for the expression assumes a sequence of nodes to be the focus. + + \sa setQuery() + */ + +// ### Qt5: Merge constructor overloads +/*! + Constructs an invalid, empty query that cannot be used until + setQuery() is called. + + \note This constructor must not be used if you intend to use + this QXmlQuery to process XSL-T stylesheets. The other constructor + must be used in that case. + */ +QXmlQuery::QXmlQuery() : d(new QXmlQueryPrivate()) +{ +} + +/*! + Constructs a QXmlQuery that is a copy of \a other. The new + instance will share resources with the existing query + to the extent possible. + */ +QXmlQuery::QXmlQuery(const QXmlQuery &other) : d(new QXmlQueryPrivate(*other.d)) +{ + /* First we have invoked QXmlQueryPrivate's synthesized copy constructor. + * Keep this section in sync with QXmlQuery::operator=(). */ + d->detach(); +} + +/*! + Constructs a query that will use \a np as its name pool. The query + cannot be evaluated until setQuery() has been called. + */ +QXmlQuery::QXmlQuery(const QXmlNamePool &np) : d(new QXmlQueryPrivate(np)) +{ +} + +/*! + + Constructs a query that will be used to run Xqueries or XSL-T + stylesheets, depending on the value of \a queryLanguage. It will use + \a np as its name pool. + + \note If your QXmlQuery will process XSL-T stylesheets, this + constructor must be used. The default constructor can only + create instances of QXmlQuery for running XQueries. + + \note The XSL-T support in this release is considered experimental. + See the \l{XQuery#XSLT 2.0} {XSLT conformance} for details. + + \since 4.5 + \sa queryLanguage() + */ +QXmlQuery::QXmlQuery(QueryLanguage queryLanguage, + const QXmlNamePool &np) : d(new QXmlQueryPrivate(np)) +{ + d->queryLanguage = queryLanguage; +} + +/*! + Destroys this QXmlQuery. + */ +QXmlQuery::~QXmlQuery() +{ + delete d; +} + +/*! + Assigns \a other to this QXmlQuery instance. + */ +QXmlQuery &QXmlQuery::operator=(const QXmlQuery &other) +{ + /* Keep this section in sync with QXmlQuery::QXmlQuery(const QXmlQuery &). + */ + if(d != other.d) + { + *d = *other.d; + d->detach(); + } + + return *this; +} + +/*! + Changes the \l {QAbstractMessageHandler}{message handler} for this + QXmlQuery to \a aMessageHandler. The query sends all compile and + runtime messages to this message handler. QXmlQuery does not take + ownership of \a aMessageHandler. + + Normally, the default message handler is sufficient. It writes + compile and runtime messages to \e stderr. The default message + handler includes color codes if \e stderr can render colors. + + Note that changing the message handler after the query has been + compiled has no effect, i.e. the query uses the same message handler + at runtime that it uses at compile time. + + When QXmlQuery calls QAbstractMessageHandler::message(), + the arguments are as follows: + + \table + \header + \o message() argument + \o Semantics + \row + \o QtMsgType type + \o Only QtWarningMsg and QtFatalMsg are used. The former + identifies a compile or runtime warning, while the + latter identifies a dynamic or static error. + \row + \o const QString & description + \o An XHTML document which is the actual message. It is translated + into the current language. + \row + \o const QUrl &identifier + \o Identifies the error with a URI, where the fragment is + the error code, and the rest of the URI is the error namespace. + \row + \o const QSourceLocation & sourceLocation + \o Identifies where the error occurred. + \endtable + + */ +void QXmlQuery::setMessageHandler(QAbstractMessageHandler *aMessageHandler) +{ + d->messageHandler = aMessageHandler; +} + +/*! + Returns the message handler that handles compile and runtime + messages for this QXmlQuery. + */ +QAbstractMessageHandler *QXmlQuery::messageHandler() const +{ + return d->messageHandler; +} + +/*! + Sets this QXmlQuery to an XQuery read from the \a sourceCode + device. The device must have been opened with at least + QIODevice::ReadOnly. + + \a documentURI represents the query obtained from the \a sourceCode + device. It is the base URI of the static context, as defined in the + \l {http://www.w3.org/TR/xquery/}{XQuery language}. It is used + internally to resolve relative URIs that appear in the query, and + for message reporting. \a documentURI can be empty. If it is empty, + the \l{QCoreApplication::applicationFilePath()} {application file + path} is used. If it is not empty, it may be either relative or + absolute. If it is relative, it is resolved itself against the + \l {QCoreApplication::applicationFilePath()} {application file + path} before it is used. If \a documentURI is neither a valid URI + nor empty, the result is undefined. + + If the query contains a static error (e.g. syntax error), an error + message is sent to the messageHandler(), and isValid() will return + \e false. + + Variables must be bound before setQuery() is called. + + The encoding of the XQuery in \a sourceCode is detected internally + using the rules for setting and detecting encoding of XQuery files, + which are explained in the \l {http://www.w3.org/TR/xquery/} + {XQuery language}. + + If \a sourceCode is \c null or not readable, or if \a documentURI is not + a valid URI, behavior is undefined. + \sa isValid() + */ +void QXmlQuery::setQuery(QIODevice *sourceCode, const QUrl &documentURI) +{ + if(!sourceCode) + { + qWarning("A null QIODevice pointer cannot be passed."); + return; + } + + if(!sourceCode->isReadable()) + { + qWarning("The device must be readable."); + return; + } + + d->queryURI = QPatternist::XPathHelper::normalizeQueryURI(documentURI); + d->expression(sourceCode); +} + +/*! + \overload + The behavior and requirements of this function are the same as for + setQuery(QIODevice*, const QUrl&), after the XQuery has been read + from the IO device into a string. Because \a sourceCode is already + a Unicode string, detection of its encoding is unnecessary. +*/ +void QXmlQuery::setQuery(const QString &sourceCode, const QUrl &documentURI) +{ + Q_ASSERT_X(documentURI.isEmpty() || documentURI.isValid(), Q_FUNC_INFO, + "The document URI must be valid."); + + QByteArray query(sourceCode.toUtf8()); + QBuffer buffer(&query); + buffer.open(QIODevice::ReadOnly); + + setQuery(&buffer, documentURI); +} + +/*! + Sets this QXmlQuery to the XQuery read from the \a queryURI. Use + isValid() after calling this function. If an error occurred reading + \a queryURI, e.g., the query does not exist, cannot be read, or is + invalid, isValid() will return \e false. + + The supported URI schemes are the same as those in the XQuery + function \c{fn:doc}, except that queryURI can be the object of + a variable binding. + + \a baseURI is the Base URI of the static context, as defined in the + \l {http://www.w3.org/TR/xquery/}{XQuery language}. It is used + internally to resolve relative URIs that appear in the query, and + for message reporting. If \a baseURI is empty, \a queryURI is used. + Otherwise, \a baseURI is used, and it is resolved against the \l + {QCoreApplication::applicationFilePath()} {application file path} if + it is relative. + + If \a queryURI is empty or invalid, or if \a baseURI is invalid, + the behavior of this function is undefined. + */ +void QXmlQuery::setQuery(const QUrl &queryURI, const QUrl &baseURI) +{ + Q_ASSERT_X(queryURI.isValid(), Q_FUNC_INFO, "The passed URI must be valid."); + + const QUrl canonicalURI(QPatternist::XPathHelper::normalizeQueryURI(queryURI)); + Q_ASSERT(canonicalURI.isValid()); + Q_ASSERT(!canonicalURI.isRelative()); + Q_ASSERT(baseURI.isValid() || baseURI.isEmpty()); + + d->queryURI = QPatternist::XPathHelper::normalizeQueryURI(baseURI.isEmpty() ? queryURI : baseURI); + + QPatternist::AutoPtr result; + + try + { + result.reset(QPatternist::AccelTreeResourceLoader::load(canonicalURI, d->m_networkAccessDelegator, + d->staticContext())); + } + catch(const QPatternist::Exception) + { + /* We do nothing, result will be 0. */ + } + + if(result) + { + setQuery(result.data(), d->queryURI); + result->close(); + } + else + d->recompileRequired(); +} + +/*! + Binds the variable \a name to the \a value so that $\a name can be + used from within the query to refer to the \a value. + + \a name must not be \e null. \a {name}.isNull() must return false. + If \a name has already been bound by a previous bindVariable() call, + its previous binding will be overridden. + + If \a {value} is null so that \a {value}.isNull() returns true, and + \a {name} already has a binding, the effect is to remove the + existing binding for \a {name}. + + To bind a value of type QString or QUrl, wrap the value in a + QVariant such that QXmlItem's QVariant constructor is called. + + All strings processed by the query must be valid XQuery strings, + which means they must contain only XML 1.0 characters. However, + this requirement is not checked. If the query processes an invalid + string, the behavior is undefined. + + \sa QVariant::isValid(), {QtXDM}{How QVariant maps to XQuery's Data Model}, + QXmlItem::isNull() + */ +void QXmlQuery::bindVariable(const QXmlName &name, const QXmlItem &value) +{ + if(name.isNull()) + { + qWarning("The variable name cannot be null."); + return; + } + + const QPatternist::VariableLoader::Ptr vl(d->variableLoader()); + const QVariant variant(QVariant::fromValue(value)); + + /* If the type of the variable changed(as opposed to only the value), + * we will have to recompile. */ + if(vl->invalidationRequired(name, variant) || value.isNull()) + d->recompileRequired(); + + vl->addBinding(name, variant); +} + +/*! + \overload + + This function constructs a QXmlName from \a localName using the + query's \l {QXmlNamePool} {namespace}. The function then behaves as + the overloaded function. It is equivalent to the following snippet. + + \snippet doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp 0 + */ +void QXmlQuery::bindVariable(const QString &localName, const QXmlItem &value) +{ + bindVariable(QXmlName(d->namePool, localName), value); +} + +/*! + Binds the variable \a name to the \a device so that $\a name can be + used from within the query to refer to the \a device. The QIODevice + \a device is exposed to the query as a URI of type \c{xs:anyURI}, + which can be passed to the \c{fn:doc()} function to be read. E.g., + this function can be used to pass an XML document in memory to + \c{fn:doc}. + + \snippet doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp 1 + + The caller must ensure that \a device has been opened with at least + QIODevice::ReadOnly prior to this binding. Otherwise, behavior is + undefined. + + If the query will access an XML document contained in a QString, use + a QBuffer as shown in the following snippet. Suppose \e myQString + contains \c{content} + + \snippet doc/src/snippets/qxmlquery/bindingExample.cpp 0 + + \a name must not be \e null. \a {name}.isNull() must return false. + If \a name has already been bound, its previous binding will be + overridden. The URI that \a name evaluates to is arbitrary and may + change. + + If the type of the variable binding changes (e.g., if a previous + binding by the same name was a QVariant, or if there was no previous + binding), isValid() will return \c{false}, and recompilation of the + query text is required. To recompile the query, call setQuery(). For + this reason, bindVariable() should be called before setQuery(), if + possible. + + \note \a device must not be deleted while this QXmlQuery exists. +*/ +void QXmlQuery::bindVariable(const QXmlName &name, QIODevice *device) +{ + if(device && !device->isReadable()) + { + qWarning("A null, or readable QIODevice must be passed."); + return; + } + + if(name.isNull()) + { + qWarning("The variable name cannot be null."); + return; + } + + const QPatternist::VariableLoader::Ptr vl(d->variableLoader()); + + if(device) + { + const QVariant variant(QVariant::fromValue(device)); + + if(vl->invalidationRequired(name, variant)) + d->recompileRequired(); + + vl->addBinding(name, variant); + + /* We need to tell the resource loader to discard its document, because + * the underlying QIODevice has changed, but the variable name is the + * same which means that the URI is the same, and hence the resource + * loader will return the document for the old QIODevice. + */ + d->resourceLoader()->clear(QUrl(QLatin1String("tag:trolltech.com,2007:QtXmlPatterns:QIODeviceVariable:") + d->namePool.d->stringForLocalName(name.localName()))); + } + else + { + vl->removeBinding(name); + d->recompileRequired(); + } +} + +/*! + \overload + + If \a localName is a valid \l {QXmlName::isNCName()} {NCName}, this + function is equivalent to the following snippet. + + \snippet doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp 2 + + A QXmlName is constructed from \a localName, and is passed + to the appropriate overload along with \a device. + + \sa QXmlName::isNCName() + */ +void QXmlQuery::bindVariable(const QString &localName, QIODevice *device) +{ + bindVariable(QXmlName(d->namePool, localName), device); +} + +/*! + Evaluates this query and sends the result as a sequence of callbacks + to the \l {QAbstractXmlReceiver} {receiver} \a callback. QXmlQuery + does not take ownership of \a callback. + + If an error occurs during the evaluation, error messages are sent to + messageHandler() and \c false is returned. + + If this query \l {isValid()} {is invalid}, \c{false} is returned + and the behavior is undefined. If \a callback is null, + behavior is undefined. + + \sa QAbstractXmlReceiver, isValid() + */ +bool QXmlQuery::evaluateTo(QAbstractXmlReceiver *callback) const +{ + if(!callback) + { + qWarning("A non-null callback must be passed."); + return false; + } + + if(isValid()) + { + try + { + /* + * This order is significant. expression() might cause + * query recompilation, and as part of that it recreates + * the static context. However, if we create the dynamic + * context before the query recompilation has been + * triggered, it will use the old static context, and + * hence old source locations. + */ + const QPatternist::Expression::Ptr expr(d->expression()); + const QPatternist::DynamicContext::Ptr dynContext(d->dynamicContext(callback)); + callback->startOfSequence(); + expr->evaluateToSequenceReceiver(dynContext); + callback->endOfSequence(); + return true; + } + catch(const QPatternist::Exception) + { + return false; + } + } + else + return false; +} + +/*! + Attempts to evaluate the query and returns the results in the + \a target \l {QStringList} {string list}. + + If the query \l {isValid()} {is valid} and the evaluation succeeds, + true is returned. Otherwise, false is returned and the contents of + \a target are undefined. + + The query must evaluate to a sequence of \c{xs:string} values. If + the query does not evaluate to a sequence of strings, the values can + often be converted by adding a call to \c{string()} at the end of + the XQuery. + + If \a target is null, the behavior is undefined. + */ +bool QXmlQuery::evaluateTo(QStringList *target) const +{ + if(!target) + { + qWarning("A non-null callback must be passed."); + return false; + } + + if(isValid()) + { + try + { + /* + * This order is significant. expression() might cause + * query recompilation, and as part of that it recreates + * the static context. However, if we create the dynamic + * context before the query recompilation has been + * triggered, it will use the old static context, and + * hence old source locations. + */ + const QPatternist::Expression::Ptr expr(d->expression()); + if(!expr) + return false; + + QPatternist::DynamicContext::Ptr dynContext(d->dynamicContext()); + + if(!QPatternist::BuiltinTypes::xsString->xdtTypeMatches(expr->staticType()->itemType())) + return false; + + const QPatternist::Item::Iterator::Ptr it(expr->evaluateSequence(dynContext)); + QPatternist::Item next(it->next()); + + while(!next.isNull()) + { + target->append(next.stringValue()); + next = it->next(); + } + + return true; + } + catch(const QPatternist::Exception) + { + return false; + } + } + else + return false; +} + +/*! + Evaluates the query or stylesheet, and writes the output to \a target. + + QXmlSerializer is used to write the output to \a target. In a future + release, it is expected that this function will be changed to + respect serialization options set in the stylesheet. + + If an error occurs during the evaluation, error messages are sent to + messageHandler() and \c false is returned. + + If \a target is \c null, or is not opened in at least + QIODevice::WriteOnly mode, the behavior is undefined. QXmlQuery + does not take ownership of \a target. + + \since 4.5 + \overload + */ +bool QXmlQuery::evaluateTo(QIODevice *target) const +{ + if(!target) + { + qWarning("The pointer to the device cannot be null."); + return false; + } + + if(!target->isWritable()) + { + qWarning("The device must be writable."); + return false; + } + + QXmlSerializer serializer(*this, target); + return evaluateTo(&serializer); +} + +/*! + Starts the evaluation and makes it available in \a result. If \a + result is null, the behavior is undefined. The evaluation takes + place incrementally (lazy evaluation), as the caller uses + QXmlResultItems::next() to get the next result. + + \sa QXmlResultItems::next() +*/ +void QXmlQuery::evaluateTo(QXmlResultItems *result) const +{ + if(!result) + { + qWarning("A null pointer cannot be passed."); + return; + } + + if(isValid()) + { + try + { + /* + * We don't have the d->expression() calls and + * d->dynamicContext() calls in the same order as seen in + * QXmlQuery::evaluateTo(), and the reason to why + * that isn't a problem, is that we call isValid(). + */ + const QPatternist::DynamicContext::Ptr dynContext(d->dynamicContext()); + result->d_ptr->setDynamicContext(dynContext); + result->d_ptr->iterator = d->expression()->evaluateSequence(dynContext); + } + catch(const QPatternist::Exception) + { + result->d_ptr->iterator = QPatternist::CommonValues::emptyIterator; + result->d_ptr->hasError = true; + } + } + else + { + result->d_ptr->iterator= QPatternist::CommonValues::emptyIterator; + result->d_ptr->hasError = true; + } +} + +/*! + Evaluates the query, and serializes the output as XML to \a output. + + If an error occurs during the evaluation, error messages are sent to + messageHandler(), the content of \a output is undefined and \c false is + returned, otherwise \c true is returned. + + If \a output is \c null behavior is undefined. QXmlQuery + does not take ownership of \a output. + + Internally, the class QXmlFormatter is used for this. + \since 4.5 + */ +bool QXmlQuery::evaluateTo(QString *output) const +{ + Q_ASSERT_X(output, Q_FUNC_INFO, + "The input cannot be null"); + + QBuffer outputDevice; + outputDevice.open(QIODevice::ReadWrite); + + QXmlFormatter formatter(*this, &outputDevice); + const bool success = evaluateTo(&formatter); + + outputDevice.close(); + *output = QString::fromUtf8(outputDevice.data().constData()); + + return success; +} + +/*! + Returns true if this query is valid. Examples of invalid queries + are ones that contain syntax errors or that have not had setQuery() + called for them yet. + */ +bool QXmlQuery::isValid() const +{ + return d->isValid(); +} + +/*! + Sets the URI resolver to \a resolver. QXmlQuery does not take + ownership of \a resolver. + + \sa uriResolver() + */ +void QXmlQuery::setUriResolver(const QAbstractUriResolver *resolver) +{ + d->uriResolver = resolver; +} + +/*! + Returns the query's URI resolver. If no URI resolver has been set, + QtXmlPatterns will use the URIs in queries as they are. + + The URI resolver provides a level of abstraction, or \e{polymorphic + URIs}. A resolver can rewrite \e{logical} URIs to physical ones, or + it can translate obsolete or invalid URIs to valid ones. + + QtXmlPatterns calls the URI resolver for all URIs it encounters, + except for namespaces. Specifically, all builtin functions that deal + with URIs (\c{fn:doc()}, and \c{fn:doc-available()}). + + In the case of \c{fn:doc()}, the absolute URI is the base URI in the + static context (which most likely is the location of the query). + Rather than use the URI the user specified, the return value of + QAbstractUriResolver::resolve() will be used. + + When QtXmlPatterns calls QAbstractUriResolver::resolve() the + absolute URI is the URI mandated by the XQuery language, and the + relative URI is the URI specified by the user. + + \sa setUriResolver() + */ +const QAbstractUriResolver *QXmlQuery::uriResolver() const +{ + return d->uriResolver; +} + +/*! + Returns the name pool used by this QXmlQuery for constructing \l + {QXmlName} {names}. There is no setter for the name pool, because + mixing name pools causes errors due to name confusion. + */ +QXmlNamePool QXmlQuery::namePool() const +{ + return d->namePool; +} + +/*! + Sets the focus to \a item. The focus is the set of items that the + context item expression and path expressions navigate from. For + example, in the expression \e p/span, the element that \e p + evaluates to is the focus for the following expression, \e span. + + The focus can be accessed using the context item expression, i.e., + dot ("."). + + By default, the focus is not set and is undefined. It will + therefore result in a dynamic error, \c XPDY0002, if the focus + is attempted to be accessed. The focus must be set before the + query is set with setQuery(). + + There is no behavior defined for setting an item which is null. + + */ +void QXmlQuery::setFocus(const QXmlItem &item) +{ + d->contextItem = item; +} + +/** + * This function should be a private member function of QXmlQuery, + * but we don't dare that due to our weird compilers. + * @internal + * @relates QXmlQuery + */ +template +bool setFocusHelper(QXmlQuery *const queryInstance, + const TInputType &focusValue) +{ + /* We call resourceLoader(), so we have ensured that we have a resourceLoader + * that we will share in our copy. */ + queryInstance->d->resourceLoader(); + + QXmlQuery focusQuery(*queryInstance); + + /* Now we use the same, so we own the loaded document. */ + focusQuery.d->m_resourceLoader = queryInstance->d->m_resourceLoader; + + /* The copy constructor doesn't allow us to copy an existing QXmlQuery and + * changing the language at the same time so we need to use private API. */ + focusQuery.d->queryLanguage = QXmlQuery::XQuery10; + + Q_ASSERT(focusQuery.queryLanguage() == QXmlQuery::XQuery10); + focusQuery.bindVariable(QChar::fromLatin1('u'), focusValue); + focusQuery.setQuery(QLatin1String("doc($u)")); + Q_ASSERT(focusQuery.isValid()); + + QXmlResultItems focusResult; + + queryInstance->d->m_resourceLoader = focusQuery.d->m_resourceLoader; + + focusQuery.evaluateTo(&focusResult); + const QXmlItem focusItem(focusResult.next()); + + if(focusItem.isNull() || focusResult.hasError()) + return false; + else + { + queryInstance->setFocus(focusItem); + return true; + } +} + +/*! + \since 4.5 + \overload + + Sets the focus to be the document located at \a documentURI and + returns true. If \a documentURI cannot be loaded, false is returned. + It is undefined at what time the document may be loaded. When + loading the document, the message handler and URI resolver set on + this QXmlQuery are used. + + If \a documentURI is empty or is not a valid URI, the behavior of + this function is undefined. + */ +bool QXmlQuery::setFocus(const QUrl &documentURI) +{ + Q_ASSERT_X(documentURI.isValid() && !documentURI.isEmpty(), + Q_FUNC_INFO, + "The URI passed must be valid."); + + return setFocusHelper(this, QVariant(documentURI)); +} + +/*! + + Sets the focus to be the \a document read from the QIODevice and + returns true. If \a document cannot be loaded, false is returned. + + QXmlQuery does not take ownership of \a document. The user + guarantees that a document is available from the \a document device + and that the document is not empty. The device must be opened in at + least read-only mode. \a document must stay in scope as long as the + current query is active. + + \since 4.5 + \overload + */ +bool QXmlQuery::setFocus(QIODevice *document) +{ + if(!document) + { + qWarning("A null QIODevice pointer cannot be passed."); + return false; + } + + if(!document->isReadable()) + { + qWarning("The device must be readable."); + return false; + } + + return setFocusHelper(this, document); +} + +/*! + This function behaves identically to calling the setFocus() overload with a + QIODevice whose content is \a focus encoded as UTF-8. That is, \a focus is + treated as if it contained an XML document. + + Returns the same result as the overload. + + \overload + \since 4.6 + */ +bool QXmlQuery::setFocus(const QString &focus) +{ + QBuffer device; + device.setData(focus.toUtf8()); + device.open(QIODevice::ReadOnly); + + return setFocusHelper(this, &device); +} + +/*! + Returns a value indicating what this QXmlQuery is being used for. + The default is QXmlQuery::XQuery10, which means the QXmlQuery is + being used for running XQuery and XPath queries. QXmlQuery::XSLT20 + can also be returned, which indicates the QXmlQuery is for running + XSL-T spreadsheets. + + \since 4.5 + */ +QXmlQuery::QueryLanguage QXmlQuery::queryLanguage() const +{ + return d->queryLanguage; +} + +/*! + Sets the \a name of the initial template. The initial template is + the one the processor calls first, instead of attempting to match a + template to the context node (if any). If an initial template is not + set, the standard order of template invocation will be used. + + This function only applies when using QXmlQuery to process XSL-T + stylesheets. The name becomes part of the compiled stylesheet. + Therefore, this function must be called before calling setQuery(). + + If the stylesheet has no template named \a name, the processor will + use the standard order of template invocation. + + \since 4.5 + \sa initialTemplateName() + */ +void QXmlQuery::setInitialTemplateName(const QXmlName &name) +{ + d->initialTemplateName = name; +} + +/*! + \overload + + Sets the name of the initial template to \a localName, which must be + a valid \l{QXmlName::localName()} {local name}. The initial template + is the one the processor calls first, instead of attempting to match + a template to the context node (if any). If an initial template is + not set, the standard order of template invocation will be used. + + This function only applies when using QXmlQuery to process XSL-T + stylesheets. The name becomes part of the compiled stylesheet. + Therefore, this function must be called before calling setQuery(). + + If \a localName is not a valid \l{QXmlName::localName()} {local + name}, the effect is undefined. If the stylesheet has no template + named \a localName, the processor will use the standard order of + template invocation. + + \since 4.5 + \sa initialTemplateName() + */ +void QXmlQuery::setInitialTemplateName(const QString &localName) +{ + Q_ASSERT_X(QXmlName::isNCName(localName), + Q_FUNC_INFO, + "The name passed must be a valid NCName."); + setInitialTemplateName(QXmlName(d->namePool, localName)); +} + +/*! + Returns the name of the XSL-T stylesheet template that the processor + will call first when running an XSL-T stylesheet. This function only + applies when using QXmlQuery to process XSL-T stylesheets. By + default, no initial template is set. In that case, a default + constructed QXmlName is returned. + + \since 4.5 + */ +QXmlName QXmlQuery::initialTemplateName() const +{ + return d->initialTemplateName; +} + +/*! + Sets the network manager to \a newManager. + QXmlQuery does not take ownership of \a newManager. + + \sa networkAccessManager() + \since 4.5 + */ +void QXmlQuery::setNetworkAccessManager(QNetworkAccessManager *newManager) +{ + d->m_networkAccessDelegator->m_genericManager = newManager; +} + +/*! + Returns the network manager, or 0 if it has not been set. + + \sa setNetworkAccessManager() + \since 4.5 + */ +QNetworkAccessManager *QXmlQuery::networkAccessManager() const +{ + return d->m_networkAccessDelegator->m_genericManager; +} + +/*! + Binds the result of the query \a query, to a variable by name \a name. + + Evaluation of \a query will be commenced when this function is called. + + If \a query is invalid, behavior is undefined. \a query will be copied. + + \since 4.5 + \sa isValid() + */ +void QXmlQuery::bindVariable(const QXmlName &name, const QXmlQuery &query) +{ + Q_ASSERT_X(query.isValid(), Q_FUNC_INFO, "The query being bound must be valid."); + + const QPatternist::VariableLoader::Ptr vl(d->variableLoader()); + const QVariant variant(QVariant::fromValue(query)); + + if(vl->invalidationRequired(name, variant)) + d->recompileRequired(); + + vl->addBinding(name, variant); +} + +/*! + \overload + + Has the same behavior and effects as the function being overloaded, but takes + the variable name \a localName as a QString. \a query is used as in the + overloaded function. + + \since 4.5 + */ +void QXmlQuery::bindVariable(const QString &localName, const QXmlQuery &query) +{ + return bindVariable(QXmlName(d->namePool, localName), query); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/api/qxmlquery.h b/src/xmlpatterns/api/qxmlquery.h new file mode 100644 index 0000000..041d035 --- /dev/null +++ b/src/xmlpatterns/api/qxmlquery.h @@ -0,0 +1,155 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QXMLQUERY_H +#define QXMLQUERY_H + +#include +#include +#include +#include + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +QT_MODULE(XmlPatterns) + +class QAbstractMessageHandler; +class QAbstractUriResolver; +class QIODevice; +class QNetworkAccessManager; +class QXmlName; +class QXmlNodeIndex; +class QXmlQueryPrivate; +class QXmlResultItems; +class QXmlSerializer; + +/* The members in the namespace QPatternistSDK are internal, not part of the public API, and + * unsupported. Using them leads to undefined behavior. */ +namespace QPatternistSDK +{ + class TestCase; +} + +namespace QPatternist +{ + class XsdSchemaParser; + class XsdValidatingInstanceReader; + class VariableLoader; +} + +class Q_XMLPATTERNS_EXPORT QXmlQuery +{ +public: + enum QueryLanguage + { + XQuery10 = 1, + XSLT20 = 2, + XmlSchema11IdentityConstraintSelector = 1024, + XmlSchema11IdentityConstraintField = 2048, + XPath20 = 4096 + }; + + QXmlQuery(); + QXmlQuery(const QXmlQuery &other); + QXmlQuery(const QXmlNamePool &np); + QXmlQuery(QueryLanguage queryLanguage, + const QXmlNamePool &np = QXmlNamePool()); + ~QXmlQuery(); + QXmlQuery &operator=(const QXmlQuery &other); + + void setMessageHandler(QAbstractMessageHandler *messageHandler); + QAbstractMessageHandler *messageHandler() const; + + void setQuery(const QString &sourceCode, const QUrl &documentURI = QUrl()); + void setQuery(QIODevice *sourceCode, const QUrl &documentURI = QUrl()); + void setQuery(const QUrl &queryURI, const QUrl &baseURI = QUrl()); + + QXmlNamePool namePool() const; + + void bindVariable(const QXmlName &name, const QXmlItem &value); + void bindVariable(const QString &localName, const QXmlItem &value); + + void bindVariable(const QXmlName &name, QIODevice *); + void bindVariable(const QString &localName, QIODevice *); + void bindVariable(const QXmlName &name, const QXmlQuery &query); + void bindVariable(const QString &localName, const QXmlQuery &query); + + bool isValid() const; + + void evaluateTo(QXmlResultItems *result) const; + bool evaluateTo(QAbstractXmlReceiver *callback) const; + bool evaluateTo(QStringList *target) const; + bool evaluateTo(QIODevice *target) const; + bool evaluateTo(QString *output) const; + + void setUriResolver(const QAbstractUriResolver *resolver); + const QAbstractUriResolver *uriResolver() const; + + void setFocus(const QXmlItem &item); + bool setFocus(const QUrl &documentURI); + bool setFocus(QIODevice *document); + bool setFocus(const QString &focus); + + void setInitialTemplateName(const QXmlName &name); + void setInitialTemplateName(const QString &name); + QXmlName initialTemplateName() const; + + void setNetworkAccessManager(QNetworkAccessManager *newManager); + QNetworkAccessManager *networkAccessManager() const; + + QueryLanguage queryLanguage() const; +private: + friend class QXmlName; + friend class QXmlSerializer; + friend class QPatternistSDK::TestCase; + friend class QPatternist::XsdSchemaParser; + friend class QPatternist::XsdValidatingInstanceReader; + friend class QPatternist::VariableLoader; + template friend bool setFocusHelper(QXmlQuery *const queryInstance, + const TInputType &focusValue); + QXmlQueryPrivate *d; +}; + +QT_END_NAMESPACE +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qxmlquery_p.h b/src/xmlpatterns/api/qxmlquery_p.h new file mode 100644 index 0000000..629b50b --- /dev/null +++ b/src/xmlpatterns/api/qxmlquery_p.h @@ -0,0 +1,328 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QXMLQUERY_P_H +#define QXMLQUERY_P_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qacceltreebuilder_p.h" +#include "qacceltreeresourceloader_p.h" +#include "qcoloringmessagehandler_p.h" +#include "qcommonsequencetypes_p.h" +#include "qexpressionfactory_p.h" +#include "qfocus_p.h" +#include "qfunctionfactorycollection_p.h" +#include "qgenericdynamiccontext_p.h" +#include "qgenericstaticcontext_p.h" +#include "qnamepool_p.h" +#include "qnetworkaccessdelegator_p.h" +#include "qreferencecountedvalue_p.h" +#include "qresourcedelegator_p.h" +#include "qstaticfocuscontext_p.h" +#include "quriloader_p.h" +#include "qvariableloader_p.h" + +QT_BEGIN_NAMESPACE + +class QXmlQueryPrivate +{ +public: + + inline QXmlQueryPrivate(const QXmlNamePool &np = QXmlNamePool()) : namePool(np) + , messageHandler(0) + , uriResolver(0) + , queryLanguage(QXmlQuery::XQuery10) + , m_networkAccessDelegator(new QPatternist::NetworkAccessDelegator(0, 0)) + { + m_networkAccessDelegator->m_variableURIManager = new QPatternist::URILoader(ownerObject(), namePool.d, variableLoader()); + } + + void detach() + { + if(m_variableLoader) + m_variableLoader = QPatternist::VariableLoader::Ptr(new QPatternist::VariableLoader(namePool.d, m_variableLoader)); + + delete m_networkAccessDelegator->m_variableURIManager; + m_networkAccessDelegator->m_variableURIManager = new QPatternist::URILoader(ownerObject(), namePool.d, m_variableLoader); + + if(m_resourceLoader) + { + const QPatternist::AccelTreeResourceLoader::Ptr nev(new QPatternist::AccelTreeResourceLoader(namePool.d, + m_networkAccessDelegator)); + m_resourceLoader = QPatternist::ResourceLoader::Ptr(new QPatternist::ResourceDelegator(m_resourceLoader->deviceURIs(), + m_resourceLoader, + nev)); + } + } + + bool isValid() + { + return expression(); + } + + inline void recompileRequired() + { + m_expr.reset(); + } + + inline QPatternist::VariableLoader::Ptr variableLoader() + { + if(!m_variableLoader) + m_variableLoader = QPatternist::VariableLoader::Ptr(new QPatternist::VariableLoader(namePool.d)); + + return m_variableLoader; + } + + inline QPatternist::GenericStaticContext::Ptr staticContext() + { + if(m_staticContext && m_expr) + return m_staticContext; + /* Else, re-create the staticContext. */ + + if(!messageHandler) + messageHandler = new QPatternist::ColoringMessageHandler(ownerObject()); + + if(!m_functionFactory) + { + if(queryLanguage == QXmlQuery::XSLT20) + m_functionFactory = QPatternist::FunctionFactoryCollection::xslt20Factory(namePool.d); + else + m_functionFactory = QPatternist::FunctionFactoryCollection::xpath20Factory(namePool.d); + } + + const QPatternist::GenericStaticContext::Ptr genericStaticContext(new QPatternist::GenericStaticContext(namePool.d, + messageHandler, + queryURI, + m_functionFactory, + queryLanguage)); + genericStaticContext->setResourceLoader(resourceLoader()); + + genericStaticContext->setExternalVariableLoader(variableLoader()); + + m_staticContext = genericStaticContext; + + if(!contextItem.isNull()) + m_staticContext = QPatternist::StaticContext::Ptr(new QPatternist::StaticFocusContext(QPatternist::AtomicValue::qtToXDMType(contextItem), m_staticContext)); + else if( queryLanguage == QXmlQuery::XmlSchema11IdentityConstraintField + || queryLanguage == QXmlQuery::XmlSchema11IdentityConstraintSelector + || queryLanguage == QXmlQuery::XPath20) + m_staticContext = QPatternist::StaticContext::Ptr(new QPatternist::StaticFocusContext(QPatternist::BuiltinTypes::node, m_staticContext)); + + for (int i = 0; i < m_additionalNamespaceBindings.count(); ++i) { + m_staticContext->namespaceBindings()->addBinding(m_additionalNamespaceBindings.at(i)); + } + + return m_staticContext; + } + + inline QPatternist::DynamicContext::Ptr dynamicContext(QAbstractXmlReceiver *const callback = 0) + { + const QPatternist::StaticContext::Ptr statContext(staticContext()); + Q_ASSERT(statContext); + + QPatternist::GenericDynamicContext::Ptr dynContext(new QPatternist::GenericDynamicContext(namePool.d, statContext->messageHandler(), + statContext->sourceLocations())); + + QPatternist::AutoPtr nodeBuilder(new QPatternist::AccelTreeBuilder(QUrl(), QUrl(), namePool.d, + dynContext.data())); + dynContext->setNodeBuilder(nodeBuilder); + + dynContext->setResourceLoader(statContext->resourceLoader()); + dynContext->setExternalVariableLoader(statContext->externalVariableLoader()); + dynContext->setUriResolver(uriResolver); + + if(callback) + dynContext->setOutputReceiver(callback); + + if(contextItem.isNull()) + return dynContext; + else + { + QPatternist::DynamicContext::Ptr focus(new QPatternist::Focus(dynContext)); + QPatternist::Item::Iterator::Ptr it(QPatternist::makeSingletonIterator(QPatternist::Item::fromPublic(contextItem))); + it->next(); + focus->setFocusIterator(it); + return focus; + } + } + + inline QPatternist::AccelTreeResourceLoader::Ptr resourceLoader() + { + if(!m_resourceLoader) + m_resourceLoader = (new QPatternist::AccelTreeResourceLoader(namePool.d, m_networkAccessDelegator)); + + return m_resourceLoader; + } + + void setRequiredType(const QPatternist::SequenceType::Ptr &seqType) + { + Q_ASSERT(seqType); + if(!m_requiredType || m_requiredType->is(seqType)) + return; + + m_requiredType = seqType; + m_staticContext.reset(); + } + + QPatternist::SequenceType::Ptr requiredType() + { + if(m_requiredType) + return m_requiredType; + else + { + m_requiredType = QPatternist::CommonSequenceTypes::ZeroOrMoreItems; + return m_requiredType; + } + } + + QPatternist::Expression::Ptr expression(QIODevice *const queryDevice = 0) + { + if(m_expr && !queryDevice) + return m_expr; + + /* If we need to update, but we don't have any source code, we can + * never create an Expression. */ + if(!queryDevice) + return QPatternist::Expression::Ptr(); + + try + { + /* The static context has source locations, and they need to be + * updated to the new query. */ + m_staticContext.reset(); + + if(!m_expressionFactory) + m_expressionFactory = QPatternist::ExpressionFactory::Ptr(new QPatternist::ExpressionFactory()); + + m_expr = m_expressionFactory->createExpression(queryDevice, staticContext(), + queryLanguage, + requiredType(), + queryURI, + initialTemplateName); + } + catch(const QPatternist::Exception) + { + m_expr.reset(); + + /* We don't call m_staticContext.reset() because it shouldn't be + * necessary, since m_staticContext is changed when the expression + * is changed. */ + } + + return m_expr; + } + + inline void addAdditionalNamespaceBinding(const QXmlName &binding) + { + m_additionalNamespaceBindings.append(binding); + } + + QXmlNamePool namePool; + QPointer messageHandler; + /** + * Must be absolute and valid. + */ + QUrl queryURI; + const QAbstractUriResolver * uriResolver; + QXmlItem contextItem; + QXmlName initialTemplateName; + + inline void setExpressionFactory(const QPatternist::ExpressionFactory::Ptr &expr) + { + m_expressionFactory = expr; + } + + QXmlQuery::QueryLanguage queryLanguage; + QPointer userNetworkManager; + + inline QObject *ownerObject() + { + if(!m_owner) + m_owner = new QPatternist::ReferenceCountedValue(new QObject()); + + return m_owner->value; + } + + QPatternist::ExpressionFactory::Ptr m_expressionFactory; + QPatternist::StaticContext::Ptr m_staticContext; + QPatternist::VariableLoader::Ptr m_variableLoader; + QPatternist::DeviceResourceLoader::Ptr m_resourceLoader; + /** + * This is the AST for the query. + */ + QPatternist::Expression::Ptr m_expr; + QPatternist::ReferenceCountedValue::Ptr m_owner; + + /** + * This is our effective network manager, that we end up using. The one the + * user sets is userNetworkManager. + */ + QPatternist::SequenceType::Ptr m_requiredType; + QPatternist::FunctionFactory::Ptr m_functionFactory; + QPatternist::NetworkAccessDelegator::Ptr m_networkAccessDelegator; + + QList m_additionalNamespaceBindings; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qxmlresultitems.cpp b/src/xmlpatterns/api/qxmlresultitems.cpp new file mode 100644 index 0000000..4d167d0 --- /dev/null +++ b/src/xmlpatterns/api/qxmlresultitems.cpp @@ -0,0 +1,152 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qxmlresultitems.h" +#include "qxmlresultitems_p.h" +#include "qitem_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QXmlResultItems + \brief The QXmlResultItems class iterates through the results of evaluating an XQuery in QXmlQuery. + \reentrant + \since 4.4 + \ingroup xml-tools + + QXmlResultItems presents the evaluation of an associated query as a + sequence of \l{QXmlItem}{QXmlItems}. The sequence is traversed by + repeatedly calling next(), which actually produces the sequence by + lazy evaluation of the query. + + \snippet doc/src/snippets/code/src_xmlpatterns_api_qxmlresultitems.cpp 0 + + An effect of letting next() produce the sequence by lazy evaluation + is that a query error can occur on any call to next(). If an error + occurs, both next() and current() will return the null QXmlItem, and + hasError() will return true. + + QXmlResultItems can be thought of as an "iterator" that traverses + the sequence of query results once, in the forward direction. Each + call to next() advances the iterator to the next QXmlItem in the + sequence and returns it, and current() always returns the QXmlItem + that next() returned the last time it was called. + + \note When using the QXmlResultItems overload of QXmlQuery::evaluateTo() + to execute a query, it is advisable to create a new instance of this + class for each new set of results rather than reusing an old instance. + + \sa QXmlItem::isNode(), QXmlItem::isAtomicValue(), QXmlNodeModelIndex + */ + +/*! + Constructs an instance of QXmlResultItems. + */ +QXmlResultItems::QXmlResultItems() : d_ptr(new QXmlResultItemsPrivate()) +{ +} + +/*! + Destroys this instance of QXmlResultItems. + */ +QXmlResultItems::~QXmlResultItems() +{ +} + +/*! + Returns the next result in the sequence produced by lazy evaluation + of the associated query. When the returned QXmlItem is null, either + the evaluation terminated normally without producing another result, + or an error occurred. Call hasError() to determine whether the null + item was caused by normal termination or by an error. + + Returns a null QXmlItem if there is no associated QXmlQuery. + */ +QXmlItem QXmlResultItems::next() +{ + Q_D(QXmlResultItems); + if(d->hasError) + return QXmlItem(); + + try + { + d->current = QPatternist::Item::toPublic(d->iterator->next()); + return d->current; + } + catch(const QPatternist::Exception) + { + d->current = QXmlItem(); + d->hasError = true; + return QXmlItem(); + } +} + +/*! + Returns the current item. The current item is the last item + that was produced and returned by next(). + + Returns a null QXmlItem if there is no associated QXmlQuery. + */ +QXmlItem QXmlResultItems::current() const +{ + Q_D(const QXmlResultItems); + + if(d->hasError) + return QXmlItem(); + else + return d->current; +} + +/*! + + If an error occurred during evaluation of the query, true is + returned. + + Returns false if query evaluation has been done. + */ +bool QXmlResultItems::hasError() const +{ + Q_D(const QXmlResultItems); + return d->hasError; +} + +QT_END_NAMESPACE + diff --git a/src/xmlpatterns/api/qxmlresultitems.h b/src/xmlpatterns/api/qxmlresultitems.h new file mode 100644 index 0000000..0a12048 --- /dev/null +++ b/src/xmlpatterns/api/qxmlresultitems.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QXMLRESULTITEMS +#define QXMLRESULTITEMS + +#include +#include + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +QT_MODULE(XmlPatterns) + +class QXmlItem; +class QXmlQuery; +class QXmlResultItemsPrivate; + +class Q_XMLPATTERNS_EXPORT QXmlResultItems +{ +public: + QXmlResultItems(); + virtual ~QXmlResultItems(); + + bool hasError() const; + QXmlItem next(); + QXmlItem current() const; + +private: + friend class QXmlQuery; + Q_DECLARE_PRIVATE(QXmlResultItems) + QScopedPointer d_ptr; + Q_DISABLE_COPY(QXmlResultItems) +}; + +QT_END_NAMESPACE +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qxmlresultitems_p.h b/src/xmlpatterns/api/qxmlresultitems_p.h new file mode 100644 index 0000000..3d0a0e9 --- /dev/null +++ b/src/xmlpatterns/api/qxmlresultitems_p.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QXMLRESULTITEMS_P_H +#define QXMLRESULTITEMS_P_H + +#include "qcommonvalues_p.h" +#include "qdynamiccontext_p.h" +#include "qitem_p.h" + +QT_BEGIN_NAMESPACE + +class QXmlResultItemsPrivate +{ +public: + inline QXmlResultItemsPrivate() : iterator(QPatternist::CommonValues::emptyIterator) + , hasError(false) + { + } + + void setDynamicContext(const QPatternist::DynamicContext::Ptr &context) + { + m_context = context; + } + + QPatternist::Item::Iterator::Ptr iterator; + QXmlItem current; + bool hasError; +private: + /** + * We never use it. We only keep a ref to it such that it doesn't get + * de-allocated. + */ + QPatternist::DynamicContext::Ptr m_context; +}; + +QT_END_NAMESPACE +#endif + diff --git a/src/xmlpatterns/api/qxmlschema.cpp b/src/xmlpatterns/api/qxmlschema.cpp new file mode 100644 index 0000000..ee92195 --- /dev/null +++ b/src/xmlpatterns/api/qxmlschema.cpp @@ -0,0 +1,304 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qxmlschema.h" +#include "qxmlschema_p.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +/*! + \class QXmlSchema + + \brief The QXmlSchema class provides loading and validation of a W3C XML Schema. + + \reentrant + \since 4.6 + \ingroup xml-tools + + The QXmlSchema class loads, compiles and validates W3C XML Schema files + that can be used further for validation of XML instance documents via + \l{QXmlSchemaValidator}. + + The following example shows how to load a XML Schema file from the network + and test whether it is a valid schema document: + + \snippet doc/src/snippets/qxmlschema/main.cpp 0 + + \section1 XML Schema Version + + This class is used to represent schemas that conform to the \l{XML Schema} 1.0 + specification. + + \sa QXmlSchemaValidator, {xmlpatterns/schema}{XML Schema Validation Example} +*/ + +/*! + Constructs an invalid, empty schema that cannot be used until + load() is called. + */ +QXmlSchema::QXmlSchema() + : d(new QXmlSchemaPrivate(QXmlNamePool())) +{ +} + +/*! + Constructs a QXmlSchema that is a copy of \a other. The new + instance will share resources with the existing schema + to the extent possible. + */ +QXmlSchema::QXmlSchema(const QXmlSchema &other) + : d(other.d) +{ +} + +/*! + Destroys this QXmlSchema. + */ +QXmlSchema::~QXmlSchema() +{ +} + +/*! + Sets this QXmlSchema to a schema loaded from the \a source + URI. + + If the schema \l {isValid()} {is invalid}, \c{false} is returned + and the behavior is undefined. + + Example: + + \snippet doc/src/snippets/qxmlschema/main.cpp 0 + + \sa isValid() + */ +bool QXmlSchema::load(const QUrl &source) +{ + d->load(source, QString()); + return d->isValid(); +} + +/*! + Sets this QXmlSchema to a schema read from the \a source + device. The device must have been opened with at least + QIODevice::ReadOnly. + + \a documentUri represents the schema obtained from the \a source + device. It is the base URI of the schema, that is used + internally to resolve relative URIs that appear in the schema, and + for message reporting. + + If \a source is \c null or not readable, or if \a documentUri is not + a valid URI, behavior is undefined. + + If the schema \l {isValid()} {is invalid}, \c{false} is returned + and the behavior is undefined. + + Example: + + \snippet doc/src/snippets/qxmlschema/main.cpp 1 + + \sa isValid() + */ +bool QXmlSchema::load(QIODevice *source, const QUrl &documentUri) +{ + d->load(source, documentUri, QString()); + return d->isValid(); +} + +/*! + Sets this QXmlSchema to a schema read from the \a data + + \a documentUri represents the schema obtained from the \a data. + It is the base URI of the schema, that is used internally to + resolve relative URIs that appear in the schema, and + for message reporting. + + If \a documentUri is not a valid URI, behavior is undefined. + \sa isValid() + + If the schema \l {isValid()} {is invalid}, \c{false} is returned + and the behavior is undefined. + + Example: + + \snippet doc/src/snippets/qxmlschema/main.cpp 2 + + \sa isValid() + */ +bool QXmlSchema::load(const QByteArray &data, const QUrl &documentUri) +{ + d->load(data, documentUri, QString()); + return d->isValid(); +} + +/*! + Returns true if this schema is valid. Examples of invalid schemas + are ones that contain syntax errors or that do not conform the + W3C XML Schema specification. + */ +bool QXmlSchema::isValid() const +{ + return d->isValid(); +} + +/*! + Returns the name pool used by this QXmlSchema for constructing \l + {QXmlName} {names}. There is no setter for the name pool, because + mixing name pools causes errors due to name confusion. + */ +QXmlNamePool QXmlSchema::namePool() const +{ + return d->namePool(); +} + +/*! + Returns the document URI of the schema or an empty URI if no + schema has been set. + */ +QUrl QXmlSchema::documentUri() const +{ + return d->documentUri(); +} + +/*! + Changes the \l {QAbstractMessageHandler}{message handler} for this + QXmlSchema to \a handler. The schema sends all compile and + validation messages to this message handler. QXmlSchema does not take + ownership of \a handler. + + Normally, the default message handler is sufficient. It writes + compile and validation messages to \e stderr. The default message + handler includes color codes if \e stderr can render colors. + + When QXmlSchema calls QAbstractMessageHandler::message(), + the arguments are as follows: + + \table + \header + \o message() argument + \o Semantics + \row + \o QtMsgType type + \o Only QtWarningMsg and QtFatalMsg are used. The former + identifies a warning, while the latter identifies an error. + \row + \o const QString & description + \o An XHTML document which is the actual message. It is translated + into the current language. + \row + \o const QUrl &identifier + \o Identifies the error with a URI, where the fragment is + the error code, and the rest of the URI is the error namespace. + \row + \o const QSourceLocation & sourceLocation + \o Identifies where the error occurred. + \endtable + + */ +void QXmlSchema::setMessageHandler(QAbstractMessageHandler *handler) +{ + d->setMessageHandler(handler); +} + +/*! + Returns the message handler that handles compile and validation + messages for this QXmlSchema. + */ +QAbstractMessageHandler *QXmlSchema::messageHandler() const +{ + return d->messageHandler(); +} + +/*! + Sets the URI resolver to \a resolver. QXmlSchema does not take + ownership of \a resolver. + + \sa uriResolver() + */ +void QXmlSchema::setUriResolver(const QAbstractUriResolver *resolver) +{ + d->setUriResolver(resolver); +} + +/*! + Returns the schema's URI resolver. If no URI resolver has been set, + QtXmlPatterns will use the URIs in schemas as they are. + + The URI resolver provides a level of abstraction, or \e{polymorphic + URIs}. A resolver can rewrite \e{logical} URIs to physical ones, or + it can translate obsolete or invalid URIs to valid ones. + + When QtXmlPatterns calls QAbstractUriResolver::resolve() the + absolute URI is the URI mandated by the schema specification, and the + relative URI is the URI specified by the user. + + \sa setUriResolver() + */ +const QAbstractUriResolver *QXmlSchema::uriResolver() const +{ + return d->uriResolver(); +} + +/*! + Sets the network manager to \a manager. + QXmlSchema does not take ownership of \a manager. + + \sa networkAccessManager() + */ +void QXmlSchema::setNetworkAccessManager(QNetworkAccessManager *manager) +{ + d->setNetworkAccessManager(manager); +} + +/*! + Returns the network manager, or 0 if it has not been set. + + \sa setNetworkAccessManager() + */ +QNetworkAccessManager *QXmlSchema::networkAccessManager() const +{ + return d->networkAccessManager(); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/api/qxmlschema.h b/src/xmlpatterns/api/qxmlschema.h new file mode 100644 index 0000000..145f2dc --- /dev/null +++ b/src/xmlpatterns/api/qxmlschema.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QXMLSCHEMA_H +#define QXMLSCHEMA_H + +#include +#include +#include + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +QT_MODULE(XmlPatterns) + +class QAbstractMessageHandler; +class QAbstractUriResolver; +class QIODevice; +class QNetworkAccessManager; +class QUrl; +class QXmlNamePool; +class QXmlSchemaPrivate; + +class Q_XMLPATTERNS_EXPORT QXmlSchema +{ + friend class QXmlSchemaValidatorPrivate; + + public: + QXmlSchema(); + QXmlSchema(const QXmlSchema &other); + ~QXmlSchema(); + + bool load(const QUrl &source); + bool load(QIODevice *source, const QUrl &documentUri = QUrl()); + bool load(const QByteArray &data, const QUrl &documentUri = QUrl()); + + bool isValid() const; + + QXmlNamePool namePool() const; + QUrl documentUri() const; + + void setMessageHandler(QAbstractMessageHandler *handler); + QAbstractMessageHandler *messageHandler() const; + + void setUriResolver(const QAbstractUriResolver *resolver); + const QAbstractUriResolver *uriResolver() const; + + void setNetworkAccessManager(QNetworkAccessManager *networkmanager); + QNetworkAccessManager *networkAccessManager() const; + + private: + QSharedDataPointer d; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qxmlschema_p.cpp b/src/xmlpatterns/api/qxmlschema_p.cpp new file mode 100644 index 0000000..f5ed5c0 --- /dev/null +++ b/src/xmlpatterns/api/qxmlschema_p.cpp @@ -0,0 +1,203 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qacceltreeresourceloader_p.h" +#include "qxmlschema.h" +#include "qxmlschema_p.h" + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +QXmlSchemaPrivate::QXmlSchemaPrivate(const QXmlNamePool &namePool) + : m_namePool(namePool) + , m_userMessageHandler(0) + , m_uriResolver(0) + , m_userNetworkAccessManager(0) + , m_schemaContext(new QPatternist::XsdSchemaContext(m_namePool.d)) + , m_schemaParserContext(new QPatternist::XsdSchemaParserContext(m_namePool.d, m_schemaContext)) + , m_schemaIsValid(false) +{ + m_networkAccessManager = new QPatternist::ReferenceCountedValue(new QNetworkAccessManager()); + m_messageHandler = new QPatternist::ReferenceCountedValue(new QPatternist::ColoringMessageHandler()); +} + +QXmlSchemaPrivate::QXmlSchemaPrivate(const QPatternist::XsdSchemaContext::Ptr &schemaContext) + : m_namePool(QXmlNamePool(schemaContext->namePool().data())) + , m_userMessageHandler(0) + , m_uriResolver(0) + , m_userNetworkAccessManager(0) + , m_schemaContext(schemaContext) + , m_schemaParserContext(new QPatternist::XsdSchemaParserContext(m_namePool.d, m_schemaContext)) + , m_schemaIsValid(false) +{ + m_networkAccessManager = new QPatternist::ReferenceCountedValue(new QNetworkAccessManager()); + m_messageHandler = new QPatternist::ReferenceCountedValue(new QPatternist::ColoringMessageHandler()); +} + +QXmlSchemaPrivate::QXmlSchemaPrivate(const QXmlSchemaPrivate &other) + : QSharedData(other) +{ + m_namePool = other.m_namePool; + m_userMessageHandler = other.m_userMessageHandler; + m_uriResolver = other.m_uriResolver; + m_userNetworkAccessManager = other.m_userNetworkAccessManager; + m_messageHandler = other.m_messageHandler; + m_networkAccessManager = other.m_networkAccessManager; + + m_schemaContext = other.m_schemaContext; + m_schemaParserContext = other.m_schemaParserContext; + m_schemaIsValid = other.m_schemaIsValid; + m_documentUri = other.m_documentUri; +} + +void QXmlSchemaPrivate::load(const QUrl &source, const QString &targetNamespace) +{ + m_documentUri = QPatternist::XPathHelper::normalizeQueryURI(source); + + m_schemaContext->setMessageHandler(messageHandler()); + m_schemaContext->setUriResolver(uriResolver()); + m_schemaContext->setNetworkAccessManager(networkAccessManager()); + + const QPatternist::AutoPtr reply(QPatternist::AccelTreeResourceLoader::load(source, m_schemaContext->networkAccessManager(), + m_schemaContext, QPatternist::AccelTreeResourceLoader::ContinueOnError)); + if (reply) + load(reply.data(), source, targetNamespace); +} + +void QXmlSchemaPrivate::load(const QByteArray &data, const QUrl &documentUri, const QString &targetNamespace) +{ + QByteArray localData(data); + + QBuffer buffer(&localData); + buffer.open(QIODevice::ReadOnly); + + load(&buffer, documentUri, targetNamespace); +} + +void QXmlSchemaPrivate::load(QIODevice *source, const QUrl &documentUri, const QString &targetNamespace) +{ + m_schemaParserContext = QPatternist::XsdSchemaParserContext::Ptr(new QPatternist::XsdSchemaParserContext(m_namePool.d, m_schemaContext)); + m_schemaIsValid = false; + + if (!source) { + qWarning("A null QIODevice pointer cannot be passed."); + return; + } + + if (!source->isReadable()) { + qWarning("The device must be readable."); + return; + } + + m_documentUri = QPatternist::XPathHelper::normalizeQueryURI(documentUri); + m_schemaContext->setMessageHandler(messageHandler()); + m_schemaContext->setUriResolver(uriResolver()); + m_schemaContext->setNetworkAccessManager(networkAccessManager()); + + QPatternist::XsdSchemaParser parser(m_schemaContext, m_schemaParserContext, source); + parser.setDocumentURI(documentUri); + parser.setTargetNamespace(targetNamespace); + + try { + parser.parse(); + m_schemaParserContext->resolver()->resolve(); + + m_schemaIsValid = true; + } catch (QPatternist::Exception exception) { + m_schemaIsValid = false; + } +} + +bool QXmlSchemaPrivate::isValid() const +{ + return m_schemaIsValid; +} + +QXmlNamePool QXmlSchemaPrivate::namePool() const +{ + return m_namePool; +} + +QUrl QXmlSchemaPrivate::documentUri() const +{ + return m_documentUri; +} + +void QXmlSchemaPrivate::setMessageHandler(QAbstractMessageHandler *handler) +{ + m_userMessageHandler = handler; +} + +QAbstractMessageHandler *QXmlSchemaPrivate::messageHandler() const +{ + if (m_userMessageHandler) + return m_userMessageHandler; + + return m_messageHandler.data()->value; +} + +void QXmlSchemaPrivate::setUriResolver(const QAbstractUriResolver *resolver) +{ + m_uriResolver = resolver; +} + +const QAbstractUriResolver *QXmlSchemaPrivate::uriResolver() const +{ + return m_uriResolver; +} + +void QXmlSchemaPrivate::setNetworkAccessManager(QNetworkAccessManager *networkmanager) +{ + m_userNetworkAccessManager = networkmanager; +} + +QNetworkAccessManager *QXmlSchemaPrivate::networkAccessManager() const +{ + if (m_userNetworkAccessManager) + return m_userNetworkAccessManager; + + return m_networkAccessManager.data()->value; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/api/qxmlschema_p.h b/src/xmlpatterns/api/qxmlschema_p.h new file mode 100644 index 0000000..2376fe3 --- /dev/null +++ b/src/xmlpatterns/api/qxmlschema_p.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QXMLSCHEMA_P_H +#define QXMLSCHEMA_P_H + +#include "qabstractmessagehandler.h" +#include "qabstracturiresolver.h" +#include "qautoptr_p.h" +#include "qcoloringmessagehandler_p.h" +#include "qreferencecountedvalue_p.h" + +#include "qxsdschemacontext_p.h" +#include "qxsdschemaparser_p.h" +#include "qxsdschemaparsercontext_p.h" + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QXmlSchemaPrivate : public QSharedData +{ + public: + QXmlSchemaPrivate(const QXmlNamePool &namePool); + QXmlSchemaPrivate(const QPatternist::XsdSchemaContext::Ptr &schemaContext); + QXmlSchemaPrivate(const QXmlSchemaPrivate &other); + + void load(const QUrl &source, const QString &targetNamespace); + void load(QIODevice *source, const QUrl &documentUri, const QString &targetNamespace); + void load(const QByteArray &data, const QUrl &documentUri, const QString &targetNamespace); + bool isValid() const; + QXmlNamePool namePool() const; + QUrl documentUri() const; + void setMessageHandler(QAbstractMessageHandler *handler); + QAbstractMessageHandler *messageHandler() const; + void setUriResolver(const QAbstractUriResolver *resolver); + const QAbstractUriResolver *uriResolver() const; + void setNetworkAccessManager(QNetworkAccessManager *networkmanager); + QNetworkAccessManager *networkAccessManager() const; + + QXmlNamePool m_namePool; + QAbstractMessageHandler* m_userMessageHandler; + const QAbstractUriResolver* m_uriResolver; + QNetworkAccessManager* m_userNetworkAccessManager; + QPatternist::ReferenceCountedValue::Ptr m_messageHandler; + QPatternist::ReferenceCountedValue::Ptr m_networkAccessManager; + + QPatternist::XsdSchemaContext::Ptr m_schemaContext; + QPatternist::XsdSchemaParserContext::Ptr m_schemaParserContext; + bool m_schemaIsValid; + QUrl m_documentUri; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qxmlschemavalidator.cpp b/src/xmlpatterns/api/qxmlschemavalidator.cpp new file mode 100644 index 0000000..682d34f --- /dev/null +++ b/src/xmlpatterns/api/qxmlschemavalidator.cpp @@ -0,0 +1,349 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qxmlschemavalidator.h" +#include "qxmlschemavalidator_p.h" + +#include "qacceltreeresourceloader_p.h" +#include "qxmlschema.h" +#include "qxmlschema_p.h" +#include "qxsdvalidatinginstancereader_p.h" + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +/*! + \class QXmlSchemaValidator + + \brief The QXmlSchemaValidator class validates XML instance documents against a W3C XML Schema. + + \reentrant + \since 4.6 + \ingroup xml-tools + + The QXmlSchemaValidator class loads, parses an XML instance document and validates it + against a W3C XML Schema that has been compiled with \l{QXmlSchema}. + + The following example shows how to load a XML Schema from a local + file, check whether it is a valid schema document and use it for validation + of an XML instance document: + + \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 3 + + \section1 XML Schema Version + + This class implements schema validation according to the \l{XML Schema} 1.0 + specification. + + \sa QXmlSchema, {xmlpatterns/schema}{XML Schema Validation Example} +*/ + +/*! + Constructs a schema validator. + The schema used for validation must be referenced in the XML instance document + via the \c xsi:schemaLocation or \c xsi:noNamespaceSchemaLocation attribute. + */ +QXmlSchemaValidator::QXmlSchemaValidator() + : d(new QXmlSchemaValidatorPrivate(QXmlSchema())) +{ +} + +/*! + Constructs a schema validator that will use \a schema for validation. + If an empty \l {QXmlSchema} schema is passed to the validator, the schema used + for validation must be referenced in the XML instance document + via the \c xsi:schemaLocation or \c xsi:noNamespaceSchemaLocation attribute. + */ +QXmlSchemaValidator::QXmlSchemaValidator(const QXmlSchema &schema) + : d(new QXmlSchemaValidatorPrivate(schema)) +{ +} + +/*! + Destroys this QXmlSchemaValidator. + */ +QXmlSchemaValidator::~QXmlSchemaValidator() +{ + delete d; +} + +/*! + Sets the \a schema that shall be used for further validation. + If the schema is empty, the schema used for validation must be referenced + in the XML instance document via the \c xsi:schemaLocation or + \c xsi:noNamespaceSchemaLocation attribute. + */ +void QXmlSchemaValidator::setSchema(const QXmlSchema &schema) +{ + d->setSchema(schema); +} + +/*! + Validates the XML instance document read from \a data with the + given \a documentUri against the schema. + + Returns \c true if the XML instance document is valid according to the + schema, \c false otherwise. + + Example: + + \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 2 + */ +bool QXmlSchemaValidator::validate(const QByteArray &data, const QUrl &documentUri) const +{ + QByteArray localData(data); + + QBuffer buffer(&localData); + buffer.open(QIODevice::ReadOnly); + + return validate(&buffer, documentUri); +} + +/*! + Validates the XML instance document read from \a source against the schema. + + Returns \c true if the XML instance document is valid according to the + schema, \c false otherwise. + + Example: + + \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 0 + */ +bool QXmlSchemaValidator::validate(const QUrl &source) const +{ + d->m_context->setMessageHandler(messageHandler()); + d->m_context->setUriResolver(uriResolver()); + d->m_context->setNetworkAccessManager(networkAccessManager()); + + const QPatternist::AutoPtr reply(QPatternist::AccelTreeResourceLoader::load(source, d->m_context->networkAccessManager(), + d->m_context, QPatternist::AccelTreeResourceLoader::ContinueOnError)); + if (reply) + return validate(reply.data(), source); + else + return false; +} + +/*! + Validates the XML instance document read from \a source with the + given \a documentUri against the schema. + + Returns \c true if the XML instance document is valid according to the + schema, \c false otherwise. + + Example: + + \snippet doc/src/snippets/qxmlschemavalidator/main.cpp 1 + */ +bool QXmlSchemaValidator::validate(QIODevice *source, const QUrl &documentUri) const +{ + if (!source) { + qWarning("A null QIODevice pointer cannot be passed."); + return false; + } + + if (!source->isReadable()) { + qWarning("The device must be readable."); + return false; + } + + const QUrl normalizedUri = QPatternist::XPathHelper::normalizeQueryURI(documentUri); + + d->m_context->setMessageHandler(messageHandler()); + d->m_context->setUriResolver(uriResolver()); + d->m_context->setNetworkAccessManager(networkAccessManager()); + + QPatternist::NetworkAccessDelegator::Ptr delegator(new QPatternist::NetworkAccessDelegator(d->m_context->networkAccessManager(), + d->m_context->networkAccessManager())); + + QPatternist::AccelTreeResourceLoader loader(d->m_context->namePool(), delegator, QPatternist::AccelTreeBuilder::SourceLocationsFeature); + + QPatternist::Item item; + try { + item = loader.openDocument(source, normalizedUri, d->m_context); + } catch (QPatternist::Exception exception) { + return false; + } + + QXmlNodeModelIndex index = item.asNode(); + const QAbstractXmlNodeModel *model = item.asNode().model(); + + QPatternist::XsdValidatedXmlNodeModel *validatedModel = new QPatternist::XsdValidatedXmlNodeModel(model); + + QPatternist::XsdValidatingInstanceReader reader(validatedModel, normalizedUri, d->m_context); + if (d->m_schema) + reader.addSchema(d->m_schema, d->m_schemaDocumentUri); + try { + reader.read(); + } catch (QPatternist::Exception exception) { + return false; + } + + return true; +} + +/*! + Returns the name pool used by this QXmlSchemaValidator for constructing \l + {QXmlName} {names}. There is no setter for the name pool, because + mixing name pools causes errors due to name confusion. + */ +QXmlNamePool QXmlSchemaValidator::namePool() const +{ + return d->m_namePool; +} + +/*! + Returns the schema that is used for validation. + */ +QXmlSchema QXmlSchemaValidator::schema() const +{ + return d->m_originalSchema; +} + +/*! + Changes the \l {QAbstractMessageHandler}{message handler} for this + QXmlSchemaValidator to \a handler. The schema validator sends all parsing and + validation messages to this message handler. QXmlSchemaValidator does not take + ownership of \a handler. + + Normally, the default message handler is sufficient. It writes + compile and validation messages to \e stderr. The default message + handler includes color codes if \e stderr can render colors. + + When QXmlSchemaValidator calls QAbstractMessageHandler::message(), + the arguments are as follows: + + \table + \header + \o message() argument + \o Semantics + \row + \o QtMsgType type + \o Only QtWarningMsg and QtFatalMsg are used. The former + identifies a warning, while the latter identifies an error. + \row + \o const QString & description + \o An XHTML document which is the actual message. It is translated + into the current language. + \row + \o const QUrl &identifier + \o Identifies the error with a URI, where the fragment is + the error code, and the rest of the URI is the error namespace. + \row + \o const QSourceLocation & sourceLocation + \o Identifies where the error occurred. + \endtable + + */ +void QXmlSchemaValidator::setMessageHandler(QAbstractMessageHandler *handler) +{ + d->m_userMessageHandler = handler; +} + +/*! + Returns the message handler that handles parsing and validation + messages for this QXmlSchemaValidator. + */ +QAbstractMessageHandler *QXmlSchemaValidator::messageHandler() const +{ + if (d->m_userMessageHandler) + return d->m_userMessageHandler; + + return d->m_messageHandler.data()->value; +} + +/*! + Sets the URI resolver to \a resolver. QXmlSchemaValidator does not take + ownership of \a resolver. + + \sa uriResolver() + */ +void QXmlSchemaValidator::setUriResolver(const QAbstractUriResolver *resolver) +{ + d->m_uriResolver = resolver; +} + +/*! + Returns the schema's URI resolver. If no URI resolver has been set, + QtXmlPatterns will use the URIs in instance documents as they are. + + The URI resolver provides a level of abstraction, or \e{polymorphic + URIs}. A resolver can rewrite \e{logical} URIs to physical ones, or + it can translate obsolete or invalid URIs to valid ones. + + When QtXmlPatterns calls QAbstractUriResolver::resolve() the + absolute URI is the URI mandated by the schema specification, and the + relative URI is the URI specified by the user. + + \sa setUriResolver() + */ +const QAbstractUriResolver *QXmlSchemaValidator::uriResolver() const +{ + return d->m_uriResolver; +} + +/*! + Sets the network manager to \a manager. + QXmlSchemaValidator does not take ownership of \a manager. + + \sa networkAccessManager() + */ +void QXmlSchemaValidator::setNetworkAccessManager(QNetworkAccessManager *manager) +{ + d->m_userNetworkAccessManager = manager; +} + +/*! + Returns the network manager, or 0 if it has not been set. + + \sa setNetworkAccessManager() + */ +QNetworkAccessManager *QXmlSchemaValidator::networkAccessManager() const +{ + if (d->m_userNetworkAccessManager) + return d->m_userNetworkAccessManager; + + return d->m_networkAccessManager.data()->value; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/api/qxmlschemavalidator.h b/src/xmlpatterns/api/qxmlschemavalidator.h new file mode 100644 index 0000000..7121d19 --- /dev/null +++ b/src/xmlpatterns/api/qxmlschemavalidator.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QXMLSCHEMAVALIDATOR_H +#define QXMLSCHEMAVALIDATOR_H + +#include +#include + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +QT_MODULE(XmlPatterns) + +class QAbstractMessageHandler; +class QAbstractUriResolver; +class QIODevice; +class QNetworkAccessManager; +class QUrl; +class QXmlNamePool; +class QXmlSchema; +class QXmlSchemaValidatorPrivate; + +class Q_XMLPATTERNS_EXPORT QXmlSchemaValidator +{ + public: + QXmlSchemaValidator(); + QXmlSchemaValidator(const QXmlSchema &schema); + ~QXmlSchemaValidator(); + + void setSchema(const QXmlSchema &schema); + + bool validate(const QUrl &source) const; + bool validate(QIODevice *source, const QUrl &documentUri = QUrl()) const; + bool validate(const QByteArray &data, const QUrl &documentUri = QUrl()) const; + + QXmlNamePool namePool() const; + QXmlSchema schema() const; + + void setMessageHandler(QAbstractMessageHandler *handler); + QAbstractMessageHandler *messageHandler() const; + + void setUriResolver(const QAbstractUriResolver *resolver); + const QAbstractUriResolver *uriResolver() const; + + void setNetworkAccessManager(QNetworkAccessManager *networkmanager); + QNetworkAccessManager *networkAccessManager() const; + + private: + QXmlSchemaValidatorPrivate* const d; + + Q_DISABLE_COPY(QXmlSchemaValidator) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qxmlschemavalidator_p.h b/src/xmlpatterns/api/qxmlschemavalidator_p.h new file mode 100644 index 0000000..fb9492a --- /dev/null +++ b/src/xmlpatterns/api/qxmlschemavalidator_p.h @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QXMLSCHEMAVALIDATOR_P_H +#define QXMLSCHEMAVALIDATOR_P_H + +#include "qabstractmessagehandler.h" +#include "qabstracturiresolver.h" +#include "qautoptr_p.h" +#include "qcoloringmessagehandler_p.h" +#include "qxmlschema.h" +#include "qxmlschema_p.h" + +#include "qxsdschemacontext_p.h" +#include "qxsdschema_p.h" + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QXmlSchemaValidatorPrivate +{ +public: + QXmlSchemaValidatorPrivate(const QXmlSchema &schema) + : m_namePool(schema.namePool()) + , m_userMessageHandler(0) + , m_uriResolver(0) + , m_userNetworkAccessManager(0) + { + setSchema(schema); + + const QXmlSchemaPrivate *p = schema.d; + + // initialize the environment properties with the ones from the schema + + if (p->m_userNetworkAccessManager) // schema has user defined network access manager + m_userNetworkAccessManager = p->m_userNetworkAccessManager; + else + m_networkAccessManager = p->m_networkAccessManager; + + if (p->m_userMessageHandler) // schema has user defined message handler + m_userMessageHandler = p->m_userMessageHandler; + else + m_messageHandler = p->m_messageHandler; + + m_uriResolver = p->m_uriResolver; + } + + void setSchema(const QXmlSchema &schema) + { + // use same name pool as the schema + m_namePool = schema.namePool(); + m_schema = schema.d->m_schemaParserContext->schema(); + m_schemaDocumentUri = schema.documentUri(); + + // create a new schema context + m_context = QPatternist::XsdSchemaContext::Ptr(new QPatternist::XsdSchemaContext(m_namePool.d)); + m_context->m_schemaTypeFactory = schema.d->m_schemaContext->m_schemaTypeFactory; + m_context->m_builtinTypesFacetList = schema.d->m_schemaContext->m_builtinTypesFacetList; + + m_originalSchema = schema; + } + + QXmlNamePool m_namePool; + QAbstractMessageHandler* m_userMessageHandler; + const QAbstractUriResolver* m_uriResolver; + QNetworkAccessManager* m_userNetworkAccessManager; + QPatternist::ReferenceCountedValue::Ptr m_messageHandler; + QPatternist::ReferenceCountedValue::Ptr m_networkAccessManager; + + QXmlSchema m_originalSchema; + QPatternist::XsdSchemaContext::Ptr m_context; + QPatternist::XsdSchema::Ptr m_schema; + QUrl m_schemaDocumentUri; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qxmlserializer.cpp b/src/xmlpatterns/api/qxmlserializer.cpp new file mode 100644 index 0000000..5849e16 --- /dev/null +++ b/src/xmlpatterns/api/qxmlserializer.cpp @@ -0,0 +1,653 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdynamiccontext_p.h" +#include "qpatternistlocale_p.h" +#include "qitem_p.h" +#include "qxmlquery_p.h" +#include "qxmlserializer_p.h" +#include "qxmlserializer.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +QXmlSerializerPrivate::QXmlSerializerPrivate(const QXmlQuery &query, + QIODevice *outputDevice) + : isPreviousAtomic(false), + state(QXmlSerializer::BeforeDocumentElement), + np(query.namePool().d), + device(outputDevice), + codec(QTextCodec::codecForMib(106)), /* UTF-8 */ + query(query) +{ + hasClosedElement.reserve(EstimatedTreeDepth); + namespaces.reserve(EstimatedTreeDepth); + nameCache.reserve(EstimatedNameCount); + + hasClosedElement.push(qMakePair(QXmlName(), true)); + + /* + We push the empty namespace such that first of all + namespaceBinding() won't assert on an empty QStack, + and such that the empty namespace is in-scope and + that the code doesn't attempt to declare it. + + We push the XML namespace. Although we won't receive + declarations for it, we may output attributes by that + name. + */ + QVector defNss; + defNss.resize(2); + defNss[0] = QXmlName(StandardNamespaces::empty, + StandardLocalNames::empty, + StandardPrefixes::empty); + defNss[1] = QXmlName(StandardNamespaces::xml, + StandardLocalNames::empty, + StandardPrefixes::xml); + + namespaces.push(defNss); + + /* If we don't set this flag, QTextCodec will generate a BOM. */ + converterState.flags = QTextCodec::IgnoreHeader; +} + +/*! + \class QXmlSerializer + \brief The QXmlSerializer class is an implementation of QAbstractXmlReceiver for transforming XQuery output into unformatted XML. + + \reentrant + \since 4.4 + \ingroup xml-tools + + QXmlSerializer translates an \l {XQuery Sequence} {XQuery sequence}, usually + the output of an QXmlQuery, into XML. Consider the example: + + \snippet doc/src/snippets/code/src_xmlpatterns_api_qxmlserializer.cpp 0 + + First it constructs a \l {QXmlQuery} {query} that gets the + first paragraph from document \c index.html. Then it constructs + an instance of this class with the \l {QXmlQuery} {query} and + \l {QIODevice} {myOutputDevice}. Finally, it + \l {QXmlQuery::evaluateTo()} {evaluates} the + \l {QXmlQuery} {query}, producing an ordered sequence of calls + to the serializer's callback functions. The sequence of callbacks + transforms the query output to XML and writes it to + \l {QIODevice} {myOutputDevice}. + + QXmlSerializer will: + + \list + \o Declare namespaces when needed, + + \o Use appropriate escaping, when characters can't be + represented in the XML, + + \o Handle line endings appropriately, + + \o Report errors, when it can't serialize the content, e.g., + when asked to serialize an attribute that is a top-level node, + or when more than one top-level element is encountered. + + \endlist + + If an error occurs during serialization, result is undefined + unless the serializer is driven through a call to + QXmlQuery::evaluateTo(). + + If the generated XML should be indented and formatted for reading, + use QXmlFormatter. + + \sa {http://www.w3.org/TR/xslt-xquery-serialization/}{XSLT 2.0 and XQuery 1.0 Serialization} + + \sa QXmlFormatter + */ + +/*! + Constructs a serializer that uses the name pool and message + handler in \a query, and writes the output to \a outputDevice. + + \a outputDevice must be a valid, non-null device that is open in + write mode, otherwise behavior is undefined. + + \a outputDevice must not be opened with QIODevice::Text because it + will cause the output to be incorrect. This class will ensure line + endings are serialized as according with the XML specification. + QXmlSerializer does not take ownership of \a outputDevice. + */ +QXmlSerializer::QXmlSerializer(const QXmlQuery &query, + QIODevice *outputDevice) : QAbstractXmlReceiver(new QXmlSerializerPrivate(query, outputDevice)) +{ + if(!outputDevice) + { + qWarning("outputDevice cannot be null."); + return; + } + + if(!outputDevice->isWritable()) + { + qWarning("outputDevice must be opened in write mode."); + return; + } +} + +/*! + \internal + */ +QXmlSerializer::QXmlSerializer(QAbstractXmlReceiverPrivate *d) : QAbstractXmlReceiver(d) +{ +} + +/*! + \internal + */ +bool QXmlSerializer::atDocumentRoot() const +{ + Q_D(const QXmlSerializer); + return d->state == BeforeDocumentElement || + (d->state == InsideDocumentElement && d->hasClosedElement.size() == 1); +} + +/*! + \internal + */ +void QXmlSerializer::startContent() +{ + Q_D(QXmlSerializer); + if (!d->hasClosedElement.top().second) { + d->write('>'); + d->hasClosedElement.top().second = true; + } +} + +/*! + \internal + */ +void QXmlSerializer::writeEscaped(const QString &toEscape) +{ + if(toEscape.isEmpty()) /* Early exit. */ + return; + + QString result; + result.reserve(int(toEscape.length() * 1.1)); + const int length = toEscape.length(); + + for(int i = 0; i < length; ++i) + { + const QChar c(toEscape.at(i)); + + if(c == QLatin1Char('<')) + result += QLatin1String("<"); + else if(c == QLatin1Char('>')) + result += QLatin1String(">"); + else if(c == QLatin1Char('&')) + result += QLatin1String("&"); + else + result += toEscape.at(i); + } + + write(result); +} + +/*! + \internal + */ +void QXmlSerializer::writeEscapedAttribute(const QString &toEscape) +{ + if(toEscape.isEmpty()) /* Early exit. */ + return; + + QString result; + result.reserve(int(toEscape.length() * 1.1)); + const int length = toEscape.length(); + + for(int i = 0; i < length; ++i) + { + const QChar c(toEscape.at(i)); + + if(c == QLatin1Char('<')) + result += QLatin1String("<"); + else if(c == QLatin1Char('>')) + result += QLatin1String(">"); + else if(c == QLatin1Char('&')) + result += QLatin1String("&"); + else if(c == QLatin1Char('"')) + result += QLatin1String("""); + else + result += toEscape.at(i); + } + + write(result); +} + +/*! + \internal + */ +void QXmlSerializer::write(const QString &content) +{ + Q_D(QXmlSerializer); + d->device->write(d->codec->fromUnicode(content.constData(), content.length(), &d->converterState)); +} + +/*! + \internal + */ +void QXmlSerializer::write(const QXmlName &name) +{ + Q_D(QXmlSerializer); + const QByteArray &cell = d->nameCache[name.code()]; + + if(cell.isNull()) + { + QByteArray &mutableCell = d->nameCache[name.code()]; + + const QString content(d->np->toLexical(name)); + mutableCell = d->codec->fromUnicode(content.constData(), + content.length(), + &d->converterState); + d->device->write(mutableCell); + } + else + d->device->write(cell); +} + +/*! + \internal + */ +void QXmlSerializer::write(const char *const chars) +{ + Q_D(QXmlSerializer); + d->device->write(chars); +} + +/*! + \reimp + */ +void QXmlSerializer::startElement(const QXmlName &name) +{ + Q_D(QXmlSerializer); + Q_ASSERT(d->device); + Q_ASSERT(d->device->isWritable()); + Q_ASSERT(d->codec); + Q_ASSERT(!name.isNull()); + + d->namespaces.push(QVector()); + + if(atDocumentRoot()) + { + if(d->state == BeforeDocumentElement) + d->state = InsideDocumentElement; + else if(d->state != InsideDocumentElement) + { + d->query.d->staticContext()->error(QtXmlPatterns::tr( + "Element %1 can't be serialized because it appears outside " + "the document element.").arg(formatKeyword(d->np, name)), + ReportContext::SENR0001, + d->query.d->expression().data()); + } + } + + startContent(); + d->write('<'); + write(name); + + /* Ensure that the namespace URI used in the name gets outputted. */ + namespaceBinding(name); + + d->hasClosedElement.push(qMakePair(name, false)); + d->isPreviousAtomic = false; +} + +/*! + \reimp + */ +void QXmlSerializer::endElement() +{ + Q_D(QXmlSerializer); + const QPair e(d->hasClosedElement.pop()); + d->namespaces.pop(); + + if(e.second) + { + write("write('>'); + } + else + write("/>"); + + d->isPreviousAtomic = false; +} + +/*! + \reimp + */ +void QXmlSerializer::attribute(const QXmlName &name, + const QStringRef &value) +{ + Q_D(QXmlSerializer); + Q_ASSERT(!name.isNull()); + + /* Ensure that the namespace URI used in the name gets outputted. */ + { + /* Since attributes doesn't pick up the default namespace, a + * namespace declaration would cause trouble if we output it. */ + if(name.prefix() != StandardPrefixes::empty) + namespaceBinding(name); + } + + if(atDocumentRoot()) + { + Q_UNUSED(d); + d->query.d->staticContext()->error(QtXmlPatterns::tr( + "Attribute %1 can't be serialized because it appears at " + "the top level.").arg(formatKeyword(d->np, name)), + ReportContext::SENR0001, + d->query.d->expression().data()); + } + else + { + d->write(' '); + write(name); + write("=\""); + writeEscapedAttribute(value.toString()); + d->write('"'); + } +} + +/*! + \internal + */ +bool QXmlSerializer::isBindingInScope(const QXmlName nb) const +{ + Q_D(const QXmlSerializer); + const int levelLen = d->namespaces.size(); + + if(nb.prefix() == StandardPrefixes::empty) + { + for(int lvl = levelLen - 1; lvl >= 0; --lvl) + { + const QVector &scope = d->namespaces.at(lvl); + const int vectorLen = scope.size(); + + for(int s = vectorLen - 1; s >= 0; --s) + { + const QXmlName &nsb = scope.at(s); + + if(nsb.prefix() == StandardPrefixes::empty) + return nsb.namespaceURI() == nb.namespaceURI(); + } + } + } + else + { + for(int lvl = 0; lvl < levelLen; ++lvl) + { + const QVector &scope = d->namespaces.at(lvl); + const int vectorLen = scope.size(); + + for(int s = 0; s < vectorLen; ++s) + { + const QXmlName &n = scope.at(s); + if (n.prefix() == nb.prefix() && + n.namespaceURI() == nb.namespaceURI()) + return true; + } + } + } + + return false; +} + +/*! + \reimp + */ +void QXmlSerializer::namespaceBinding(const QXmlName &nb) +{ + /* + * Writes out \a nb. + * + * Namespace bindings aren't looked up in a cache, because + * we typically receive very few. + */ + + Q_D(QXmlSerializer); + Q_ASSERT_X(!nb.isNull(), Q_FUNC_INFO, + "It makes no sense to pass a null QXmlName."); + + Q_ASSERT_X((nb.namespaceURI() != StandardNamespaces::empty) || + (nb.prefix() == StandardPrefixes::empty), + Q_FUNC_INFO, + "Undeclarations of prefixes aren't allowed in XML 1.0 " + "and aren't supposed to be received."); + + if(nb.namespaceURI() == QPatternist::StandardNamespaces::StopNamespaceInheritance) + return; + + if(isBindingInScope(nb)) + return; + + d->namespaces.top().append(nb); + + if(nb.prefix() == StandardPrefixes::empty) + write(" xmlns"); + else + { + write(" xmlns:"); + write(d->np->stringForPrefix(nb.prefix())); + } + + write("=\""); + writeEscapedAttribute(d->np->stringForNamespace(nb.namespaceURI())); + d->write('"'); +} + +/*! + \reimp + */ +void QXmlSerializer::comment(const QString &value) +{ + Q_D(QXmlSerializer); + Q_ASSERT_X(!value.contains(QLatin1String("--")), + Q_FUNC_INFO, + "Invalid input; it's the caller's responsibility to ensure " + "the input is correct."); + + startContent(); + write(""); + d->isPreviousAtomic = false; +} + +/*! + \reimp + */ +void QXmlSerializer::characters(const QStringRef &value) +{ + Q_D(QXmlSerializer); + d->isPreviousAtomic = false; + startContent(); + writeEscaped(value.toString()); +} + +/*! + \reimp + */ +void QXmlSerializer::processingInstruction(const QXmlName &name, + const QString &value) +{ + Q_D(QXmlSerializer); + Q_ASSERT_X(!value.contains(QLatin1String("?>")), + Q_FUNC_INFO, + "Invalid input; it's the caller's responsibility to ensure " + "the input is correct."); + + startContent(); + write("write(' '); + write(value); + write("?>"); + + d->isPreviousAtomic = false; +} + +/*! + \internal + */ +void QXmlSerializer::item(const QPatternist::Item &outputItem) +{ + Q_D(QXmlSerializer); + + if(outputItem.isAtomicValue()) + { + if(d->isPreviousAtomic) + { + startContent(); + d->write(' '); + writeEscaped(outputItem.stringValue()); + } + else + { + d->isPreviousAtomic = true; + const QString value(outputItem.stringValue()); + + if(!value.isEmpty()) + { + startContent(); + writeEscaped(value); + } + } + } + else + { + startContent(); + Q_ASSERT(outputItem.isNode()); + sendAsNode(outputItem); + } +} + +/*! + \reimp + */ +void QXmlSerializer::atomicValue(const QVariant &value) +{ + Q_UNUSED(value); +} + +/*! + \reimp + */ +void QXmlSerializer::startDocument() +{ + Q_D(QXmlSerializer); + d->isPreviousAtomic = false; +} + +/*! + \reimp + */ +void QXmlSerializer::endDocument() +{ + Q_D(QXmlSerializer); + d->isPreviousAtomic = false; +} + +/*! + + Returns a pointer to the output device. There is no corresponding + function to \e set the output device, because the output device must + be passed to the constructor. The serializer does not take ownership + of its IO device. + */ +QIODevice *QXmlSerializer::outputDevice() const +{ + Q_D(const QXmlSerializer); + return d->device; +} + +/*! + Sets the codec the serializer will use for encoding its XML output. + The output codec is set to \a outputCodec. By default, the output + codec is set to the one for \c UTF-8. The serializer does not take + ownership of the codec. + + \sa codec() + + */ +void QXmlSerializer::setCodec(const QTextCodec *outputCodec) +{ + Q_D(QXmlSerializer); + d->codec = outputCodec; +} + +/*! + Returns the codec being used by the serializer for encoding its + XML output. + + \sa setCodec() + */ +const QTextCodec *QXmlSerializer::codec() const +{ + Q_D(const QXmlSerializer); + return d->codec; +} + +/*! + \reimp + */ +void QXmlSerializer::startOfSequence() +{ +} + +/*! + \reimp + */ +void QXmlSerializer::endOfSequence() +{ + /* If this function is changed to flush or close or something like that, + * take into consideration QXmlFormatter, especially + * QXmlFormatter::endOfSequence(). + */ +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/api/qxmlserializer.h b/src/xmlpatterns/api/qxmlserializer.h new file mode 100644 index 0000000..ae0a69e --- /dev/null +++ b/src/xmlpatterns/api/qxmlserializer.h @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QXMLSERIALIZER_H +#define QXMLSERIALIZER_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(XmlPatterns) + +class QIODevice; +class QTextCodec; +class QXmlQuery; +class QXmlSerializerPrivate; + +class Q_XMLPATTERNS_EXPORT QXmlSerializer : public QAbstractXmlReceiver +{ +public: + QXmlSerializer(const QXmlQuery &query, + QIODevice *outputDevice); + + virtual void namespaceBinding(const QXmlName &nb); + + virtual void characters(const QStringRef &value); + virtual void comment(const QString &value); + + virtual void startElement(const QXmlName &name); + + virtual void endElement(); + + virtual void attribute(const QXmlName &name, + const QStringRef &value); + + virtual void processingInstruction(const QXmlName &name, + const QString &value); + + virtual void atomicValue(const QVariant &value); + + virtual void startDocument(); + virtual void endDocument(); + virtual void startOfSequence(); + virtual void endOfSequence(); + + QIODevice *outputDevice() const; + + void setCodec(const QTextCodec *codec); + const QTextCodec *codec() const; + + /* The members below are internal, not part of the public API, and + * unsupported. Using them leads to undefined behavior. */ + virtual void item(const QPatternist::Item &item); +protected: + QXmlSerializer(QAbstractXmlReceiverPrivate *d); + +private: + inline bool isBindingInScope(const QXmlName nb) const; + + /** + * Where in the document the QXmlSerializer is currently working. + */ + enum State + { + /** + * Before the document element. This is the XML prolog where the + * XML declaration, and possibly comments and processing + * instructions are found. + */ + BeforeDocumentElement, + + /** + * This is inside the document element, at any level. + */ + InsideDocumentElement + }; + + /** + * If the current state is neither BeforeDocumentElement or + * AfterDocumentElement. + */ + inline bool atDocumentRoot() const; + + /** + * Closes any open element start tag. Must be called before outputting + * any element content. + */ + inline void startContent(); + + /** + * Escapes content intended as text nodes for elements. + */ + void writeEscaped(const QString &toEscape); + + /** + * Identical to writeEscaped(), but also escapes quotes. + */ + inline void writeEscapedAttribute(const QString &toEscape); + + /** + * Writes out @p name. + */ + inline void write(const QXmlName &name); + + inline void write(const char *const chars); + /** + * Encodes and writes out @p content. + */ + inline void write(const QString &content); + + Q_DECLARE_PRIVATE(QXmlSerializer) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/api/qxmlserializer_p.h b/src/xmlpatterns/api/qxmlserializer_p.h new file mode 100644 index 0000000..8aa525d --- /dev/null +++ b/src/xmlpatterns/api/qxmlserializer_p.h @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef QXMLSERIALIZER_P_H +#define QXMLSERIALIZER_P_H + +#include +#include +#include +#include +#include +#include + +#include "qnamepool_p.h" +#include "qabstractxmlreceiver_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QXmlSerializerPrivate : public QAbstractXmlReceiverPrivate +{ +public: + QXmlSerializerPrivate(const QXmlQuery &q, + QIODevice *outputDevice); + + QStack > hasClosedElement; + bool isPreviousAtomic; + QXmlSerializer::State state; + const QPatternist::NamePool::Ptr np; + + /** + * This member worries me a bit. We never use it but nevertheless + * it is pushed and pops linear to startElement() and endElement(). + * An optimization would be to at least merge it with hasClosedElement, + * but even better to push it on demand. That is, namespaceBinding() + * pushes it up to the tree depth first when it is needed. + */ + QStack > namespaces; + + QIODevice * device; + const QTextCodec * codec; + QTextCodec::ConverterState converterState; + /** + * Name cache. Since encoding QStrings are rather expensive + * operations to do, and we on top of that would have to do + * it each time a name appears, we here map names to their + * encoded equivalents. + * + * This means that when writing out large documents, the serialization + * of names after a while is reduced to a hash lookup and passing an + * existing byte array. + * + * We use QXmlName::Code as key as opposed to merely QName, because the + * prefix is of significance. + */ + QHash nameCache; + const QXmlQuery query; + + inline void write(const char c); + +private: + enum Constants + { + EstimatedTreeDepth = 10, + + /** + * We use a high count to avoid rehashing. We can afford it since we + * only allocate one hash for this. + */ + EstimatedNameCount = 60 + }; +}; + +void QXmlSerializerPrivate::write(const char c) +{ + device->putChar(c); +} +QT_END_NAMESPACE +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/common.pri b/src/xmlpatterns/common.pri new file mode 100644 index 0000000..27253d8 --- /dev/null +++ b/src/xmlpatterns/common.pri @@ -0,0 +1,18 @@ +# This qmake file is included by all Patternist projects and contains common Qt defines, +# compiler warnings, and include paths. + +INCLUDEPATH += $$PWD/acceltree \ + $$PWD/data \ + $$PWD/api \ + $$PWD/environment \ + $$PWD/expr \ + $$PWD/functions \ + $$PWD/iterators \ + $$PWD/janitors \ + $$PWD/parser \ + $$PWD/schema \ + $$PWD/type \ + $$PWD/utils + +DEPENDPATH += $$INCLUDEPATH + diff --git a/src/xmlpatterns/data/data.pri b/src/xmlpatterns/data/data.pri new file mode 100644 index 0000000..ccfed42 --- /dev/null +++ b/src/xmlpatterns/data/data.pri @@ -0,0 +1,82 @@ +HEADERS += $$PWD/qabstractdatetime_p.h \ + $$PWD/qabstractduration_p.h \ + $$PWD/qabstractfloatcasters_p.h \ + $$PWD/qabstractfloatmathematician_p.h \ + $$PWD/qabstractfloat_p.h \ + $$PWD/qanyuri_p.h \ + $$PWD/qatomiccaster_p.h \ + $$PWD/qatomiccasters_p.h \ + $$PWD/qatomiccomparator_p.h \ + $$PWD/qatomiccomparators_p.h \ + $$PWD/qatomicmathematician_p.h \ + $$PWD/qatomicmathematicians_p.h \ + $$PWD/qatomicstring_p.h \ + $$PWD/qbase64binary_p.h \ + $$PWD/qboolean_p.h \ + $$PWD/qcommonvalues_p.h \ + $$PWD/qcomparisonfactory_p.h \ + $$PWD/qdate_p.h \ + $$PWD/qdaytimeduration_p.h \ + $$PWD/qdecimal_p.h \ + $$PWD/qderivedinteger_p.h \ + $$PWD/qderivedstring_p.h \ + $$PWD/qduration_p.h \ + $$PWD/qgday_p.h \ + $$PWD/qgmonthday_p.h \ + $$PWD/qgmonth_p.h \ + $$PWD/qgyearmonth_p.h \ + $$PWD/qgyear_p.h \ + $$PWD/qhexbinary_p.h \ + $$PWD/qinteger_p.h \ + $$PWD/qitem_p.h \ + $$PWD/qnodebuilder_p.h \ + $$PWD/qqnamevalue_p.h \ + $$PWD/qresourceloader_p.h \ + $$PWD/qschemadatetime_p.h \ + $$PWD/qschemanumeric_p.h \ + $$PWD/qschematime_p.h \ + $$PWD/qsorttuple.cpp \ + $$PWD/quntypedatomic_p.h \ + $$PWD/qvalidationerror_p.h \ + $$PWD/qvaluefactory_p.h \ + $$PWD/qyearmonthduration_p.h + +SOURCES += $$PWD/qabstractdatetime.cpp \ + $$PWD/qabstractduration.cpp \ + $$PWD/qanyuri.cpp \ + $$PWD/qatomiccaster.cpp \ + $$PWD/qatomiccasters.cpp \ + $$PWD/qatomiccomparator.cpp \ + $$PWD/qatomiccomparators.cpp \ + $$PWD/qatomicmathematician.cpp \ + $$PWD/qatomicmathematicians.cpp \ + $$PWD/qatomicstring.cpp \ + $$PWD/qatomicvalue.cpp \ + $$PWD/qbase64binary.cpp \ + $$PWD/qboolean.cpp \ + $$PWD/qcommonvalues.cpp \ + $$PWD/qcomparisonfactory.cpp \ + $$PWD/qdate.cpp \ + $$PWD/qdaytimeduration.cpp \ + $$PWD/qdecimal.cpp \ + $$PWD/qduration.cpp \ + $$PWD/qgday.cpp \ + $$PWD/qgmonth.cpp \ + $$PWD/qgmonthday.cpp \ + $$PWD/qgyear.cpp \ + $$PWD/qgyearmonth.cpp \ + $$PWD/qhexbinary.cpp \ + $$PWD/qinteger.cpp \ + $$PWD/qitem.cpp \ + $$PWD/qnodebuilder.cpp \ + $$PWD/qnodemodel.cpp \ + $$PWD/qqnamevalue.cpp \ + $$PWD/qresourceloader.cpp \ + $$PWD/qschemadatetime.cpp \ + $$PWD/qschemanumeric.cpp \ + $$PWD/qschematime.cpp \ + $$PWD/qsorttuple.cpp \ + $$PWD/quntypedatomic.cpp \ + $$PWD/qvalidationerror.cpp \ + $$PWD/qvaluefactory.cpp \ + $$PWD/qyearmonthduration.cpp diff --git a/src/xmlpatterns/data/qabstractdatetime.cpp b/src/xmlpatterns/data/qabstractdatetime.cpp new file mode 100644 index 0000000..900a516 --- /dev/null +++ b/src/xmlpatterns/data/qabstractdatetime.cpp @@ -0,0 +1,400 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qbuiltintypes_p.h" +#include "qitem_p.h" +#include "qpatternistlocale_p.h" +#include "qvalidationerror_p.h" + +#include "qabstractdatetime_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +AbstractDateTime::AbstractDateTime(const QDateTime &dateTime) : m_dateTime(dateTime) +{ + Q_ASSERT(dateTime.isValid()); +} + +#define badData(msg) errorMessage = ValidationError::createError(msg); return QDateTime() +#define getCapt(sym) ((captTable.sym == -1) ? QString() : capts.at(captTable.sym)) +#define getSafeCapt(sym) ((captTable.sym == -1) ? QString() : capts.value(captTable.sym)) + +QDateTime AbstractDateTime::create(AtomicValue::Ptr &errorMessage, + const QString &lexicalSource, + const CaptureTable &captTable) +{ + QRegExp myExp(captTable.regExp); + + if(!myExp.exactMatch(lexicalSource)) + { + badData(QString()); + } + + const QStringList capts(myExp.capturedTexts()); + const QString yearStr(getCapt(year)); + + if(yearStr.size() > 4 && yearStr.at(0) == QLatin1Char('0')) + { + badData(QtXmlPatterns::tr("Year %1 is invalid because it begins with %2.") + .arg(formatData(yearStr)).arg(formatData("0"))); + } + + /* If the strings are empty, load default values which are + * guranteed to pass the validness tests. */ + const QString monthStr(getCapt(month)); + const QString dayStr(getCapt(day)); + YearProperty year = yearStr.isEmpty() ? DefaultYear : yearStr.toInt(); + if(getCapt(yearSign) == QChar::fromLatin1('-')) + year = -year; + const MonthProperty month = monthStr.isEmpty() ? DefaultMonth : monthStr.toInt(); + const MonthProperty day = dayStr.isEmpty() ? DefaultDay : dayStr.toInt(); + + if(!QDate::isValid(year, month, day)) + { + /* Try to give an intelligent message. */ + if(day > 31 || day < 1) + { + badData(QtXmlPatterns::tr("Day %1 is outside the range %2..%3.") + .arg(formatData(QString::number(day))) + .arg(formatData("01")) + .arg(formatData("31"))); + } + else if(month > 12 || month < -12 || month == 0) + { + badData(QtXmlPatterns::tr("Month %1 is outside the range %2..%3.") + .arg(month) + .arg(formatData("01")) + .arg(formatData("12"))); + + } + else if(QDate::isValid(DefaultYear, month, day)) + { + /* We can't use the badData() macro here because we need a different + * error code: FODT0001 instead of FORG0001. */ + errorMessage = ValidationError::createError(QtXmlPatterns::tr( + "Overflow: Can't represent date %1.") + .arg(formatData(QLatin1String("%1-%2-%3")) + .arg(year).arg(month).arg(day)), + ReportContext::FODT0001); + return QDateTime(); + } + else + { + badData(QtXmlPatterns::tr("Day %1 is invalid for month %2.") + .arg(formatData(QString::number(day))) + .arg(formatData(QString::number(month)))); + } + } + + /* Parse the zone offset. */ + ZoneOffsetParseResult zoResult; + const ZOTotal offset = parseZoneOffset(zoResult, capts, captTable); + + if(zoResult == Error) + { + errorMessage = ValidationError::createError(); + /* We encountered an error, so stop processing. */ + return QDateTime(); + } + + QDate date(year, month, day); + + /* Only deal with time if time is needed. */ + if(captTable.hour == -1) + { + QDateTime result(date); + setUtcOffset(result, zoResult, offset); + return result; + } + else + { + /* Now, it's time for the time-part. + * + * If the strings are empty, toInt() will return 0, which + * in all cases is valid properties. */ + const QString hourStr(getCapt(hour)); + const QString minutesStr(getCapt(minutes)); + const QString secondsStr(getCapt(seconds)); + HourProperty hour = hourStr.toInt(); + const MinuteProperty mins = minutesStr.toInt(); + const SecondProperty secs = secondsStr.toInt(); + + QString msecondsStr(getSafeCapt(mseconds)); + if(!msecondsStr.isEmpty()) + msecondsStr = msecondsStr.leftJustified(3, QLatin1Char('0'), true); + const MSecondProperty msecs = msecondsStr.toInt(); + + if(hour == 24) + { + /* 24:00:00.00 is an invalid time for QTime, so handle it here. */ + if(mins != 0 || secs != 0 || msecs != 0) + { + badData(QtXmlPatterns::tr("Time 24:%1:%2.%3 is invalid. " + "Hour is 24, but minutes, seconds, " + "and milliseconds are not all 0; ") + .arg(mins).arg(secs).arg(msecs)); + } + else + { + hour = 0; + date = date.addDays(1); + } + } + else if(!QTime::isValid(hour, mins, secs, msecs)) + { + badData(QtXmlPatterns::tr("Time %1:%2:%3.%4 is invalid.") + .arg(hour).arg(mins).arg(secs).arg(msecs)); + } + + const QTime time(hour, mins, secs, msecs); + Q_ASSERT(time.isValid()); + + QDateTime result(date, time); + setUtcOffset(result, zoResult, offset); + return result; + } +} + +ZOTotal AbstractDateTime::parseZoneOffset(ZoneOffsetParseResult &result, + const QStringList &capts, + const CaptureTable &captTable) +{ + const QString zoneOffsetSignStr(getCapt(zoneOffsetSign)); + + if(zoneOffsetSignStr.isEmpty()) + { + const QString zoneOffsetUTCStr(getCapt(zoneOffsetUTCSymbol)); + Q_ASSERT(zoneOffsetUTCStr.isEmpty() || zoneOffsetUTCStr == QLatin1String("Z")); + + if(zoneOffsetUTCStr.isEmpty()) + result = LocalTime; + else + result = UTC; + + return 0; + } + + Q_ASSERT(zoneOffsetSignStr == QLatin1String("-") || zoneOffsetSignStr == QLatin1String("+")); + + const QString zoneOffsetHourStr(getCapt(zoneOffsetHour)); + Q_ASSERT(!zoneOffsetHourStr.isEmpty()); + const ZOHourProperty zoHour = zoneOffsetHourStr.toInt(); + + if(zoHour > 14 || zoHour < -14) + { + result = Error; + return 0; + /* + badZOData(QtXmlPatterns::tr("%1 it is not a valid hour property in a zone offset. " + "It must be less than or equal to 14.").arg(zoHour)); + */ + } + + const QString zoneOffsetMinuteStr(getCapt(zoneOffsetMinute)); + Q_ASSERT(!zoneOffsetMinuteStr.isEmpty()); + const ZOHourProperty zoMins = zoneOffsetMinuteStr.toInt(); + + if(zoHour == 14 && zoMins != 0) + { + /* + badZOData(QtXmlPatterns::tr("When the hour property in a zone offset is 14, the minute property " + "must be 0, not %1.").arg(zoMins)); + */ + result = Error; + return 0; + } + else if(zoMins > 59 || zoMins < -59) + { + /* + badZOData(QtXmlPatterns::tr("The minute property in a zone offset cannot be larger than 59. " + "%1 is therefore invalid.").arg(zoMins)); + */ + result = Error; + return 0; + } + + if(zoHour == 0 && zoMins == 0) /* "-00:00" and "+00:00" is equal to 'Z'. */ + { + result = UTC; + return 0; + } + else + { + ZOTotal zoneOffset = (zoHour * 60 + zoMins) * 60; + + if(zoneOffsetSignStr == QChar::fromLatin1('-')) + zoneOffset = -zoneOffset; + + result = Offset; + return zoneOffset; + } +} +//#undef badZOData + +void AbstractDateTime::setUtcOffset(QDateTime &result, + const ZoneOffsetParseResult zoResult, + const int zoOffset) +{ + if(zoResult == UTC) + result.setTimeSpec(Qt::UTC); + else if(zoResult == LocalTime) + result.setTimeSpec(Qt::LocalTime); + else + { + Q_ASSERT(zoResult == Offset); + result.setUtcOffset(zoOffset); + } +} + +#undef badData +#undef getCapt +#undef getSafeCapt + +bool AbstractDateTime::isRangeValid(const QDate &date, + QString &message) +{ + if(date.isValid()) + return true; + else + { + message = QtXmlPatterns::tr("Overflow: Date can't be represented."); + return false; + } +} + +QString AbstractDateTime::dateToString() const +{ + return m_dateTime.toString(QLatin1String("yyyy-MM-dd")); +} + +QString AbstractDateTime::serializeMSeconds(const MSecondProperty mseconds) +{ + QString retval; + retval.append(QLatin1Char('.')); + int div = 100; + MSecondProperty msecs = mseconds; + + while(msecs > 0) + { + int d = msecs / div; + retval.append(QLatin1Char(d + '0')); + msecs = msecs % div; + div = div / 10; + } + + return retval; +} + +QString AbstractDateTime::timeToString() const +{ + QString base(m_dateTime.toString(QLatin1String("hh:mm:ss"))); + const MSecondProperty msecs = m_dateTime.time().msec(); + + if(msecs) + base.append(serializeMSeconds(msecs)); + + return base; +} + +QString AbstractDateTime::zoneOffsetToString() const +{ + switch(m_dateTime.timeSpec()) + { + case Qt::LocalTime: + return QString(); + case Qt::UTC: + return QLatin1String("Z"); + default: + { + Q_ASSERT(m_dateTime.timeSpec() == Qt::OffsetFromUTC); + + const int zoneOffset = m_dateTime.utcOffset(); + Q_ASSERT(zoneOffset != 0); + const int posZoneOffset = qAbs(zoneOffset); + + /* zoneOffset is in seconds. */ + const int hours = posZoneOffset/(60 * 60); + const int minutes = (posZoneOffset % (60 * 60)) / 60; + + QString result; + result.reserve(6); + + result.append(zoneOffset < 0 ? QLatin1Char('-') : QLatin1Char('+')); + result.append(QString::number(hours).rightJustified(2, QLatin1Char('0'))); + result.append(QLatin1Char(':')); + result.append(QString::number(minutes).rightJustified(2, QLatin1Char('0'))); + return result; + } + } +} + +void AbstractDateTime::copyTimeSpec(const QDateTime &from, + QDateTime &to) +{ + switch(from.timeSpec()) + { + case Qt::UTC: + /* Fallthrough. */ + case Qt::LocalTime: + { + to.setTimeSpec(from.timeSpec()); + return; + } + case Qt::OffsetFromUTC: + { + to.setUtcOffset(from.utcOffset()); + Q_ASSERT(to.timeSpec() == Qt::OffsetFromUTC); + return; + } + } +} + +Item AbstractDateTime::fromValue(const QDateTime &) const +{ + Q_ASSERT_X(false, Q_FUNC_INFO, + "Calling AbstractDateTime::fromDateTime() makes no sense."); + return Item(); +} +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qabstractdatetime_p.h b/src/xmlpatterns/data/qabstractdatetime_p.h new file mode 100644 index 0000000..3ad169b --- /dev/null +++ b/src/xmlpatterns/data/qabstractdatetime_p.h @@ -0,0 +1,261 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_AbstractDateTime_H +#define Patternist_AbstractDateTime_H + +#include +#include + +#include "qitem_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Base class for classes implementing values related to time, date or both. + * + * @see XML Schema + * Part 2: Datatypes Second Edition, 3.2.7 dateTime + * @see XQuery + * 1.0 and XPath 2.0 Data Model (XDM), 3.3.2 Dates and Times + * @see A summary of + * the international standard date and time notation, Markus Kuhn + * @see ISO 8601, + * From Wikipedia, the free encyclopedia + * @author Frans Englich + * @ingroup Patternist_xdm + */ + class AbstractDateTime : public AtomicValue + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + AbstractDateTime(const QDateTime &dateTime); + + enum + { + DefaultYear = 2000, + DefaultMonth = 1, + DefaultDay = 1 + }; + + /** + * @returns the date time this class represents, as a QDateTime. + */ + inline const QDateTime &toDateTime() const + { + return m_dateTime; + } + + + /** + * @short Acts as a mapping table for AbstractDateTime::create() + * and describes where certain fields in a QRegExp pattern can be found + * for a particular W3C XML Schema date/time type. + * + * @author Frans Englich + * @ingroup Patternist_xdm + */ + class CaptureTable + { + public: + CaptureTable(const QRegExp &exp, + const qint8 zoneOffsetSignP, + const qint8 zoneOffsetHourP, + const qint8 zoneOffsetMinuteP, + const qint8 zoneOffsetUTCSymbolP, + const qint8 yearP, + const qint8 monthP = -1, + const qint8 dayP = -1, + const qint8 hourP = -1, + const qint8 minutesP = -1, + const qint8 secondsP = -1, + const qint8 msecondsP = -1, + const qint8 yearSignP = -1) : regExp(exp) + , zoneOffsetSign(zoneOffsetSignP) + , zoneOffsetHour(zoneOffsetHourP) + , zoneOffsetMinute(zoneOffsetMinuteP) + , zoneOffsetUTCSymbol(zoneOffsetUTCSymbolP) + , year(yearP) + , month(monthP) + , day(dayP) + , hour(hourP) + , minutes(minutesP) + , seconds(secondsP) + , mseconds(msecondsP) + , yearSign(yearSignP) + { + Q_ASSERT(exp.isValid()); + } + + const QRegExp regExp; + const qint8 zoneOffsetSign; + const qint8 zoneOffsetHour; + const qint8 zoneOffsetMinute; + const qint8 zoneOffsetUTCSymbol; + const qint8 year; + const qint8 month; + const qint8 day; + const qint8 hour; + const qint8 minutes; + const qint8 seconds; + const qint8 mseconds; + const qint8 yearSign; + + private: + Q_DISABLE_COPY(CaptureTable) + }; + + /** + * @returns m_dateTime's time part converted to string. This is for + * example "12" or "01.023". + */ + QString timeToString() const; + + /** + * @returns m_dateTime's date part converted to string. This is for + * example "2004-05-12" or "-2004-05-12". + */ + QString dateToString() const; + + /** + * Serializes the milli seconds @p msecs into a string representation. For + * example, if @p msecs is 1, ".001" is returned; if @p msecs is 100 then + * is ".1" returned. + */ + static QString serializeMSeconds(const MSecondProperty msecs); + + /** + * A factory function for creating instances that are of the dynamic + * type of this class, that represents @p dt. + * + * The default implementation performs an assert() call. This function + * is not pure virtual because all sub-classes do not use it. + */ + virtual Item fromValue(const QDateTime &dt) const; + + /** + * Determines whether @p dt is a date-time that can be represented, + * and isn't too early or too late. If it is valid, @c true is returned. Otherwise, + * @c false is returned and @p message is set to contain a translated message for + * human consumption, describing the error. + */ + static bool isRangeValid(const QDate &date, + QString &message); + + protected: + + /** + * @returns m_dateTime' zone offset converted to string, as per the + * the W3C XML Schema types. This is for + * example "Z" or "+12.00"(depending on m_dateTime). + */ + QString zoneOffsetToString() const; + + static QDateTime create(AtomicValue::Ptr &errorMessage, + const QString &lexicalSource, + const CaptureTable &captTable); + + /** + * @short Makes the QDateTime::timeSpec() and QDateTime::zoneOffset() + * of @p ot * consistent to @p from. + */ + static void copyTimeSpec(const QDateTime &from, + QDateTime &to); + + const QDateTime m_dateTime; + + private: + enum ZoneOffsetParseResult + { + /** + * syntax or logical error was encountered. + */ + Error, + /** + * It's a valid offset from UTC. + */ + Offset, + + /** + * No zone offset was specified, it's an implementation defined zone offset. + */ + LocalTime, + UTC + }; + + /** + * @short Parses the zone offset. All types use zone offsets. + * + * If result is set to Offset, the offset is returned, otherwise + * the return value is undefined. + * + * The offset is in seconds. + */ + static ZOTotal parseZoneOffset(ZoneOffsetParseResult &result, + const QStringList &capts, + const CaptureTable &captTable); + + static inline void setUtcOffset(QDateTime &result, + const ZoneOffsetParseResult zoResult, + const int zoOffset); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qabstractduration.cpp b/src/xmlpatterns/data/qabstractduration.cpp new file mode 100644 index 0000000..6bd46c4 --- /dev/null +++ b/src/xmlpatterns/data/qabstractduration.cpp @@ -0,0 +1,235 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qbuiltintypes_p.h" +#include "qpatternistlocale_p.h" +#include "qvalidationerror_p.h" + +#include "qabstractduration_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +AbstractDuration::AbstractDuration(const bool isPos) : m_isPositive(isPos) +{ +} + +#define error(msg) return ValidationError::createError(msg); +#define getCapt(sym) ((captTable.sym == -1) ? QString() : capts.at(captTable.sym)) + +AtomicValue::Ptr AbstractDuration::create(const CaptureTable &captTable, + const QString &lexical, + bool *isPositive, + YearProperty *years, + MonthProperty *months, + DayCountProperty *days, + HourProperty *hours, + MinuteProperty *minutes, + SecondProperty *seconds, + MSecondProperty *mseconds) +{ + /* We don't directly write into the arguments(eg @p years) but uses these + * because the arguments are intended for normalized values, and therefore + * can cause overflows. */ + MonthCountProperty monthCount = 0; + MinuteCountProperty minCount = 0; + HourCountProperty hourCount = 0; + SecondCountProperty secCount = 0; + + Q_ASSERT(isPositive); + QRegExp myExp(captTable.regExp); /* Copy, in order to stay thread safe. */ + + if(!myExp.exactMatch(lexical)) + { + error(QString()); + } + + const QStringList capts(myExp.capturedTexts()); + + + if(days) + { + if(getCapt(tDelimiter).isEmpty()) + { + if((years && getCapt(year).isEmpty() && getCapt(month).isEmpty() && getCapt(day).isEmpty()) + || + (!years && getCapt(day).isEmpty())) + { + error(QtXmlPatterns::tr("At least one component must be present.")); + } + } + else if(getCapt(hour).isEmpty() && + getCapt(minutes).isEmpty() && + getCapt(seconds).isEmpty() && + getCapt(mseconds).isEmpty()) + { + error(QtXmlPatterns::tr("At least one time component must appear " + "after the %1-delimiter.") + .arg(formatKeyword("T"))); + } + } + else if(getCapt(year).isEmpty() && getCapt(month).isEmpty()) /* This checks xs:yearMonthDuration. */ + { + error(QtXmlPatterns::tr("At least one component must be present.")); + } + + /* If we got no '-', we are positive. */ + *isPositive = capts.at(1).isEmpty(); + + if(days) + { + Q_ASSERT(hours); + Q_ASSERT(minutes); + Q_ASSERT(seconds); + Q_ASSERT(mseconds); + + *days = getCapt(day).toInt(); + hourCount = getCapt(hour).toInt(); + minCount = getCapt(minutes).toInt(); + secCount = getCapt(seconds).toInt(); + + const QString msecondsStr(getCapt(mseconds)); + if(!msecondsStr.isEmpty()) + *mseconds = msecondsStr.leftJustified(3, QLatin1Char('0')).toInt(); + else + *mseconds = msecondsStr.toInt(); + + if(secCount > 59) + { + minCount += secCount / 60; + *seconds = secCount % 60; + } + else + *seconds = secCount; + + if(minCount > 59) + { + hourCount += minCount / 60; + *minutes = minCount % 60; + } + else + *minutes = minCount; + + if(hourCount > 23) + { + *days += hourCount / 24; + *hours = hourCount % 24; + } + else + *hours = hourCount; + } + + if(!years) + return AtomicValue::Ptr(); + + /* We're supposed to handle years/months. */ + Q_ASSERT(months); + + *years = getCapt(year).toInt(); + monthCount = getCapt(month).toInt(); + + if(monthCount > 11) + { + *years += monthCount / 12; + *months = monthCount % 12; + } + else + *months = monthCount; + + return AtomicValue::Ptr(); +} +#undef error +#undef getCapt + +bool AbstractDuration::operator==(const AbstractDuration &other) const +{ + if(years() == other.years() + && months() == other.months() + && days() == other.days() + && hours() == other.hours() + && minutes() == other.minutes() + && seconds() == other.seconds() + && mseconds() == other.mseconds()) + { + if(isPositive() == other.isPositive()) + return true; + else if(years() == 0 + && months() == 0 + && days() == 0 + && hours() == 0 + && minutes() == 0 + && seconds () == 0 + && mseconds() == 0) + { + return true; /* Signedness doesn't matter if all are zero. */ + } + } + + return false; +} + +QString AbstractDuration::serializeMSeconds(const MSecondProperty mseconds) +{ + QString retval; + retval.append(QLatin1Char('.')); + int div = 100; + MSecondProperty msecs = mseconds; + + while(msecs > 0) + { + int d = msecs / div; + retval.append(QLatin1Char(d + '0')); + msecs = msecs % div; + div = div / 10; + } + + return retval; +} + +bool AbstractDuration::isPositive() const +{ + return m_isPositive; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qabstractduration_p.h b/src/xmlpatterns/data/qabstractduration_p.h new file mode 100644 index 0000000..adde9d5 --- /dev/null +++ b/src/xmlpatterns/data/qabstractduration_p.h @@ -0,0 +1,192 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_AbstractDuration_H +#define Patternist_AbstractDuration_H + +#include + +#include "qitem_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Base class for classes implementing durations. + * + * @see XML Schema Part + * 2: Datatypes Second Edition, 3.2.6 duration + * @see XQuery + * 1.0 and XPath 2.0 Data Model (XDM), 3.3.2 Dates and Times + * @author Frans Englich + * @ingroup Patternist_xdm + * @todo Documentation is missing/incomplete + */ + class AbstractDuration : public AtomicValue + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * @short The amount in milli seconds. + */ + typedef qint64 Value; + + /** + * @short Acts as a mapping table for AbstractDuration::create() + * and describes where certain fields in a QRegExp pattern can be found + * for a particular W3C XML Schema duration type. + * + * @author Frans Englich + * @ingroup Patternist_xdm + */ + class CaptureTable + { + public: + CaptureTable(const QRegExp &exp, + const qint8 yearP, + const qint8 monthP, + const qint8 dayP = -1, + const qint8 tDelimiterP = -1, + const qint8 hourP = -1, + const qint8 minutesP = -1, + const qint8 secondsP = -1, + const qint8 msecondsP = -1) : regExp(exp), + year(yearP), + month(monthP), + day(dayP), + tDelimiter(tDelimiterP), + hour(hourP), + minutes(minutesP), + seconds(secondsP), + mseconds(msecondsP) + { + Q_ASSERT(exp.isValid()); + Q_ASSERT(yearP == -1 || yearP == 2); + } + + const QRegExp regExp; + const qint8 year; + const qint8 month; + const qint8 day; + const qint8 tDelimiter; + const qint8 hour; + const qint8 minutes; + const qint8 seconds; + const qint8 mseconds; + }; + + /** + * Determines whether this Duration is equal to @p other. + * + * @note Do not re-implement this function. It uses getters such as years() and + * mseconds() for determining its truth value. + */ + bool operator==(const AbstractDuration &other) const; + + virtual YearProperty years() const = 0; + virtual MonthProperty months() const = 0; + virtual DayCountProperty days() const = 0; + virtual HourProperty hours() const = 0; + virtual MinuteProperty minutes() const = 0; + virtual SecondProperty seconds() const = 0; + virtual MSecondProperty mseconds() const = 0; + + /** + * @returns the value of this AbstractDuration. For example, + * in the case of xs:yearMonthDuration, that is YearMonthDuration, + * years times twelve plus the months is returned. + */ + virtual Value value() const = 0; + + /** + * A polymorphic factory function that returns instances of the + * sub-class with the value @p val. + */ + virtual Item fromValue(const Value val) const = 0; + + /** + * Determines whether this AbstractDuration is positive. For example, + * "P10H" is positive, while "-P10H" is not. + * + * @note Do not re-implement this function. Use the constructor, AbstractDuration(), + * for changing the value. + * @returns @c true if this AbstractDuration is positive, otherwise @c false. + */ + bool isPositive() const; + + protected: + + AbstractDuration(const bool isPos); + + static QString serializeMSeconds(const MSecondProperty mseconds); + static AtomicValue::Ptr create(const CaptureTable &captTable, + const QString &lexical, + bool *isPositive, + YearProperty *years, + MonthProperty *months, + DayCountProperty *days, + HourProperty *hours, + MinuteProperty *minutes, + SecondProperty *seconds, + MSecondProperty *mseconds); + const bool m_isPositive; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qabstractfloat.cpp b/src/xmlpatterns/data/qabstractfloat.cpp new file mode 100644 index 0000000..4f0c175 --- /dev/null +++ b/src/xmlpatterns/data/qabstractfloat.cpp @@ -0,0 +1,321 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/** + * @file + * @short This file is included by qabstractfloat_p.h. + * If you need includes in this file, put them in qabstractfloat_p.h, outside of the namespace. + */ + +template +AbstractFloat::AbstractFloat(const xsDouble num) : m_value(num) +{ +} + +template +Numeric::Ptr AbstractFloat::fromValue(const xsDouble num) +{ + return Numeric::Ptr(new AbstractFloat(num)); +} + +template +AtomicValue::Ptr AbstractFloat::fromLexical(const QString &strNumeric) +{ + /* QString::toDouble() handles the whitespace facet. */ + + if(strNumeric == QLatin1String("NaN")) + return isDouble ? CommonValues::DoubleNaN : CommonValues::FloatNaN; + else if(strNumeric == QLatin1String("-INF")) + return isDouble ? CommonValues::NegativeInfDouble : CommonValues::NegativeInfFloat; + else if(strNumeric == QLatin1String("INF")) + return isDouble ? CommonValues::InfDouble : CommonValues::InfFloat; + + /* QString::toDouble() supports any case as well as +INF, but we don't. */ + const QString toUpper(strNumeric.toUpper()); + if(toUpper == QLatin1String("-INF") || + toUpper == QLatin1String("INF") || + toUpper == QLatin1String("+INF") || + toUpper == QLatin1String("NAN")) + { + return ValidationError::createError(); + } + + bool conversionOk = false; + const xsDouble num = strNumeric.toDouble(&conversionOk); + + if(conversionOk) + return AtomicValue::Ptr(new AbstractFloat(num)); + else + return ValidationError::createError(); +} + +template +int AbstractFloat::internalSignbit(const xsDouble num) +{ + Q_ASSERT_X(sizeof(xsDouble) == 8 || sizeof(xsDouble) == 4, Q_FUNC_INFO, + "This implementation of signbit assumes xsDouble, that is qreal, is 64 bits large."); + + union + { + xsDouble asDouble; + qint64 asInt; + } value; + + value.asDouble = num; + + /* The highest bit, the 64'th for those who have 64bit floats, is the sign bit. So we pull it down until that bit is the + * only one left. */ + if(sizeof(xsDouble) == 8) + return value.asInt >> 63; + else + return value.asInt >> 31; +} + +template +bool AbstractFloat::isEqual(const xsDouble a, const xsDouble b) +{ + if(qIsInf(a)) + return qIsInf(b) && internalSignbit(a) == internalSignbit(b); + else if(qIsInf(b)) + return qIsInf(a) && internalSignbit(a) == internalSignbit(b); + else + { + /* Preferably, we would use std::numeric_limits::espilon(), but + * we cannot since we cannot depend on the STL. The small xs:double value below, + * was extracted by printing the std::numeric_limits::epsilon() using + * gdb. */ + return qAbs(a - b) <= 2.2204460492503131e-16 * qAbs(a); + } +} + +template +bool AbstractFloat::isZero() const +{ + return AbstractFloat::isEqual(m_value, 0.0); +} + +template +bool AbstractFloat::evaluateEBV(const QExplicitlySharedDataPointer &) const +{ + if(isZero() || qIsNaN(m_value)) + return false; + else + return true; +} + +template +QString AbstractFloat::stringValue() const +{ + if(qIsNaN(m_value)) + return QLatin1String("NaN"); + else if(qIsInf(m_value)) + return internalSignbit(m_value) == 0 ? QLatin1String("INF") : QLatin1String("-INF"); + /* + * If SV has an absolute value that is greater than or equal to 0.000001 + * (one millionth) and less than 1000000 (one million), + * then the value is converted to an xs:decimal and the resulting xs:decimal + * is converted to an xs:string according to the rules above. + */ + else if(0.000001 <= qAbs(m_value) && qAbs(m_value) < 1000000.0) + return Decimal::toString(toDecimal()); + /* + * If SV has the value positive or negative zero, TV is "0" or "-0" respectively. + */ + else if(isZero()) + return internalSignbit(m_value) == 0 ? QLatin1String("0") : QLatin1String("-0"); + else + { + /* + * Besides these special values, the general form of the canonical form for + * xs:float and xs:double is a mantissa, which is a xs:decimal, followed by + * the letter "E", followed by an exponent which is an xs:integer. + */ + int sign; + int decimalPoint; + char *result = 0; + static_cast(qdtoa(m_value, -1, 0, &decimalPoint, &sign, 0, &result)); + + /* If the copy constructor is used instead of QString::operator=(), + * it doesn't compile. I have no idea why. */ + const QString qret(QString::fromLatin1(result)); + + /* We use free() instead of delete here, because qlocale.cpp use malloc(). Spotted + * by valgrind. */ + free(result); + + QString valueAsString; + + if(sign) + valueAsString += QLatin1Char('-'); + + valueAsString += qret.at(0); + valueAsString += QLatin1Char('.'); + + if(1 == qret.size()) + valueAsString += QLatin1Char('0'); + else + valueAsString += qret.mid(1); + + valueAsString += QLatin1Char('E'); + decimalPoint--; + valueAsString += QString::number(decimalPoint); + return valueAsString; + } +} + +template +xsDouble AbstractFloat::toDouble() const +{ + return m_value; +} + +template +xsInteger AbstractFloat::toInteger() const +{ + return static_cast(m_value); +} + +template +xsFloat AbstractFloat::toFloat() const +{ + /* No cast, since xsFloat and xsDouble are typedef'ed with the same type. */ + return m_value; +} + +template +xsDecimal AbstractFloat::toDecimal() const +{ + return static_cast(m_value); +} + +template +Numeric::Ptr AbstractFloat::round() const +{ + return AbstractFloat::fromValue(static_cast(roundFloat(m_value))); +} + +template +Numeric::Ptr AbstractFloat::roundHalfToEven(const xsInteger precision) const +{ + if(isNaN() || isInf() || isZero()) + return Numeric::Ptr(const_cast *>(this)); + else + { + /* The cast to double helps finding the correct pow() version on irix-cc. */ + const xsDouble powered = pow(double(10), double(precision)); + xsDouble val = powered * m_value; + bool isHalf = false; + + if(val - 0.5 == ::floor(val)) + isHalf = true; + + val = m_value * powered + 0.5; + val = ::floor(val); + + if(isHalf /*&& isOdd(val) or? TODO */) + val -= 1; + + val /= powered; + + return fromValue(val); + } +} + +template +Numeric::Ptr AbstractFloat::floor() const +{ + return AbstractFloat::fromValue(static_cast(::floor(m_value))); +} + +template +Numeric::Ptr AbstractFloat::ceiling() const +{ + return AbstractFloat::fromValue(static_cast(ceil(m_value))); +} + +template +Numeric::Ptr AbstractFloat::abs() const +{ + /* We must use fabs() instead of qAbs() because qAbs() + * doesn't return 0 for -0.0. */ + return AbstractFloat::fromValue(static_cast(fabs(m_value))); +} + +template +bool AbstractFloat::isNaN() const +{ + return qIsNaN(m_value); +} + +template +bool AbstractFloat::isInf() const +{ + return qIsInf(m_value); +} + +template +ItemType::Ptr AbstractFloat::type() const +{ + return isDouble ? BuiltinTypes::xsDouble : BuiltinTypes::xsFloat; +} + +template +Item AbstractFloat::toNegated() const +{ + return fromValue(-m_value).data(); +} + +template +bool AbstractFloat::isSigned() const +{ + Q_ASSERT_X(false, Q_FUNC_INFO, + "It makes no sense to call this function, see Numeric::isSigned()."); + return false; +} + +template +qulonglong AbstractFloat::toUnsignedInteger() const +{ + Q_ASSERT_X(false, Q_FUNC_INFO, + "It makes no sense to call this function, see Numeric::toUnsignedInteger()."); + return 0; +} + diff --git a/src/xmlpatterns/data/qabstractfloat_p.h b/src/xmlpatterns/data/qabstractfloat_p.h new file mode 100644 index 0000000..9abf97f --- /dev/null +++ b/src/xmlpatterns/data/qabstractfloat_p.h @@ -0,0 +1,174 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_AbstractFloat_H +#define Patternist_AbstractFloat_H + +#include + +#include + +#include "qcommonvalues_p.h" +#include "qdecimal_p.h" +#include "qschemanumeric_p.h" +#include "qvalidationerror_p.h" +#include "qbuiltintypes_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Base template class for Float and Double classes. + * + * @author Vincent Ricard + * @ingroup Patternist_xdm + */ + template + class AbstractFloat : public Numeric + { + public: + static Numeric::Ptr fromValue(const xsDouble num); + static AtomicValue::Ptr fromLexical(const QString &strNumeric); + + /** + * @todo more extensive docs. + * + * Performs floating point comparison. + * + * @returns @c true if @p a and @p are equal, otherwise @c false. + */ + static bool isEqual(const xsDouble a, const xsDouble b); + + /** + * Determines the Effective %Boolean Value of this number. + * + * @returns @c false if the number is 0 or @c NaN, otherwise @c true. + */ + bool evaluateEBV(const QExplicitlySharedDataPointer &) const; + + /** + * Returns this AbstractFloat represented as an @c xs:string. + * + * @note In the XPath/XQuery languages, converting @c xs:double and @c xs:float + * to @c xs:string is not specified in XML Schema 1.0 Part 2: Datatypes Second Edition, + * but in XQuery 1.0 and XPath 2.0 Functions and Operators. This will change with W3C XML + * Schema 1.1 + * + * @see XQuery 1.0 + * and XPath 2.0 Functions and Operators, 17.1.2 Casting to xs:string and xdt:untypedAtomic + */ + virtual QString stringValue() const; + + virtual xsDouble toDouble() const; + virtual xsInteger toInteger() const; + virtual xsFloat toFloat() const; + virtual xsDecimal toDecimal() const; + + virtual Numeric::Ptr round() const; + virtual Numeric::Ptr roundHalfToEven(const xsInteger scale) const; + virtual Numeric::Ptr floor() const; + virtual Numeric::Ptr ceiling() const; + virtual Numeric::Ptr abs() const; + + virtual bool isNaN() const; + virtual bool isInf() const; + + virtual ItemType::Ptr type() const; + virtual Item toNegated() const; + virtual qulonglong toUnsignedInteger() const; + + virtual bool isSigned() const; + protected: + AbstractFloat(const xsDouble num); + + private: + /** + * From the Open Group's man page: "The signbit() macro shall return a + * non-zero value if and only if the sign of its argument value is + * negative." + * + * MS Windows doesn't have std::signbit() so here's + * a reinvention of that function. + */ + static inline int internalSignbit(const xsDouble v); + inline bool isZero() const; + + const xsDouble m_value; + }; + + template + Numeric::Ptr createFloat(const xsDouble num); + +#include "qabstractfloat.cpp" + + /** + * @short An instantiation of AbsbstractFloat suitable for @c xs:double. + * + * @ingroup Patternist_xdm + */ + typedef AbstractFloat Double; + + /** + * @short An instantiation of AbstractFloat suitable for @c xs:float. + * + * @ingroup Patternist_xdm + */ + typedef AbstractFloat Float; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qabstractfloatcasters.cpp b/src/xmlpatterns/data/qabstractfloatcasters.cpp new file mode 100644 index 0000000..394d732 --- /dev/null +++ b/src/xmlpatterns/data/qabstractfloatcasters.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + * NOTE: This file is included by qabstractfloatcasters_p.h + * if you need some includes, put them in qabstractfloatcasters_p.h (outside of the namespace) + */ + +template +Item NumericToAbstractFloatCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + // toDouble() returns same thing than toFloat() + return toItem(AbstractFloat::fromValue(from.template as()->toDouble())); +} + +template +Item StringToAbstractFloatCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + return toItem(AbstractFloat::fromLexical(from.stringValue())); +} + +template +Item BooleanToAbstractFloatCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const +{ + // RVCT doesn't like using template parameter in trinary operator when the trinary operator result is + // passed directly into another constructor. + bool tempDouble = isDouble; + if(from.template as()->evaluateEBV(context)) + return tempDouble ? toItem(CommonValues::DoubleOne) : toItem(CommonValues::FloatOne); + else + return tempDouble ? toItem(CommonValues::DoubleZero) : toItem(CommonValues::FloatZero); +} + diff --git a/src/xmlpatterns/data/qabstractfloatcasters_p.h b/src/xmlpatterns/data/qabstractfloatcasters_p.h new file mode 100644 index 0000000..109018c --- /dev/null +++ b/src/xmlpatterns/data/qabstractfloatcasters_p.h @@ -0,0 +1,175 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_AbstractFloatCasters_H +#define Patternist_AbstractFloatCasters_H + +#include "qabstractfloat_p.h" +#include "qatomiccaster_p.h" +#include "qschemanumeric_p.h" + +/** + * @file + * @short Contains classes sub-classing AtomicCaster and which + * are responsible of casting an atomic value to AbstractFloat. + */ + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Casts a @c numeric value, such as @c xs:integer or @c xs:float, to @c xs:double or xs:float. + * + * castFrom() uses Numeric::toDouble() for doing the actual casting. + * + * @ingroup Patternist_xdm + * @author Vincent Ricard + */ + template + class NumericToAbstractFloatCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts a string value, @c xs:string or @c xs:untypedAtomic, to @c xs:double or xs:float. + * + * @ingroup Patternist_xdm + * @author Vincent Ricard + */ + template + class StringToAbstractFloatCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts a value of type @c xs:boolean to @c xs:double or xs:float. + * + * @ingroup Patternist_xdm + * @author Vincent Ricard + */ + template + class BooleanToAbstractFloatCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + +#include "qabstractfloatcasters.cpp" + + /** + * @short Casts a @c numeric value, such as @c xs:integer or @c xs:float, to @c xs:double. + * + * castFrom() uses Numeric::toDouble() for doing the actual casting. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + typedef NumericToAbstractFloatCaster NumericToDoubleCaster; + + /** + * @short Casts a @c numeric value, such as @c xs:double or @c xs:decimal, to @c xs:float. + * + * castFrom() uses Numeric::toFloat() for doing the actual casting. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + typedef NumericToAbstractFloatCaster NumericToFloatCaster; + + /** + * @short Casts a string value, @c xs:string or @c xs:untypedAtomic, to @c xs:double. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + typedef StringToAbstractFloatCaster StringToDoubleCaster; + + /** + * @short Casts a string value, @c xs:string or @c xs:untypedAtomic, to @c xs:float. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + typedef StringToAbstractFloatCaster StringToFloatCaster; + + /** + * @short Casts a value of type @c xs:boolean to @c xs:double. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + typedef BooleanToAbstractFloatCaster BooleanToDoubleCaster; + + /** + * @short Casts a value of type @c xs:boolean to @c xs:float. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + typedef BooleanToAbstractFloatCaster BooleanToFloatCaster; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qabstractfloatmathematician.cpp b/src/xmlpatterns/data/qabstractfloatmathematician.cpp new file mode 100644 index 0000000..94507b3 --- /dev/null +++ b/src/xmlpatterns/data/qabstractfloatmathematician.cpp @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + * @file + * @short This file is included by qatomicmathematicians_p.h + * if you need some includes, put them in qabstractfloatmathematician_p.h, outside of the namespace. + */ + +template +Item AbstractFloatMathematician::calculate(const Item &o1, + const Operator op, + const Item &o2, + const QExplicitlySharedDataPointer &context) const +{ + const Numeric *const num1 = o1.template as(); + const Numeric *const num2 = o2.template as(); + switch(op) + { + case Div: + return toItem(AbstractFloat::fromValue(num1->toDouble() / num2->toDouble())); + case IDiv: + { + if(num1->isNaN() || num2->isNaN()) + { + context->error(QtXmlPatterns::tr("No operand in an integer division, %1, can be %2.") + .arg(formatKeyword("idiv")) + .arg(formatData("NaN")), + ReportContext::FOAR0002, this); + } + else if(num1->isInf()) + { + context->error(QtXmlPatterns::tr("The first operand in an integer division, %1, cannot be infinity (%2).") + .arg(formatKeyword("idiv")) + .arg(formatData("INF")), + ReportContext::FOAR0002, this); + } + else if(num2->toInteger() == 0) + context->error(QtXmlPatterns::tr("The second operand in a division, %1, cannot be zero (%2).") + .arg(formatKeyword("idiv")) + .arg(formatData("0")), + ReportContext::FOAR0001, this); + + return Integer::fromValue(static_cast(num1->toDouble() / num2->toDouble())); + } + case Substract: + return toItem(AbstractFloat::fromValue(num1->toDouble() - num2->toDouble())); + case Mod: + return toItem(AbstractFloat::fromValue(::fmod(num1->toDouble(), num2->toDouble()))); + case Multiply: + return toItem(AbstractFloat::fromValue(num1->toDouble() * num2->toDouble())); + case Add: + return toItem(AbstractFloat::fromValue(num1->toDouble() + num2->toDouble())); + } + + Q_ASSERT(false); + return Item(); /* GCC unbarfer. */ +} + diff --git a/src/xmlpatterns/data/qabstractfloatmathematician_p.h b/src/xmlpatterns/data/qabstractfloatmathematician_p.h new file mode 100644 index 0000000..a51934a --- /dev/null +++ b/src/xmlpatterns/data/qabstractfloatmathematician_p.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_AbstractFloatMathematician_H +#define Patternist_AbstractFloatMathematician_H + +#include "qabstractfloat_p.h" +#include "qatomicmathematician_p.h" +#include "qinteger_p.h" +#include "qschemanumeric_p.h" +#include "qpatternistlocale_p.h" +#include "qsourcelocationreflection_p.h" + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Performs arithmetics between AbstractFloat values (Float and Double classes). + * + * @ingroup Patternist_xdm + * @author Vincent Ricard + */ + template + class AbstractFloatMathematician : public AtomicMathematician + , public DelegatingSourceLocationReflection + { + public: + inline AbstractFloatMathematician(const SourceLocationReflection *const r) : DelegatingSourceLocationReflection(r) + { + } + + virtual Item calculate(const Item &o1, + const Operator op, + const Item &o2, + const QExplicitlySharedDataPointer &context) const; + }; + +#include "qabstractfloatmathematician.cpp" + + /** + * An instantiation of AbstractFloatMathematician that handles @c xs:double. + */ + typedef AbstractFloatMathematician DoubleMathematician; + + /** + * An instantiation of AbstractFloatMathematician that handles @c xs:float. + */ + typedef AbstractFloatMathematician FloatMathematician; +} + +QT_END_NAMESPACE +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qanyuri.cpp b/src/xmlpatterns/data/qanyuri.cpp new file mode 100644 index 0000000..5d50efc --- /dev/null +++ b/src/xmlpatterns/data/qanyuri.cpp @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdynamiccontext_p.h" +#include "qvalidationerror_p.h" +#include "qitem_p.h" + +#include "qanyuri_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +AnyURI::AnyURI(const QString &s) : AtomicString(s) +{ +} + +AnyURI::Ptr AnyURI::fromValue(const QString &value) +{ + return AnyURI::Ptr(new AnyURI(value)); +} + +AnyURI::Ptr AnyURI::fromValue(const QUrl &uri) +{ + return AnyURI::Ptr(new AnyURI(uri.toString())); +} + +AnyURI::Ptr AnyURI::resolveURI(const QString &relative, + const QString &base) +{ + const QUrl urlBase(base); + return AnyURI::fromValue(urlBase.resolved(relative).toString()); +} + +ItemType::Ptr AnyURI::type() const +{ + return BuiltinTypes::xsAnyURI; +} + +AnyURI::Ptr AnyURI::fromLexical(const QString &value) +{ + bool isValid; + /* The error code doesn't matter, because we never raise error. */ + const QUrl retval(toQUrl(value, + DynamicContext::Ptr(), + 0, + &isValid, + false)); + if(isValid) + return fromValue(retval); + else + return ValidationError::createError(); +} + +bool AnyURI::isValid(const QString &candidate) +{ + bool isOk = false; + /* The error code doesn't matter, because we never raise error. */ + toQUrl(candidate, + ReportContext::Ptr(), + 0, + &isOk, + false); + return isOk; +} +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qanyuri_p.h b/src/xmlpatterns/data/qanyuri_p.h new file mode 100644 index 0000000..6567d9c --- /dev/null +++ b/src/xmlpatterns/data/qanyuri_p.h @@ -0,0 +1,212 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_AnyURI_H +#define Patternist_AnyURI_H + +#include +#include + +#include "qatomicstring_p.h" +#include "qbuiltintypes_p.h" +#include "qpatternistlocale_p.h" +#include "qreportcontext_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A value of type xs:anyURI. + * + * Due to bugs in QUrl and slight differences in behavior and + * interpretation, QUrl can never be used directly for dealing with URIs, + * values of type @c xs:anyURI. Therefore, it's important to use the + * functionality this class provides, such as the functions toQUrl(), + * fromLexical(), isValid(), and resolveURI(). + * + * @see QUrl + * @author Frans Englich + * @ingroup Patternist_xdm + */ + class AnyURI : public AtomicString + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Creates an instance representing @p value. + * + * @note @p value must be a valid @c xs:anyURI. If it is of interest + * to construct from a lexical representation, use fromLexical(). + */ + static AnyURI::Ptr fromValue(const QString &value); + + static AnyURI::Ptr fromValue(const QUrl &uri); + + /** + * @short Treates @p value as a lexical representation of @c xs:anyURI + * but returns the value instance as a QUrl. + * + * If @p value is not a valid lexical representation of @c xs:anyURI, + * an error is issued via @p context. + * + * If @p isValid is passed, no error is raised and it is instead set + * appropriately. + */ + template + static inline QUrl toQUrl(const QString &value, + const TReportContext &context, + const SourceLocationReflection *const r, + bool *const isValid = 0, + const bool issueError = true) + { + /* QUrl doesn't flag ":/..." so we workaround it. */ + const QString simplified(value.simplified()); + const QUrl uri(simplified, QUrl::StrictMode); + + if(uri.isEmpty() || (uri.isValid() && (!simplified.startsWith(QLatin1Char(':')) || !uri.isRelative()))) + { + if(isValid) + *isValid = true; + + return uri; + } + else + { + if(isValid) + *isValid = false; + + if(issueError) + { + context->error(QtXmlPatterns::tr("%1 is not a valid value of type %2.").arg(formatURI(value), formatType(context->namePool(), BuiltinTypes::xsAnyURI)), + code, r); + } + + return QUrl(); + } + } + + /** + * @short Return @c true if @p candidate is a valid @c xs:anyURI, + * otherwise @c false. + */ + static bool isValid(const QString &candidate); + + /** + * @short Constructs a @c xs:anyURI value from the lexical representation @p value. + * + * If @p value is not a valid lexical representation of @c xs:anyURI, + * an error is issued via @p context. + */ + template + static inline AnyURI::Ptr fromLexical(const QString &value, + const TReportContext &context, + const SourceLocationReflection *const r) + { + return AnyURI::Ptr(new AnyURI(toQUrl(value, context, r).toString())); + } + + /** + * If @p value is not a valid lexical representation for @c xs:anyURI, + * a ValidationError is returned. + */ + static AnyURI::Ptr fromLexical(const QString &value); + + /** + * Creates an AnyURI instance representing an absolute URI which + * is created from resolving @p relative against @p base. + * + * This function must be compatible with the resolution semantics + * specified for fn:resolve-uri. In fact, the implementation of fn:resolve-uri, + * ResourceURIFN, relies on this function. + * + * @see RFC 3986 - Uniform + * Resource Identifier (URI): Generic Syntax + * @see XQuery 1.0 + * and XPath 2.0 Functions and Operators, 8.1 fn:resolve-uri + */ + static AnyURI::Ptr resolveURI(const QString &relative, + const QString &base); + + virtual ItemType::Ptr type() const; + + /** + * @short Returns this @c xs:anyURI value in a QUrl. + */ + inline QUrl toQUrl() const + { + Q_ASSERT_X(QUrl(m_value).isValid(), Q_FUNC_INFO, + qPrintable(QString::fromLatin1("%1 is apparently not ok for QUrl.").arg(m_value))); + return QUrl(m_value); + } + protected: + friend class CommonValues; + + AnyURI(const QString &value); + }; + + /** + * @short Formats @p uri, that's considered to be a URI, for display. + */ + static inline QString formatURI(const NamePool::Ptr &np, const QXmlName::NamespaceCode &uri) + { + return formatURI(np->stringForNamespace(uri)); + } +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qatomiccaster.cpp b/src/xmlpatterns/data/qatomiccaster.cpp new file mode 100644 index 0000000..20af624 --- /dev/null +++ b/src/xmlpatterns/data/qatomiccaster.cpp @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qatomiccaster_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +AtomicCaster::AtomicCaster() +{ +} + +AtomicCaster::~AtomicCaster() +{ +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qatomiccaster_p.h b/src/xmlpatterns/data/qatomiccaster_p.h new file mode 100644 index 0000000..b746bc6 --- /dev/null +++ b/src/xmlpatterns/data/qatomiccaster_p.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_AtomicCaster_H +#define Patternist_AtomicCaster_H + +#include "qdynamiccontext_p.h" +#include "qitem_p.h" +#include "qatomictypedispatch_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short AtomicCaster is an abstract base class for classes + * that performs casting between two atomic values of specific types. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class AtomicCaster : public AtomicTypeVisitorResult + { + public: + typedef QExplicitlySharedDataPointer Ptr; + AtomicCaster(); + virtual ~AtomicCaster(); + + /** + * Casts @p from to an atomic value of the type this class + * casts to, and returns that value. The @p context is used + * for reporting errors in case the casting fails, and to in general + * access information from the dynamic context. + */ + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const = 0; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qatomiccasters.cpp b/src/xmlpatterns/data/qatomiccasters.cpp new file mode 100644 index 0000000..250641f --- /dev/null +++ b/src/xmlpatterns/data/qatomiccasters.cpp @@ -0,0 +1,336 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qabstractfloat_p.h" +#include "qanyuri_p.h" +#include "qbase64binary_p.h" +#include "qboolean_p.h" +#include "qcommonvalues_p.h" +#include "qdate_p.h" +#include "qschemadatetime_p.h" +#include "qdaytimeduration_p.h" +#include "qdecimal_p.h" +#include "qduration_p.h" +#include "qgday_p.h" +#include "qgmonth_p.h" +#include "qgmonthday_p.h" +#include "qgyear_p.h" +#include "qgyearmonth_p.h" +#include "qhexbinary_p.h" +#include "qinteger_p.h" +#include "qatomicstring_p.h" +#include "qschematime_p.h" +#include "quntypedatomic_p.h" +#include "qyearmonthduration_p.h" + +#include "qatomiccasters_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Item ToUntypedAtomicCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + return UntypedAtomic::fromValue(from.stringValue()); +} + +Item ToAnyURICaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + return toItem(AnyURI::fromLexical(from.stringValue())); +} + +Item Base64BinaryToHexBinaryCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + return HexBinary::fromValue(from.as()->asByteArray()); +} + +Item StringToHexBinaryCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const +{ + return HexBinary::fromLexical(context->namePool(), from.stringValue()); +} + +Item HexBinaryToBase64BinaryCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + return Base64Binary::fromValue(from.as()->asByteArray()); +} + +Item StringToBase64BinaryCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + return Base64Binary::fromLexical(from.stringValue()); +} + +Item NumericToBooleanCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + const xsDouble val = from.as()->toDouble(); + if(Double::isEqual(val, 0.0) || qIsNaN(val)) + return CommonValues::BooleanFalse; + else + return CommonValues::BooleanTrue; +} + +Item StringToBooleanCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + return Boolean::fromLexical(from.stringValue()); +} + +Item StringToDecimalCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + return Decimal::fromLexical(from.stringValue()); +} + +Item StringToIntegerCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + return Integer::fromLexical(from.stringValue()); +} + +Item BooleanToDecimalCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const +{ + if(from.as()->evaluateEBV(context)) + return CommonValues::DecimalOne; + else + return CommonValues::DecimalZero; +} + +Item BooleanToIntegerCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const +{ + if(from.as()->evaluateEBV(context)) + return CommonValues::IntegerOne; + else + return CommonValues::IntegerZero; +} + +Item SelfToSelfCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + return from; +} + +Item StringToGYearCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + return GYear::fromLexical(from.stringValue()); +} + +Item StringToGDayCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + return GDay::fromLexical(from.stringValue()); +} + +Item StringToGMonthCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + return GMonth::fromLexical(from.stringValue()); +} + +Item StringToGYearMonthCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + return GYearMonth::fromLexical(from.stringValue()); +} + +Item StringToGMonthDayCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + return GMonthDay::fromLexical(from.stringValue()); +} + +Item StringToDateTimeCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + return DateTime::fromLexical(from.stringValue()); +} + +Item StringToTimeCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + return SchemaTime::fromLexical(from.stringValue()); +} + +Item StringToDateCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + return Date::fromLexical(from.stringValue()); +} + +Item StringToDurationCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + return Duration::fromLexical(from.stringValue()); +} + +Item StringToDayTimeDurationCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + return toItem(DayTimeDuration::fromLexical(from.stringValue())); +} + +Item AbstractDurationToDayTimeDurationCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + const AbstractDuration *const val = from.as(); + + return toItem(DayTimeDuration::fromComponents(val->isPositive(), + val->days(), + val->hours(), + val->minutes(), + val->seconds(), + val->mseconds())); +} + +Item AbstractDurationToYearMonthDurationCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + const AbstractDuration *const val = from.as(); + + return toItem(YearMonthDuration::fromComponents(val->isPositive(), + val->years(), + val->months())); +} + +Item AbstractDurationToDurationCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + const AbstractDuration *const val = from.as(); + + return Duration::fromComponents(val->isPositive(), + val->years(), + val->months(), + val->days(), + val->hours(), + val->minutes(), + val->seconds(), + val->mseconds()); +} + +Item StringToYearMonthDurationCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + return YearMonthDuration::fromLexical(from.stringValue()); +} + +Item AbstractDateTimeToGYearCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + QDateTime dt(from.as()->toDateTime()); + // TODO DT dt.setDateOnly(true); + + return GYear::fromDateTime(dt); +} + +Item AbstractDateTimeToGYearMonthCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + QDateTime dt(from.as()->toDateTime()); + // TODO DT dt.setDateOnly(true); + + return GYearMonth::fromDateTime(dt); +} + +Item AbstractDateTimeToGMonthCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + QDateTime dt(from.as()->toDateTime()); + // TODO DT dt.setDateOnly(true); + + return GMonth::fromDateTime(dt); +} + +Item AbstractDateTimeToGMonthDayCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + QDateTime dt(from.as()->toDateTime()); + // TODO DT dt.setDateOnly(true); + + return GMonthDay::fromDateTime(dt); +} + +Item AbstractDateTimeToGDayCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + QDateTime dt(from.as()->toDateTime()); + // TODO DT dt.setDateOnly(true); + + return GDay::fromDateTime(dt); +} + +Item AbstractDateTimeToDateTimeCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + QDateTime dt(from.as()->toDateTime()); + // TODO DT dt.setDateOnly(false); + + return DateTime::fromDateTime(dt); +} + +Item AbstractDateTimeToDateCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + QDateTime dt(from.as()->toDateTime()); + // TODO DT dt.setDateOnly(true); + + return Date::fromDateTime(dt); +} + +Item AbstractDateTimeToTimeCaster::castFrom(const Item &from, + const QExplicitlySharedDataPointer &) const +{ + QDateTime dt(from.as()->toDateTime()); + // TODO DT dt.setDateOnly(false); + + return SchemaTime::fromDateTime(dt); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qatomiccasters_p.h b/src/xmlpatterns/data/qatomiccasters_p.h new file mode 100644 index 0000000..d55344f --- /dev/null +++ b/src/xmlpatterns/data/qatomiccasters_p.h @@ -0,0 +1,705 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_AtomicCasters_H +#define Patternist_AtomicCasters_H + +#include "qatomiccaster_p.h" +#include "qdecimal_p.h" +#include "qderivedinteger_p.h" +#include "qderivedstring_p.h" +#include "qinteger_p.h" +#include "qvalidationerror_p.h" + +/** + * @file + * @short Contains classes sub-classing AtomicCaster and which + * are responsible of casting an atomic value to another type. + */ + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Casts any atomic value to @c xs:string. + * + * This class uses Item::stringValue() for retrieving a string + * representation, and thus supports casting from atomic values + * of any type. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + template + class ToStringCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const + { + Q_ASSERT(from); + return DerivedString::fromLexical(context->namePool(), from.stringValue()); + } + }; + + /** + * @short Casts any atomic value to @c xs:untypedAtomic. + * + * This class uses Item::stringValue() for retrieving a string + * representation, and thus supports casting from atomic values + * of any type. The implementation is similar to ToStringCaster. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class ToUntypedAtomicCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts a string value to @c xs:anyURI. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class ToAnyURICaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts a @c xs:hexBinary atomic value to @c xs:base64Binary. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class HexBinaryToBase64BinaryCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts a @c xs:base64Binary atomic value to @c xs:hexBinary. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class Base64BinaryToHexBinaryCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:base64Binary. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class StringToBase64BinaryCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:hexBinary. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class StringToHexBinaryCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts any @c numeric value to @c xs:boolean. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class NumericToBooleanCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts any string value, @c xs:string or @c xs:untypedAtomic, to @c xs:boolean. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class StringToBooleanCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts a @c numeric value, such as @c xs:double or @c xs:decimal, to @c xs:integer or + * @c xs:decimal, depending on IsInteger. + * + * castFrom() uses Numeric::toInteger() for doing the actual casting. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + template + class NumericToDecimalCaster : public AtomicCaster + { + public: + /** + * Used by NumericToDerivedIntegerCaster in addition to this class. + */ + static inline QString errorMessage() + { + return QtXmlPatterns::tr("When casting to %1 from %2, the source value cannot be %3."); + } + + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const + { + const ItemType::Ptr t(from.type()); + const Numeric *const num = from.template as(); + + if(BuiltinTypes::xsDouble->xdtTypeMatches(t) || BuiltinTypes::xsFloat->xdtTypeMatches(t)) + { + if(num->isInf() || num->isNaN()) + { + return ValidationError::createError(errorMessage() + .arg(formatType(context->namePool(), IsInteger ? BuiltinTypes::xsInteger : BuiltinTypes::xsDecimal)) + .arg(formatType(context->namePool(), t)) + .arg(formatData(num->stringValue())), + ReportContext::FOCA0002); + } + } + + if(IsInteger) + return Integer::fromValue(num->toInteger()); + else + return toItem(Decimal::fromValue(num->toDecimal())); + } + }; + + /** + * @short Casts a string value, @c xs:string or @c xs:untypedAtomic, to @c xs:decimal. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class StringToDecimalCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts a string value, @c xs:string or @c xs:untypedAtomic, to @c xs:integer. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class StringToIntegerCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts a value of type @c xs:boolean to @c xs:decimal. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class BooleanToDecimalCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts a value of type @c xs:boolean to @c xs:integer. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class BooleanToIntegerCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts a value to itself. Essentially, this AtomicCaster does nothing. + * + * Casting a value to the type of itself is defined to be a noop, + * no operation. When it can be statically detected that will be done, + * CastAs rewrites itself appropriately during compilation, but + * in some cases insufficent data is available at compile time and then + * is this class need on a case-per-case base at evaluation time. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class SelfToSelfCaster : public AtomicCaster + { + public: + + /** + * This function simply returns @p from. + */ + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:gYear. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class StringToGYearCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:gDay. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class StringToGDayCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:gMonth. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class StringToGMonthCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:gYearMonth. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class StringToGYearMonthCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:gYearMonth. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class StringToGMonthDayCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:dateTime. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class StringToDateTimeCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:time. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class StringToTimeCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:date. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class StringToDateCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:duration. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class StringToDurationCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:dayTimeDuration. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class StringToDayTimeDurationCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:yearMonthDuration. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class StringToYearMonthDurationCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + + /** + * @short Casts a @c xs:date or @c xs:dateTime atomic value to @c xs:gYear. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class AbstractDateTimeToGYearCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts a @c xs:date or @c xs:dateTime atomic value to @c xs:gYearMonth. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class AbstractDateTimeToGYearMonthCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts a @c xs:date or @c xs:dateTime atomic value to @c xs:gMonth. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class AbstractDateTimeToGMonthCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts a @c xs:date or @c xs:dateTime atomic value to @c xs:gMonthDay. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class AbstractDateTimeToGMonthDayCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts a @c xs:date or @c xs:dateTime atomic value to @c xs:gDay. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class AbstractDateTimeToGDayCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts an AbstractDateTime instance to DateTime. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class AbstractDateTimeToDateTimeCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts an AbstractDateTime instance to SchemaTime. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class AbstractDateTimeToDateCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts an AbstractDateTime instance to SchemaTime. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class AbstractDateTimeToTimeCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts an AbstractDuration instance to Duration. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class AbstractDurationToDurationCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts an AbstractDuration instance to DayTimeDuration. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class AbstractDurationToDayTimeDurationCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts an AbstractDuration instance to YearMonthDuration. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class AbstractDurationToYearMonthDurationCaster : public AtomicCaster + { + public: + virtual Item castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Casts an @c xs:string instance to a derived type of @c xs:integer. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + template + class StringToDerivedIntegerCaster : public AtomicCaster + { + public: + virtual Item + castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const + { + return DerivedInteger::fromLexical(context->namePool(), from.stringValue()); + } + }; + + /** + * @short Casts an @c xs:boolean instance to a derived type of @c xs:integer. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + template + class BooleanToDerivedIntegerCaster : public AtomicCaster + { + public: + virtual Item + castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const + { + return DerivedInteger::fromValue(context->namePool(), from.template as()->evaluateEBV(context) ? 1 : 0); + } + }; + + /** + * @short Casts an @c xs:boolean instance to a derived type of @c xs:integer. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + template + class AnyToDerivedStringCaster : public AtomicCaster + { + public: + virtual Item + castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const + { + return DerivedString::fromLexical(context->namePool(), from.stringValue()); + } + }; + + /** + * @short Casts any @c numeric instance to a derived type of @c xs:integer. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + template + class NumericToDerivedIntegerCaster : public AtomicCaster + { + public: + virtual Item + castFrom(const Item &from, + const QExplicitlySharedDataPointer &context) const + { + const ItemType::Ptr t(from.type()); + const Numeric *const num = from.template as(); + + if(BuiltinTypes::xsDouble->xdtTypeMatches(t) || BuiltinTypes::xsFloat->xdtTypeMatches(t)) + { + if(num->isInf() || num->isNaN()) + { + return ValidationError::createError(NumericToDecimalCaster::errorMessage() + .arg(formatType(context->namePool(), DerivedInteger::itemType())) + .arg(formatType(context->namePool(), t)) + .arg(formatData(num->stringValue())), + ReportContext::FOCA0002); + } + } + + return toItem(DerivedInteger::fromValue(context->namePool(), from.template as()->toInteger())); + } + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qatomiccomparator.cpp b/src/xmlpatterns/data/qatomiccomparator.cpp new file mode 100644 index 0000000..c0bf3b9 --- /dev/null +++ b/src/xmlpatterns/data/qatomiccomparator.cpp @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qatomiccomparator_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +AtomicComparator::AtomicComparator() +{ +} + +AtomicComparator::~AtomicComparator() +{ +} + +AtomicComparator::ComparisonResult +AtomicComparator::compare(const Item &, + const AtomicComparator::Operator, + const Item &) const +{ + Q_ASSERT_X(false, Q_FUNC_INFO, "This function should never be called."); + return LessThan; +} + +QString AtomicComparator::displayName(const AtomicComparator::Operator op, + const ComparisonType type) +{ + Q_ASSERT(type == AsGeneralComparison || type == AsValueComparison); + if(type == AsGeneralComparison) + { + switch(op) + { + case OperatorEqual: + return QLatin1String("="); + case OperatorGreaterOrEqual: + return QLatin1String("<="); + case OperatorGreaterThan: + return QLatin1String("<"); + case OperatorLessOrEqual: + return QLatin1String(">="); + case OperatorLessThanNaNLeast: + /* Fallthrough. */ + case OperatorLessThanNaNGreatest: + /* Fallthrough. */ + case OperatorLessThan: + return QLatin1String(">"); + case OperatorNotEqual: + return QLatin1String("!="); + } + } + + switch(op) + { + case OperatorEqual: + return QLatin1String("eq"); + case OperatorGreaterOrEqual: + return QLatin1String("ge"); + case OperatorGreaterThan: + return QLatin1String("gt"); + case OperatorLessOrEqual: + return QLatin1String("le"); + case OperatorLessThanNaNLeast: + /* Fallthrough. */ + case OperatorLessThanNaNGreatest: + /* Fallthrough. */ + case OperatorLessThan: + return QLatin1String("lt"); + case OperatorNotEqual: + return QLatin1String("ne"); + } + + Q_ASSERT(false); + return QString(); /* GCC unbarfer. */ +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qatomiccomparator_p.h b/src/xmlpatterns/data/qatomiccomparator_p.h new file mode 100644 index 0000000..304bd92 --- /dev/null +++ b/src/xmlpatterns/data/qatomiccomparator_p.h @@ -0,0 +1,223 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_AtomicComparator_H +#define Patternist_AtomicComparator_H + +#include + +#include "qitem_p.h" +#include "qatomictypedispatch_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QString; + +namespace QPatternist +{ + + /** + * @short Base class for classes responsible of comparing two atomic values. + * + * This class is also known as the AtomicParrot. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class Q_AUTOTEST_EXPORT AtomicComparator : public AtomicTypeVisitorResult + { + public: + AtomicComparator(); + virtual ~AtomicComparator(); + + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Identifies operators used in value comparisons. + * + * The enum values are bit-significant. + * + * @see W3C XML Path + * Language (XPath) 2.0, 3.5.1 Value Comparisons + */ + enum Operator + { + /** + * Operator eq and =. + */ + OperatorEqual = 1, + + /** + * Operator ne and !=. + */ + OperatorNotEqual = 1 << 1, + + /** + * Operator gt and \>. + */ + OperatorGreaterThan = 1 << 2, + + /** + * Operator lt and \<. + */ + OperatorLessThan = 1 << 3, + + /** + * One of the operators we use for sorting. The only difference from + * OperatorLessThan is that it sees NaN as ordered and smaller than + * other numbers. + */ + OperatorLessThanNaNLeast = 1 << 4, + + /** + * One of the operators we use for sorting. The only difference from + * OperatorLessThanLeast is that it sees NaN as ordered and larger than + * other numbers. + */ + OperatorLessThanNaNGreatest = 1 << 5, + + /** + * Operator ge and \>=. + */ + OperatorGreaterOrEqual = OperatorEqual | OperatorGreaterThan, + + /** + * Operator le and \<=. + */ + OperatorLessOrEqual = OperatorEqual | OperatorLessThan + }; + + typedef QFlags Operators; + + /** + * Signifies the result of a value comparison. This is used for value comparisons, + * and in the future likely also for sorting. + * + * @see W3C XML Path + * Language (XPath) 2.0, 3.5.1 Value Comparisons + */ + enum ComparisonResult + { + LessThan = 1, + Equal = 2, + GreaterThan = 4, + Incomparable = 8 + }; + + /** + * Compares @p op1 and @p op2 and determines the relationship between the two. This + * is used for sorting and comparisons. The implementation performs an assert crash, + * and must therefore be re-implemented if comparing the relevant values should be + * possible. + * + * @param op1 the first operand + * @param op the operator. How a comparison is carried out shouldn't depend on what the + * operator is, but in some cases it is of interest. + * @param op2 the second operand + */ + virtual ComparisonResult compare(const Item &op1, + const AtomicComparator::Operator op, + const Item &op2) const; + + /** + * Determines whether @p op1 and @p op2 are equal. It is the same as calling compare() + * and checking whether the return value is Equal, but since comparison testing is such + * a common operation, this specialized function exists. + * + * @returns true if @p op1 and @p op2 are equal. + * + * @param op1 the first operand + * @param op2 the second operand + */ + virtual bool equals(const Item &op1, + const Item &op2) const = 0; + + /** + * Identifies the kind of comparison. + */ + enum ComparisonType + { + /** + * Identifies a general comparison; operator @c =, @c >, @c <=, and so on. + */ + AsGeneralComparison = 1, + + /** + * Identifies a value comparison; operator @c eq, @c lt, @c le, and so on. + */ + AsValueComparison + }; + + /** + * Utility function for getting the lexical representation for + * the comparison operator @p op. Depending on the @p type argument, + * the string returned is either a general comparison or a value comparison + * operator. + * + * @param op the operator which the display name should be determined for. + * @param type signifies whether the returned display name should be for + * a value comparison or a general comparison. For example, if @p op is + * OperatorEqual and @p type is AsValueComparision, "eq" is returned. + */ + static QString displayName(const AtomicComparator::Operator op, + const ComparisonType type); + + }; + Q_DECLARE_OPERATORS_FOR_FLAGS(AtomicComparator::Operators) +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qatomiccomparators.cpp b/src/xmlpatterns/data/qatomiccomparators.cpp new file mode 100644 index 0000000..38d7092 --- /dev/null +++ b/src/xmlpatterns/data/qatomiccomparators.cpp @@ -0,0 +1,386 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qabstractduration_p.h" +#include "qabstractdatetime_p.h" +#include "qbase64binary_p.h" +#include "qboolean_p.h" +#include "qdynamiccontext_p.h" +#include "qqnamevalue_p.h" + +#include "qatomiccomparators_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +/* -------------------------------------------------- */ +AtomicComparator::ComparisonResult +StringComparator::compare(const Item &o1, + const AtomicComparator::Operator, + const Item &o2) const +{ + const int result = QString::compare(o1.stringValue(), o2.stringValue()); + + if(result > 0) + return GreaterThan; + else if(result < 0) + return LessThan; + else + { + Q_ASSERT(result == 0); + return Equal; + } +} + +bool StringComparator::equals(const Item &o1, + const Item &o2) const +{ + return o1.stringValue() == o2.stringValue(); +} +/* -------------------------------------------------- */ + +/* -------------------------------------------------- */ +AtomicComparator::ComparisonResult +CaseInsensitiveStringComparator::compare(const Item &o1, + const AtomicComparator::Operator, + const Item &o2) const +{ + const QString i1(o1.stringValue().toLower()); + const QString i2(o2.stringValue().toLower()); + const int result = QString::compare(i1, i2); + + if(result > 0) + return GreaterThan; + else if(result < 0) + return LessThan; + else + { + Q_ASSERT(result == 0); + return Equal; + } +} + +bool CaseInsensitiveStringComparator::equals(const Item &o1, + const Item &o2) const +{ + const QString s1(o1.stringValue()); + const QString s2(o2.stringValue()); + + return s1.length() == s2.length() && + s1.startsWith(s2, Qt::CaseInsensitive); +} +/* -------------------------------------------------- */ + +/* -------------------------------------------------- */ +bool BinaryDataComparator::equals(const Item &o1, + const Item &o2) const +{ + return o1.as()->asByteArray() == + o2.as()->asByteArray(); +} +/* -------------------------------------------------- */ + +/* -------------------------------------------------- */ +AtomicComparator::ComparisonResult +BooleanComparator::compare(const Item &o1, + const AtomicComparator::Operator, + const Item &o2) const +{ + /* We know Boolean::evaluateEBV doesn't use the DynamicContext. */ + const bool v1 = o1.as()->evaluateEBV(QExplicitlySharedDataPointer()); + const bool v2 = o2.as()->evaluateEBV(QExplicitlySharedDataPointer()); + + if(v1 == v2) + return Equal; + else if(v1 == false) + { + Q_ASSERT(v2 == true); + return LessThan; + } + else + { + Q_ASSERT(v1 == true && v2 == false); + return GreaterThan; + } +} + +bool BooleanComparator::equals(const Item &o1, + const Item &o2) const +{ + /* Boolean is an atomic class. */ + return o1.as() == o2.as(); +} +/* -------------------------------------------------- */ + +/* -------------------------------------------------- */ +AtomicComparator::ComparisonResult +AbstractFloatComparator::compare(const Item &o1, + const AtomicComparator::Operator op, + const Item &o2) const +{ + const xsDouble v1 = o1.as()->toDouble(); + const xsDouble v2 = o2.as()->toDouble(); + + if(Double::isEqual(v1, v2)) + return Equal; + else if(v1 < v2) + return LessThan; + else if(v1 > v2) + return GreaterThan; + else + { + /* We have NaN values. Make sure we don't return a result which would + * signify success for the operator in question. */ + if((op & OperatorGreaterThan) == OperatorGreaterThan) + return LessThan; + else + { + Q_ASSERT((op & OperatorLessThan) == OperatorLessThan); + return GreaterThan; + } + } +} + +bool AbstractFloatComparator::equals(const Item &o1, + const Item &o2) const +{ + return Double::isEqual(o1.as()->toDouble(), o2.as()->toDouble()); +} +/* -------------------------------------------------- */ + +/* -------------------------------------------------- */ +AtomicComparator::ComparisonResult +DecimalComparator::compare(const Item &o1, + const AtomicComparator::Operator, + const Item &o2) const +{ + const xsDecimal v1 = o1.as()->toDecimal(); + const xsDecimal v2 = o2.as()->toDecimal(); + + if(Double::isEqual(v1, v2)) + return Equal; + else if(v1 < v2) + return LessThan; + else + return GreaterThan; +} + +bool DecimalComparator::equals(const Item &o1, + const Item &o2) const +{ + return Double::isEqual(o1.as()->toDecimal(), o2.as()->toDecimal()); +} +/* -------------------------------------------------- */ + +/* -------------------------------------------------- */ +AtomicComparator::ComparisonResult +IntegerComparator::compare(const Item &o1, + const AtomicComparator::Operator, + const Item &o2) const +{ + const Numeric *const num1 = o1.as(); + const Numeric *const num2 = o1.as(); + + /** + * Consider: + * xs:unsignedLong("100") > xs:unsignedLong("18446744073709551615") + * + * If we perform math on the values as if they were xsInteger, the right + * operand overflows, wraps around, and the expression evaluates to false. + * Hence we have this code to deal with it. + * + * This is runtime code, it would have been better if we had separate + * AtomicComparator classes for signed and unsigned values, but the changes + * required to the lookup code are extensive. + */ + if(num1->isSigned() || num2->isSigned()) + { + const xsInteger v1 = o1.as()->toInteger(); + const xsInteger v2 = o2.as()->toInteger(); + + if(v1 == v2) + return Equal; + else if(v1 < v2) + return LessThan; + else + return GreaterThan; + } + else + { + const qulonglong v1 = o1.as()->toUnsignedInteger(); + const qulonglong v2 = o2.as()->toUnsignedInteger(); + + if(v1 == v2) + return Equal; + else if(v1 < v2) + return LessThan; + else + return GreaterThan; + } +} + +bool IntegerComparator::equals(const Item &o1, + const Item &o2) const +{ + return o1.as()->toInteger() == o2.as()->toInteger(); +} + +/* -------------------------------------------------- */ + +/* -------------------------------------------------- */ +bool QNameComparator::equals(const Item &o1, + const Item &o2) const +{ + return o1.as()->m_qName == + o2.as()->m_qName; +} +/* -------------------------------------------------- */ + +/* -------------------------------------------------- */ +bool AbstractDateTimeComparator::equals(const Item &o1, + const Item &o2) const +{ + const QDateTime dt1(o1.as()->toDateTime()); + const QDateTime dt2(o2.as()->toDateTime()); + + /* + pDebug() << "COMPARING:" + << o1->as()->toDateTime().toString() + << o2->as()->toDateTime().toString(); + pDebug() << "DATE ONLY:" + << o1->as()->toDateTime().isDateOnly() + << o2->as()->toDateTime().isDateOnly(); + */ + return dt1 == dt2 && + dt1.timeSpec() == dt2.timeSpec(); +} + +AtomicComparator::ComparisonResult +AbstractDateTimeComparator::compare(const Item &operand1, + const AtomicComparator::Operator, + const Item &operand2) const +{ + const QDateTime &dt1 = operand1.as()->toDateTime(); + const QDateTime &dt2 = operand2.as()->toDateTime(); + + if(dt1 == dt2) + return Equal; + else if(dt1 < dt2) + return LessThan; + else + return GreaterThan; +} +/* -------------------------------------------------- */ + +/* -------------------------------------------------- */ +bool AbstractDurationComparator::equals(const Item &o1, + const Item &o2) const +{ + /* We use AbstractDuration::operator==() */ + return *o1.as() == + *o2.as(); +} + +QDateTime AbstractDurationComparator::addDurationToDateTime(const QDateTime &dateTime, + const AbstractDuration *const duration) +{ + QDateTime result(dateTime); + qint64 seconds = 0; + + const qint8 signMultiplier = (duration->isPositive() ? 1 : -1); + + result = result.addYears(signMultiplier * duration->years()); + result = result.addMonths(signMultiplier * duration->months()); + result = result.addDays(signMultiplier * duration->days()); + + seconds = 60 * 60 * duration->hours(); + seconds += 60 * duration->minutes(); + seconds += duration->seconds(); + + result = result.addSecs(signMultiplier * seconds); + result = result.addMSecs(signMultiplier * duration->mseconds()); + + return result; +} + +AtomicComparator::ComparisonResult +AbstractDurationComparator::compare(const Item &o1, + const AtomicComparator::Operator, + const Item &o2) const +{ + const AbstractDuration *const duration = o1.as(); + const AbstractDuration *const otherDuration = o2.as(); + + const QDateTime dateTime1(QDate(1696, 9, 1), QTime(0, 0, 0), Qt::UTC); + const QDateTime dateTime2(QDate(1697, 2, 1), QTime(0, 0, 0), Qt::UTC); + const QDateTime dateTime3(QDate(1903, 3, 1), QTime(0, 0, 0), Qt::UTC); + const QDateTime dateTime4(QDate(1903, 7, 1), QTime(0, 0, 0), Qt::UTC); + + const QDateTime durationDateTime1 = addDurationToDateTime(dateTime1, duration); + const QDateTime durationDateTime2 = addDurationToDateTime(dateTime2, duration); + const QDateTime durationDateTime3 = addDurationToDateTime(dateTime3, duration); + const QDateTime durationDateTime4 = addDurationToDateTime(dateTime4, duration); + + const QDateTime otherDurationDateTime1 = addDurationToDateTime(dateTime1, otherDuration); + const QDateTime otherDurationDateTime2 = addDurationToDateTime(dateTime2, otherDuration); + const QDateTime otherDurationDateTime3 = addDurationToDateTime(dateTime3, otherDuration); + const QDateTime otherDurationDateTime4 = addDurationToDateTime(dateTime4, otherDuration); + + if (durationDateTime1 > otherDurationDateTime1 && + durationDateTime2 > otherDurationDateTime2 && + durationDateTime3 > otherDurationDateTime3 && + durationDateTime4 > otherDurationDateTime4) { + return GreaterThan; + } else if (durationDateTime1 < otherDurationDateTime1 && + durationDateTime2 < otherDurationDateTime2 && + durationDateTime3 < otherDurationDateTime3 && + durationDateTime4 < otherDurationDateTime4) { + return LessThan; + } else if (*duration == *otherDuration) { + return Equal; + } else { + return Incomparable; + } +} + +/* -------------------------------------------------- */ +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qatomiccomparators_p.h b/src/xmlpatterns/data/qatomiccomparators_p.h new file mode 100644 index 0000000..614916f --- /dev/null +++ b/src/xmlpatterns/data/qatomiccomparators_p.h @@ -0,0 +1,298 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_AtomicComparators_H +#define Patternist_AtomicComparators_H + +#include "qabstractfloat_p.h" +#include "qatomiccomparator_p.h" +#include "qprimitives_p.h" + +/** + * @file + * @short Contains all the classes implementing comparisons between atomic values. + */ + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Performs case @em sensitive string comparison + * between @c xs:anyUri, @c xs:string, and @c xs:untypedAtomic. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class StringComparator : public AtomicComparator + { + public: + /** + * Compares two strings, and returns the appropriate AtomicComparator::ComparisonResult enum. This + * is a bit simplified version of string comparison as defined in the XPath specifications, + * since this does not take any string collations into account(which an implementation neither + * is required to do). + * + * @see XQuery 1.0 and XPath + * 2.0 Functions and Operators, 7.3 ValueComparison::Equality and Comparison of Strings + */ + virtual ComparisonResult compare(const Item &op1, + const AtomicComparator::Operator op, + const Item &op2) const; + + /** + * Compares two strings, and returns @c true if they are considered equal as per + * an ordinary string comparison. In other words, this is an implementation with + * the Unicode code point collation. + * + * @see XQuery 1.0 and XPath + * 2.0 Functions and Operators, 7.3 ValueComparison::Equality and Comparison of Strings + */ + virtual bool equals(const Item &op1, + const Item &op2) const; + }; + + /** + * @short Performs case @em insensitive string comparison + * between @c xs:anyUri, @c xs:string, and @c xs:untypedAtomic. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class CaseInsensitiveStringComparator : public AtomicComparator + { + public: + /** + * Converts both string values to upper case and afterwards compare them. + */ + virtual ComparisonResult compare(const Item &op1, + const AtomicComparator::Operator op, + const Item &op2) const; + + /** + * Converts both string values case insensitively. + */ + virtual bool equals(const Item &op1, + const Item &op2) const; + }; + + /** + * @short Compares @c xs:base64Binary and @c xs:hexBinary values. + * + * @author Frans Englich + */ + class BinaryDataComparator : public AtomicComparator + { + public: + virtual bool equals(const Item &op1, + const Item &op2) const; + }; + + /** + * @short Compares @c xs:boolean values. + * + * This is done via the object's Boolean::evaluteEBV() function. + * + * @author Frans Englich + */ + class BooleanComparator : public AtomicComparator + { + public: + virtual ComparisonResult compare(const Item &op1, + const AtomicComparator::Operator op, + const Item &op2) const; + + virtual bool equals(const Item &op1, + const Item &op2) const; + }; + + /** + * @short Compares @c xs:double values. + * + * @todo Add docs about numeric promotion + * + * @author Frans Englich + */ + class AbstractFloatComparator : public AtomicComparator + { + public: + virtual ComparisonResult compare(const Item &op1, + const AtomicComparator::Operator op, + const Item &op2) const; + + virtual bool equals(const Item &op1, + const Item &op2) const; + }; + + /** + * @short Compares @c xs:double values for the purpose of sorting. + * + * @todo Add docs about numeric promotion + * + * @author Frans Englich + */ + template + class AbstractFloatSortComparator : public AbstractFloatComparator + { + public: + virtual ComparisonResult compare(const Item &o1, + const AtomicComparator::Operator op, + const Item &o2) const + { + Q_ASSERT_X(t_op == OperatorLessThanNaNLeast || t_op == OperatorLessThanNaNGreatest, Q_FUNC_INFO, + "Can only be instantiated with those two."); + Q_ASSERT(op == t_op); + Q_UNUSED(op); /* Needed when building in release mode. */ + + const xsDouble v1 = o1.template as()->toDouble(); + const xsDouble v2 = o2.template as()->toDouble(); + + if(qIsNaN(v1) && !qIsNaN(v2)) + return t_op == OperatorLessThanNaNLeast ? LessThan : GreaterThan; + if(!qIsNaN(v1) && qIsNaN(v2)) + return t_op == OperatorLessThanNaNLeast ? GreaterThan : LessThan; + + if(Double::isEqual(v1, v2)) + return Equal; + else if(v1 < v2) + return LessThan; + else + return GreaterThan; + } + + }; + + /** + * @short Compares @c xs:decimal values. + * + * @author Frans Englich + */ + class DecimalComparator : public AtomicComparator + { + public: + virtual ComparisonResult compare(const Item &op1, + const AtomicComparator::Operator op, + const Item &op2) const; + + virtual bool equals(const Item &op1, + const Item &op2) const; + }; + + /** + * @short Compares @c xs:integer values. + * + * @author Frans Englich + */ + class IntegerComparator : public AtomicComparator + { + public: + virtual ComparisonResult compare(const Item &op1, + const AtomicComparator::Operator op, + const Item &op2) const; + + virtual bool equals(const Item &op1, + const Item &op2) const; + }; + + /** + * @short Compares @c xs:QName values. + * + * @author Frans Englich + */ + class QNameComparator : public AtomicComparator + { + public: + virtual bool equals(const Item &op1, + const Item &op2) const; + }; + + /** + * @short Compares sub-classes of AbstractDateTime. + * + * @author Frans Englich + */ + class AbstractDateTimeComparator : public AtomicComparator + { + public: + virtual ComparisonResult compare(const Item &op1, + const AtomicComparator::Operator op, + const Item &op2) const; + virtual bool equals(const Item &op1, + const Item &op2) const; + }; + + /** + * @short Compares sub-classes of AbstractDuration. + * + * @author Frans Englich + */ + class AbstractDurationComparator : public AtomicComparator + { + public: + virtual ComparisonResult compare(const Item &op1, + const AtomicComparator::Operator op, + const Item &op2) const; + virtual bool equals(const Item &op1, + const Item &op2) const; + + private: + static inline QDateTime addDurationToDateTime(const QDateTime &dateTime, + const AbstractDuration *const duration); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qatomicmathematician.cpp b/src/xmlpatterns/data/qatomicmathematician.cpp new file mode 100644 index 0000000..ddd27a9 --- /dev/null +++ b/src/xmlpatterns/data/qatomicmathematician.cpp @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qatomicmathematician_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +AtomicMathematician::~AtomicMathematician() +{ +} + +QString AtomicMathematician::displayName(const AtomicMathematician::Operator op) +{ + switch(op) + { + case AtomicMathematician::Div: + return QLatin1String("div"); + case AtomicMathematician::IDiv: + return QLatin1String("idiv"); + case AtomicMathematician::Substract: + return QLatin1String("-"); + case AtomicMathematician::Mod: + return QLatin1String("mod"); + case AtomicMathematician::Multiply: + return QLatin1String("*"); + case AtomicMathematician::Add: + return QLatin1String("+"); + } + + return QString(); /* Silence GCC warning. */ +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qatomicmathematician_p.h b/src/xmlpatterns/data/qatomicmathematician_p.h new file mode 100644 index 0000000..a61e1b0 --- /dev/null +++ b/src/xmlpatterns/data/qatomicmathematician_p.h @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_AtomicMathematician_H +#define Patternist_AtomicMathematician_H + +#include + +#include "qdynamiccontext_p.h" +#include "qitem_p.h" +#include "qatomictypedispatch_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Base class for classes that performs arithmetic operations between atomic values. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class Q_AUTOTEST_EXPORT AtomicMathematician : public AtomicTypeVisitorResult + { + public: + virtual ~AtomicMathematician(); + + typedef QExplicitlySharedDataPointer Ptr; + + enum Operator + { + /** + * @see XQuery 1.0 + * and XPath 2.0 Functions and Operators, 6.2.4 op:numeric-divide + */ + Div = 1, + + /** + * @see XQuery 1.0 + * and XPath 2.0 Functions and Operators, 6.2.5 op:numeric-integer-divide + */ + IDiv = 2, + + /** + * @see XQuery 1.0 + * and XPath 2.0 Functions and Operators, 6.2.2 op:numeric-subtract + */ + Substract = 4, + + /** + * @see XQuery 1.0 + * and XPath 2.0 Functions and Operators, 6.2.6 op:numeric-mod + */ + Mod = 8, + + /** + * @see XQuery 1.0 + * and XPath 2.0 Functions and Operators, 6.2.3 op:numeric-multiply + */ + Multiply = 16, + + /** + * @see XQuery 1.0 + * and XPath 2.0 Functions and Operators, 6.2.1 op:numeric-add + */ + Add = 32 + }; + + typedef QFlags Operators; + + virtual Item calculate(const Item &operand1, + const Operator op, + const Item &operand2, + const QExplicitlySharedDataPointer &context) const = 0; + + static QString displayName(const AtomicMathematician::Operator op); + + }; + Q_DECLARE_OPERATORS_FOR_FLAGS(AtomicMathematician::Operators) +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qatomicmathematicians.cpp b/src/xmlpatterns/data/qatomicmathematicians.cpp new file mode 100644 index 0000000..3c6ce40 --- /dev/null +++ b/src/xmlpatterns/data/qatomicmathematicians.cpp @@ -0,0 +1,352 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include + +#include "qabstractdatetime_p.h" +#include "qabstractduration_p.h" +#include "qabstractfloat_p.h" +#include "qdaytimeduration_p.h" +#include "qdecimal_p.h" +#include "qinteger_p.h" +#include "qpatternistlocale_p.h" + +#include "qatomicmathematicians_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +/* The translation strings is place here once, in order to reduce work for translators, + * and provide consistency. */ + +static inline QString idivZeroInvalid() +{ + return QtXmlPatterns::tr("Integer division (%1) by zero (%2) is undefined.") + .arg(formatKeyword("idiv")) + .arg(formatData("0")); +} + +static inline QString divZeroInvalid() +{ + return QtXmlPatterns::tr("Division (%1) by zero (%2) is undefined.") + .arg(formatKeyword("div")) + .arg(formatData("0")); +} + +static inline QString modZeroInvalid() +{ + return QtXmlPatterns::tr("Modulus division (%1) by zero (%2) is undefined.") + .arg(formatKeyword("mod")) + .arg(formatData("0")); +} + +Item DecimalMathematician::calculate(const Item &o1, + const Operator op, + const Item &o2, + const QExplicitlySharedDataPointer &context) const +{ + switch(op) + { + case Div: + { + if(o2.as()->toInteger() == 0) + { + context->error(divZeroInvalid(), ReportContext::FOAR0001, this); + return Item(); /* Silences source code analyzer warning. */ + } + else + return toItem(Decimal::fromValue(o1.as()->toDecimal() / o2.as()->toDecimal())); + } + case IDiv: + { + if(o2.as()->toInteger() == 0) + { + context->error(idivZeroInvalid(), ReportContext::FOAR0001, this); + return Item(); /* Silences source code analyzer warning. */ + } + else + return Integer::fromValue(static_cast(o1.as()->toDecimal() / + o2.as()->toDecimal())); + } + case Substract: + return toItem(Decimal::fromValue(o1.as()->toDecimal() - o2.as()->toDecimal())); + case Mod: + { + if(o2.as()->toInteger() == 0) + { + context->error(modZeroInvalid(), ReportContext::FOAR0001, this); + return Item(); /* Silences source code analyzer warning. */ + } + else + return toItem(Decimal::fromValue(::fmod(o1.as()->toDecimal(), o2.as()->toDecimal()))); + } + case Multiply: + return toItem(Decimal::fromValue(o1.as()->toDecimal() * o2.as()->toDecimal())); + case Add: + return toItem(Decimal::fromValue(o1.as()->toDecimal() + o2.as()->toDecimal())); + } + + Q_ASSERT(false); + return Item(); /* GCC unbarfer. */ +} + +Item IntegerMathematician::calculate(const Item &o1, + const Operator op, + const Item &o2, + const QExplicitlySharedDataPointer &context) const +{ + switch(op) + { + case Div: + if(o2.as()->toInteger() == 0) + { + context->error(divZeroInvalid(), ReportContext::FOAR0001, this); + return Item(); /* Silences source code analyzer warning. */ + } + else /* C++ automatically performs truncation of long integer(xsInteger). */ + return toItem(Decimal::fromValue(o1.as()->toDecimal() / o2.as()->toDecimal())); + case IDiv: + { + if(o2.as()->toInteger() == 0) + { + context->error(idivZeroInvalid(), ReportContext::FOAR0001, this); + return Item(); /* Silences source code analyzer warning. */ + } + else /* C++ automatically performs truncation of long integer(xsInteger). */ + return Integer::fromValue(o1.as()->toInteger() / o2.as()->toInteger()); + } + case Substract: + return Integer::fromValue(o1.as()->toInteger() - o2.as()->toInteger()); + case Mod: + { + const xsInteger divisor = o2.as()->toInteger(); + + if(divisor == 0) + { + context->error(modZeroInvalid(), ReportContext::FOAR0001, this); + return Item(); /* Silences source code analyzer warning. */ + } + else + return Integer::fromValue(o1.as()->toInteger() % divisor); + } + case Multiply: + return Integer::fromValue(o1.as()->toInteger() * o2.as()->toInteger()); + case Add: + return Integer::fromValue(o1.as()->toInteger() + o2.as()->toInteger()); + } + + Q_ASSERT(false); + return Item(); /* GCC unbarfer. */ +} + +Item DurationNumericMathematician::calculate(const Item &o1, + const Operator op, + const Item &o2, + const QExplicitlySharedDataPointer &context) const +{ + Q_ASSERT(op == Div || op == Multiply); + + const AbstractDuration::Ptr duration(o1.as()); + const xsDouble dbl = o2.as()->toDouble(); + + switch(op) + { + case Div: + { + if(qIsInf(dbl)) + return duration->fromValue(0); + else if(qIsNaN(dbl)) + { + context->error(QtXmlPatterns::tr( + "Dividing a value of type %1 by %2 (not-a-number) " + "is not allowed.") + .arg(formatType(context->namePool(), + duration->type())) + .arg(formatData("NaN")), + ReportContext::FOCA0005, + this); + return Item(); + } + else if(Double::isEqual(dbl, 0)) + { + context->error(QtXmlPatterns::tr( + "Dividing a value of type %1 by %2 or %3 (plus or " + "minus zero) is not allowed.") + .arg(formatType(context->namePool(), + duration->type())) + .arg(formatData("-0")) + .arg(formatData("0")), + ReportContext::FODT0002, + this); + return Item(); + } + + return duration->fromValue(static_cast(duration->value() / dbl)); + } + case Multiply: + { + if(Double::isEqual(dbl, 0)) + return duration->fromValue(0); + else if(qIsNaN(dbl)) + { + context->error(QtXmlPatterns::tr( + "Dividing a value of type %1 by %2 (not-a-number) " + "is not allowed.") + .arg(formatType(context->namePool(), + duration->type())) + .arg(formatData("NaN")), + ReportContext::FOCA0005, + this); + return Item(); + } + else if(qIsInf(dbl)) + { + context->error(QtXmlPatterns::tr( + "Multiplication of a value of type %1 by %2 or %3 " + "(plus or minus infinity) is not allowed.") + .arg(formatType(context->namePool(), + duration->type())) + .arg(formatData("-INF")) + .arg(formatData("INF")), + ReportContext::FODT0002, + this); + return Item(); + } + + return duration->fromValue(static_cast(duration->value() * dbl)); + } + default: + { + Q_ASSERT(false); + return Item(); /* Silence warning. */ + } + } +} + +Item DurationDurationMathematician::calculate(const Item &o1, + const Operator op, + const Item &o2, + const QExplicitlySharedDataPointer &) const +{ + const AbstractDuration::Ptr duration(o1.as()); + const AbstractDuration::Value op2 = o2.as()->value(); + + switch(op) + { + case Div: + return toItem(Decimal::fromValue(static_cast(duration->value()) / op2)); + case Substract: + return duration->fromValue(duration->value() - op2); + case Add: + return duration->fromValue(duration->value() + op2); + default: + { + Q_ASSERT(false); + return Item(); /* Silence warning. */ + } + } +} + +OperandSwitcherMathematician:: +OperandSwitcherMathematician(const AtomicMathematician::Ptr &mathematician) : m_mather(mathematician) +{ + Q_ASSERT(mathematician); +} + +Item OperandSwitcherMathematician::calculate(const Item &o1, + const Operator op, + const Item &o2, + const QExplicitlySharedDataPointer &context) const +{ + return m_mather->calculate(o2, op, o1, context); +} + + +Item DateTimeDurationMathematician::calculate(const Item &o1, + const Operator op, + const Item &o2, + const QExplicitlySharedDataPointer &context) const +{ + Q_ASSERT(op == Substract || op == Add); + + const AbstractDateTime::Ptr adt(o1.as()); + const AbstractDuration::Ptr dur(o2.as()); + QDateTime dt(adt->toDateTime()); + //pDebug() << "DateTimeDurationMathematician::calculate():" << dt.toString(); + //dt.setDateOnly(false); + const qint8 sign = (op == Add ? 1 : -1) * (dur->isPositive() ? 1 : -1); + + // TODO milli seconds + dt = dt.addSecs(sign * (dur->seconds() + dur->minutes() * 60 + dur->hours() * 60 * 60)); + dt = dt.addDays(sign * dur->days()); + dt = dt.addMonths(sign * dur->months()); + dt = dt.addYears(sign * dur->years()); + + QString msg; + + if(AbstractDateTime::isRangeValid(dt.date(), msg)) + return adt->fromValue(dt); + else + { + context->error(msg, ReportContext::FODT0001, + this); + return Item(); + } +} + +Item AbstractDateTimeMathematician::calculate(const Item &o1, + const Operator op, + const Item &o2, + const QExplicitlySharedDataPointer &) const +{ + Q_ASSERT(op == Substract || op == Add); + QDateTime dt1(o1.as()->toDateTime()); + QDateTime dt2(o2.as()->toDateTime()); + + const int diff = op == Add ? dt1.secsTo(dt2) : dt2.secsTo(dt1); + + return toItem(DayTimeDuration::fromSeconds(diff)); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qatomicmathematicians_p.h b/src/xmlpatterns/data/qatomicmathematicians_p.h new file mode 100644 index 0000000..607f303 --- /dev/null +++ b/src/xmlpatterns/data/qatomicmathematicians_p.h @@ -0,0 +1,249 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_AtomicMathematicians_H +#define Patternist_AtomicMathematicians_H + +#include "qatomicmathematician_p.h" +#include "qsourcelocationreflection_p.h" + +/** + * @file + * @short Contains classes performing arithemetic operations between atomic values, such as + * subtracting two dates. + */ + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class DecimalMathematician : public AtomicMathematician + , public DelegatingSourceLocationReflection + { + public: + inline DecimalMathematician(const SourceLocationReflection *const r) : DelegatingSourceLocationReflection(r) + { + } + + virtual Item calculate(const Item &o1, + const Operator op, + const Item &o2, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Performs arithmetics between Integer values. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class IntegerMathematician : public AtomicMathematician + , public DelegatingSourceLocationReflection + { + public: + inline IntegerMathematician(const SourceLocationReflection *const r) : DelegatingSourceLocationReflection(r) + { + } + + virtual Item calculate(const Item &o1, + const Operator op, + const Item &o2, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Performs division or multiplication between either DayTimeDuration or YearMonthDuration + * and Double values. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class DurationNumericMathematician : public AtomicMathematician + , public DelegatingSourceLocationReflection + { + public: + inline DurationNumericMathematician(const SourceLocationReflection *const r) : DelegatingSourceLocationReflection(r) + { + } + + virtual Item calculate(const Item &o1, + const Operator op, + const Item &o2, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Performs division between DayTimeDuration and DayTimeDuration, or + * YearMonthDuration and YearMonthDuration. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class DurationDurationDivisor : public AtomicMathematician + { + public: + virtual Item calculate(const Item &o1, + const Operator op, + const Item &o2, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Performs arithmetics between DayTimeDuration and DayTimeDuration, or + * YearMonthDuration and YearMonthDuration. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class DurationDurationMathematician : public AtomicMathematician + { + public: + virtual Item calculate(const Item &o1, + const Operator op, + const Item &o2, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Delegates an AtomicMathematician and switches its operands. + * + * Switches the operands of the call to a call to the calculate() + * on an AtomicMathematician such that the left operand becomes the right, and + * vice versa. + * + * Its constructor takes an AtomicMathematician instance which this OperandSwitcherMathematician + * should act as as a middle-man for, having the role of switching the two operands. Thus, + * OperandSwitcherMathematician can be described as a proxy or delegator class. + * + * This class is used for implementing operator combinations such as + * numeric * xs:yearMonthDuration and + * xs:yearMonthDuration * numeric. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class OperandSwitcherMathematician : public AtomicMathematician + { + public: + /** + * Creates an OperandSwitcherMathematician. + * + * @param mathematician the AtomicMathematician this OperandSwitcherMathematician + * should switch the operands for. Must be a non @c null, valid pointer. + */ + OperandSwitcherMathematician(const AtomicMathematician::Ptr &mathematician); + + /** + * Switch @p o1 and @p o2, and returns the value from the AtomicMathematician + * this OperandSwitcherMathematician represents. + */ + virtual Item calculate(const Item &o1, + const Operator op, + const Item &o2, + const QExplicitlySharedDataPointer &context) const; + private: + const AtomicMathematician::Ptr m_mather; + }; + + /** + * @short Performs arithmetics between an AbstractDateTime value and + * an AbstractDuration value. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class DateTimeDurationMathematician : public AtomicMathematician + , public DelegatingSourceLocationReflection + { + public: + + inline DateTimeDurationMathematician(const SourceLocationReflection *const r) : DelegatingSourceLocationReflection(r) + { + } + + /** + * @p o1 is an AbstractDateTime and @p o2 is an AbstractDuration. + * + */ + virtual Item calculate(const Item &o1, + const Operator op, + const Item &o2, + const QExplicitlySharedDataPointer &context) const; + }; + + /** + * @short Performs arithmetics between two AbstractDateTime values. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class AbstractDateTimeMathematician : public AtomicMathematician + { + public: + virtual Item calculate(const Item &o1, + const Operator op, + const Item &o2, + const QExplicitlySharedDataPointer &context) const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qatomicstring.cpp b/src/xmlpatterns/data/qatomicstring.cpp new file mode 100644 index 0000000..134607f --- /dev/null +++ b/src/xmlpatterns/data/qatomicstring.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" + +#include "qatomicstring_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +AtomicString::AtomicString(const QString &s) : m_value(s) +{ +} + +AtomicString::Ptr AtomicString::fromValue(const QString &value) +{ + return AtomicString::Ptr(new AtomicString(value)); +} + +bool AtomicString::evaluateEBV(const QExplicitlySharedDataPointer &) const +{ + return m_value.length() > 0; +} + +QString AtomicString::stringValue() const +{ + return m_value; +} + +ItemType::Ptr AtomicString::type() const +{ + return BuiltinTypes::xsString; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qatomicstring_p.h b/src/xmlpatterns/data/qatomicstring_p.h new file mode 100644 index 0000000..278b822 --- /dev/null +++ b/src/xmlpatterns/data/qatomicstring_p.h @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_String_H +#define Patternist_String_H + +#include + +#include "qitem_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the value instance of the @c xs:string type. + * + * + * This class was originally called String, and correspondingly the header + * file was called String.h. However, this broke building on OS X, which + * looks up file names case insensitively, and therefore found string.h. + * + * @author Frans Englich + * @ingroup Patternist_xdm + * @todo Documentation is missing/incomplete + */ + class Q_AUTOTEST_EXPORT AtomicString : public AtomicValue + { + public: + friend class CommonValues; + + typedef AtomicValue::Ptr Ptr; + + /** + * Creates an instance representing @p value. + * + * @note This function does not remove the string literal escaping allowed in XPath 2.0 + */ + static AtomicString::Ptr fromValue(const QString &value); + + static inline AtomicString::Ptr fromValue(const QUrl &value) + { + return fromValue(value.toString()); + } + + /** + * Get the Effective %Boolean Value of this string. A zero-length + * string has an effective boolean value of @c false, in all other cases @c true. + * + * @returns @c false if the contained string has a zero-length, otherwise @c true. + */ + virtual bool evaluateEBV(const QExplicitlySharedDataPointer &) const; + + /** + * The string value of a AtomicString instance is the value space. + */ + virtual QString stringValue() const; + + virtual ItemType::Ptr type() const; + + protected: + friend class StringComparator; + friend class CompareFN; + AtomicString(const QString &value); + const QString m_value; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qatomicvalue.cpp b/src/xmlpatterns/data/qatomicvalue.cpp new file mode 100644 index 0000000..a15a6b4 --- /dev/null +++ b/src/xmlpatterns/data/qatomicvalue.cpp @@ -0,0 +1,238 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qabstractdatetime_p.h" +#include "qabstractfloat_p.h" +#include "qatomicstring_p.h" +#include "qatomictype_p.h" +#include "qboolean_p.h" +#include "qbuiltintypes_p.h" +#include "qdate_p.h" +#include "qschemadatetime_p.h" +#include "qderivedinteger_p.h" +#include "qdynamiccontext_p.h" +#include "qgenericsequencetype_p.h" +#include "qhexbinary_p.h" +#include "qinteger_p.h" +#include "qpatternistlocale_p.h" +#include "qqnamevalue_p.h" +#include "qschematime_p.h" +#include "qvalidationerror_p.h" + +#include "qitem_p.h" + +QT_BEGIN_NAMESPACE + +/** + * @file + * @short Contains the implementation for AtomicValue. The definition is in qitem_p.h. + */ + +using namespace QPatternist; + +AtomicValue::~AtomicValue() +{ +} + +bool AtomicValue::evaluateEBV(const QExplicitlySharedDataPointer &context) const +{ + context->error(QtXmlPatterns::tr("A value of type %1 cannot have an " + "Effective Boolean Value.") + .arg(formatType(context->namePool(), type())), + ReportContext::FORG0006, + QSourceLocation()); + return false; /* Silence GCC warning. */ +} + +bool AtomicValue::hasError() const +{ + return false; +} + +QVariant AtomicValue::toQt(const AtomicValue *const value) +{ + Q_ASSERT_X(value, Q_FUNC_INFO, + "Internal error, a null pointer cannot be passed."); + + const ItemType::Ptr t(value->type()); + + if(BuiltinTypes::xsString->xdtTypeMatches(t) + || BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t) + || BuiltinTypes::xsAnyURI->xdtTypeMatches(t)) + return value->stringValue(); + /* Note, this occurs before the xsInteger test, since xs:unsignedLong + * is a subtype of it. */ + else if(*BuiltinTypes::xsUnsignedLong == *t) + return QVariant(value->as >()->storedValue()); + else if(BuiltinTypes::xsInteger->xdtTypeMatches(t)) + return QVariant(value->as()->toInteger()); + else if(BuiltinTypes::xsFloat->xdtTypeMatches(t) + || BuiltinTypes::xsDouble->xdtTypeMatches(t) + || BuiltinTypes::xsDecimal->xdtTypeMatches(t)) + return QVariant(value->as()->toDouble()); + /* We currently does not support xs:time. */ + else if(BuiltinTypes::xsDateTime->xdtTypeMatches(t)) + return QVariant(value->as()->toDateTime()); + else if(BuiltinTypes::xsDate->xdtTypeMatches(t)) + return QVariant(value->as()->toDateTime().toUTC().date()); + else if(BuiltinTypes::xsBoolean->xdtTypeMatches(t)) + return QVariant(value->as()->value()); + else if(BuiltinTypes::xsBase64Binary->xdtTypeMatches(t) + || BuiltinTypes::xsHexBinary->xdtTypeMatches(t)) + return QVariant(value->as()->asByteArray()); + else if(BuiltinTypes::xsQName->xdtTypeMatches(t)) + return QVariant::fromValue(value->as()->qName()); + else + { + /* A type we don't support in Qt. Includes xs:time currently. */ + return QVariant(); + } +} + +Item AtomicValue::toXDM(const QVariant &value) +{ + Q_ASSERT_X(value.isValid(), Q_FUNC_INFO, + "QVariants sent to Patternist must be valid."); + + switch(value.userType()) + { + case QVariant::Char: + /* Fallthrough. A single codepoint is a string in XQuery. */ + case QVariant::String: + return AtomicString::fromValue(value.toString()); + case QVariant::Url: + { + /* QUrl doesn't follow the spec properly, so we + * have to let it be an xs:string. Calling QVariant::toString() + * on a QVariant that contains a QUrl returns, surprisingly, + * an empty string. */ + return AtomicString::fromValue(value.toUrl().toString()); + } + case QVariant::ByteArray: + return HexBinary::fromValue(value.toByteArray()); + case QVariant::Int: + /* Fallthrough. */ + case QVariant::LongLong: + /* Fallthrough. */ + case QVariant::UInt: + return Integer::fromValue(value.toLongLong()); + case QVariant::ULongLong: + return DerivedInteger::fromValueUnchecked(value.toULongLong()); + case QVariant::Bool: + return Boolean::fromValue(value.toBool()); + case QVariant::Time: + return SchemaTime::fromDateTime(value.toDateTime()); + case QVariant::Date: + return Date::fromDateTime(QDateTime(value.toDate(), QTime(), Qt::UTC)); + case QVariant::DateTime: + return DateTime::fromDateTime(value.toDateTime()); + case QMetaType::Float: + return Item(Double::fromValue(value.toFloat())); + case QVariant::Double: + return Item(Double::fromValue(value.toDouble())); + default: + { + if (value.userType() == qMetaTypeId()) + { + return Item(Float::fromValue(value.value())); + } + else { + Q_ASSERT_X(false, + Q_FUNC_INFO, + qPrintable(QString::fromLatin1( + "QVariants of type %1 are not supported in " + "Patternist, see the documentation") + .arg(QLatin1String(value.typeName())))); + return AtomicValue::Ptr(); + } + } + } +} + +ItemType::Ptr AtomicValue::qtToXDMType(const QXmlItem &item) +{ + Q_ASSERT(!item.isNull()); + + if(item.isNull()) + return ItemType::Ptr(); + + if(item.isNode()) + return BuiltinTypes::node; + + Q_ASSERT(item.isAtomicValue()); + const QVariant v(item.toAtomicValue()); + + switch(int(v.type())) + { + case QVariant::Char: + /* Fallthrough. */ + case QVariant::String: + /* Fallthrough. */ + case QVariant::Url: + return BuiltinTypes::xsString; + case QVariant::Bool: + return BuiltinTypes::xsBoolean; + case QVariant::ByteArray: + return BuiltinTypes::xsBase64Binary; + case QVariant::Int: + /* Fallthrough. */ + case QVariant::LongLong: + return BuiltinTypes::xsInteger; + case QVariant::ULongLong: + return BuiltinTypes::xsUnsignedLong; + case QVariant::Date: + return BuiltinTypes::xsDate; + case QVariant::DateTime: + /* Fallthrough. */ + case QVariant::Time: + return BuiltinTypes::xsDateTime; + case QMetaType::Float: + return BuiltinTypes::xsFloat; + case QVariant::Double: + return BuiltinTypes::xsDouble; + default: + return ItemType::Ptr(); + } +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qbase64binary.cpp b/src/xmlpatterns/data/qbase64binary.cpp new file mode 100644 index 0000000..42c6cb9 --- /dev/null +++ b/src/xmlpatterns/data/qbase64binary.cpp @@ -0,0 +1,216 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include "qbuiltintypes_p.h" +#include "qvalidationerror_p.h" + +#include "qbase64binary_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Base64Binary::Base64Binary(const QByteArray &val) : m_value(val) +{ +} + +const char Base64Binary::Base64DecMap[128] = +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3F, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, + 0x3C, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, + 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, + 0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +void Base64Binary::base64Decode(const QByteArray &in, QByteArray &out, bool &ok) +{ + out.resize(0); + + if(in.isEmpty()) + { + ok = false; + return; + } + + ok = true; + int len = in.size(), tail = len; + const char *const data = in.data(); + unsigned int eqCount = 0; + + // Find the tail end of the actual encoded data even if + // there is/are trailing CR and/or LF. + while(data[tail - 1] == '=') + { + --tail; + if(data[tail] != '=') + len = tail; + else + ++eqCount; + } + + if(eqCount > 2) + { + ok = false; + return; + } + + unsigned int outIdx = 0; + const int count = len; // We modify len below + out.resize((count)); + + for(int idx = 0; idx < count; ++idx) + { + const unsigned char ch = data[idx]; + if((ch > 47 && ch < 58) || + (ch > 64 && ch < 91) || + (ch > 96 && ch < 123) || + ch == '+' || + ch == '/') + { + out[outIdx++] = Base64DecMap[ch]; + } + else if(ch == '=') + { + if((idx + 1) == count || data[idx + 1] == '=') + { + out[++outIdx] = Base64DecMap[ch]; + continue; + } + + ok = false; + return; + } + else if(ch == ' ') + { + /* One space is ok, and the previously applied whitespace facet(not implemented + * at this time of writing) have ensured it's only one space, so we assume that. */ + --tail; + --len; + continue; + } + else + { + ok = false; + return; + } + } + + if(outIdx % 4 != 0) + { + ok = false; + return; + } + + out.resize(len); + + // 4-byte to 3-byte conversion + len = (tail > (len / 4)) ? tail - (len / 4) : 0; + int sidx = 0, didx = 0; + if(len > 1) + { + while(didx < len - 2) + { + out[didx] =(((out[sidx] << 2) & 255) | ((out[sidx + 1] >> 4) & 003)); + out[didx + 1] =(((out[sidx + 1] << 4) & 255) | ((out[sidx + 2] >> 2) & 017)); + out[didx + 2] =(((out[sidx + 2] << 6) & 255) | (out[sidx + 3] & 077)); + sidx += 4; + didx += 3; + } + } + + if(didx < len) + out[didx] =(((out[sidx] << 2) & 255) | ((out[sidx + 1] >> 4) & 003)); + + if(++didx < len) + out[didx] =(((out[sidx + 1] << 4) & 255) | ((out[sidx + 2] >> 2) & 017)); + + // Resize the output buffer + if(len == 0 || len < out.size()) + out.resize(len); +} + +AtomicValue::Ptr Base64Binary::fromLexical(const QString &str) +{ + const QString simple(str.simplified()); + if(simple.isEmpty()) + return AtomicValue::Ptr(new Base64Binary(QByteArray())); + + bool ok = false; + QByteArray result; + base64Decode(simple.toUtf8(), result, ok); + + if(ok) + return AtomicValue::Ptr(new Base64Binary(result)); + else + return ValidationError::createError(); +} + +Base64Binary::Ptr Base64Binary::fromValue(const QByteArray &data) +{ + return Base64Binary::Ptr(new Base64Binary(data)); +} + +QString Base64Binary::stringValue() const +{ + return QString::fromLatin1(m_value.toBase64().constData()); +} + +ItemType::Ptr Base64Binary::type() const +{ + return BuiltinTypes::xsBase64Binary; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qbase64binary_p.h b/src/xmlpatterns/data/qbase64binary_p.h new file mode 100644 index 0000000..f408fcd --- /dev/null +++ b/src/xmlpatterns/data/qbase64binary_p.h @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_Base64Binary_H +#define Patternist_Base64Binary_H + +#include "qitem_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Implements the value instance of the @c xs:base64Binary type. + * + * @author Frans Englich + * @ingroup Patternist_xdm + */ + class Base64Binary : public AtomicValue + { + public: + friend class CommonValues; + + typedef AtomicValue::Ptr Ptr; + + /** + * Creates an instance representing @p value. + */ + static AtomicValue::Ptr fromLexical(const QString &value); + + static Base64Binary::Ptr fromValue(const QByteArray &data); + + virtual QString stringValue() const; + virtual ItemType::Ptr type() const; + inline const QByteArray &asByteArray() const + { + return m_value; + } + + protected: + Base64Binary(const QByteArray &val); + + const QByteArray m_value; + + private: + /** + * @short Assumes @p in is a lexical representation of @c xs:base64Binary, and + * converts it to the binary data set in @p out. + * + * If @p instr is invalid Base64 content, @p ok is set to + * false, and the returned QByteArray has an undefined value. + * + * We cannot use QByteArray::fromBase64() because it doesn't do the + * necessary validation that we need to properly implement W3C XML + * Schema's xs:base64Binary type. + */ + static void base64Decode(const QByteArray &in, QByteArray &out, bool &ok); + + static const char Base64DecMap[128]; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qboolean.cpp b/src/xmlpatterns/data/qboolean.cpp new file mode 100644 index 0000000..2f22cb3 --- /dev/null +++ b/src/xmlpatterns/data/qboolean.cpp @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qatomictype_p.h" +#include "qbuiltintypes_p.h" +#include "qcommonvalues_p.h" +#include "qdynamiccontext_p.h" +#include "qpatternistlocale_p.h" +#include "qvalidationerror_p.h" + +#include "qboolean_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +bool Boolean::evaluateEBV(const Item::Iterator::Ptr &it, + const QExplicitlySharedDataPointer &context) +{ + return evaluateEBV(it->next(), it, context); +} + +bool Boolean::evaluateEBV(const Item &first, + const Item::Iterator::Ptr &it, + const QExplicitlySharedDataPointer &context) +{ + Q_ASSERT(it); + Q_ASSERT(context); + + if(!first) + return false; + else if(first.isNode()) + return true; + + const Item second(it->next()); + + if(second) + { + Q_ASSERT(context); + context->error(QtXmlPatterns::tr("Effective Boolean Value cannot be calculated for a sequence " + "containing two or more atomic values."), + ReportContext::FORG0006, + QSourceLocation()); + return false; + } + else + return first.as()->evaluateEBV(context); +} + +bool Boolean::evaluateEBV(const Item &item, + const QExplicitlySharedDataPointer &context) +{ + if(!item) + return false; + else if(item.isNode()) + return true; + else + return item.as()->evaluateEBV(context); +} + +Boolean::Boolean(const bool value) : m_value(value) +{ +} + +QString Boolean::stringValue() const +{ + return m_value + ? CommonValues::TrueString->stringValue() + : CommonValues::FalseString->stringValue(); +} + +bool Boolean::evaluateEBV(const QExplicitlySharedDataPointer &) const +{ + return m_value; +} + +Boolean::Ptr Boolean::fromValue(const bool value) +{ + return value ? CommonValues::BooleanTrue : CommonValues::BooleanFalse; +} + +AtomicValue::Ptr Boolean::fromLexical(const QString &lexical) +{ + const QString val(lexical.trimmed()); /* Apply the whitespace facet. */ + + if(val == QLatin1String("true") || val == QChar(QLatin1Char('1'))) + return CommonValues::BooleanTrue; + else if(val == QLatin1String("false") || val == QChar(QLatin1Char('0'))) + return CommonValues::BooleanFalse; + else + return ValidationError::createError(); +} + +ItemType::Ptr Boolean::type() const +{ + return BuiltinTypes::xsBoolean; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qboolean_p.h b/src/xmlpatterns/data/qboolean_p.h new file mode 100644 index 0000000..da69e8b --- /dev/null +++ b/src/xmlpatterns/data/qboolean_p.h @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_Boolean_H +#define Patternist_Boolean_H + +#include "qitem_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the value instance of the @c xs:boolean type. + * + * @author Frans Englich + * @ingroup Patternist_xdm + */ + class Q_AUTOTEST_EXPORT Boolean : public AtomicValue + { + public: + typedef AtomicValue::Ptr Ptr; + + /** + * @returns the boolean value this Boolean represents + */ + static bool evaluateEBV(const Item::Iterator::Ptr &e, + const QExplicitlySharedDataPointer &); + + static bool evaluateEBV(const Item &first, + const Item::Iterator::Ptr &e, + const QExplicitlySharedDataPointer &); + + static bool evaluateEBV(const Item &item, + const QExplicitlySharedDataPointer &context); + + virtual QString stringValue() const; + + /** + * @returns a Boolean object instantiating @p value. Use True() or False() + * if you already know what value you need. + */ + static Boolean::Ptr fromValue(const bool value); + + /** + * Creates a boolean value from a lexical representation. "true" and "1" + * becomes @c true, while "false" and "0" becomes @c false. + */ + static AtomicValue::Ptr fromLexical(const QString &val); + + /** + * Get the Effective %Boolean Value of this boolean value. For xs:boolean, this + * is simply the value. + */ + virtual bool evaluateEBV(const QExplicitlySharedDataPointer &) const; + + virtual ItemType::Ptr type() const; + + inline bool value() const + { + return m_value; + } + + protected: + friend class CommonValues; + Boolean(const bool value); + + private: + const bool m_value; + }; +} + +QT_END_NAMESPACE +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qcommonvalues.cpp b/src/xmlpatterns/data/qcommonvalues.cpp new file mode 100644 index 0000000..88beeea --- /dev/null +++ b/src/xmlpatterns/data/qcommonvalues.cpp @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qabstractfloat_p.h" +#include "qanyuri_p.h" +#include "qboolean_p.h" +#include "qdecimal_p.h" +#include "qinteger_p.h" +#include "qatomicstring_p.h" +#include "quntypedatomic_p.h" + +#include "qcommonvalues_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +// STATIC DATA +const AtomicString::Ptr CommonValues::EmptyString + (new AtomicString(QLatin1String(""))); +const AtomicString::Ptr CommonValues::TrueString + (new AtomicString(QLatin1String("true"))); +const AtomicString::Ptr CommonValues::FalseString + (new AtomicString(QLatin1String("false"))); + +const UntypedAtomic::Ptr CommonValues::UntypedAtomicTrue + (new UntypedAtomic(QLatin1String("true"))); +const UntypedAtomic::Ptr CommonValues::UntypedAtomicFalse + (new UntypedAtomic(QLatin1String("false"))); + +const AtomicValue::Ptr CommonValues::BooleanTrue + (new Boolean(true)); +const AtomicValue::Ptr CommonValues::BooleanFalse(new Boolean(false)); + +const AtomicValue::Ptr CommonValues::DoubleNaN + (Double::fromValue(std::numeric_limits::quiet_NaN())); + +const AtomicValue::Ptr CommonValues::FloatNaN + (Float::fromValue(std::numeric_limits::quiet_NaN())); + +const Item CommonValues::IntegerZero + (Integer::fromValue(0)); + +const AtomicValue::Ptr CommonValues::EmptyAnyURI + (AnyURI::fromValue(QLatin1String(""))); + +const AtomicValue::Ptr CommonValues::DoubleOne + (Double::fromValue(1)); +const AtomicValue::Ptr CommonValues::FloatOne + (Float::fromValue(1)); +const AtomicValue::Ptr CommonValues::DecimalOne + (Decimal::fromValue(1)); +const Item CommonValues::IntegerOne + (Integer::fromValue(1)); +const Item CommonValues::IntegerOneNegative + (Integer::fromValue(-1)); + +const AtomicValue::Ptr CommonValues::DoubleZero + (Double::fromValue(0)); +const AtomicValue::Ptr CommonValues::FloatZero + (Float::fromValue(0)); +const AtomicValue::Ptr CommonValues::DecimalZero + (Decimal::fromValue(0)); + +const Item::EmptyIterator::Ptr CommonValues::emptyIterator + (new Item::EmptyIterator()); + +const AtomicValue::Ptr CommonValues::NegativeInfDouble + (Double::fromValue(-std::numeric_limits::infinity())); +const AtomicValue::Ptr CommonValues::InfDouble + (Double::fromValue(std::numeric_limits::infinity())); +const AtomicValue::Ptr CommonValues::NegativeInfFloat + (Float::fromValue(-std::numeric_limits::infinity())); +const AtomicValue::Ptr CommonValues::InfFloat + (Float::fromValue(std::numeric_limits::infinity())); + +const DayTimeDuration::Ptr CommonValues::DayTimeDurationZero + (DayTimeDuration::fromSeconds(0)); +const DayTimeDuration::Ptr CommonValues::YearMonthDurationZero + (YearMonthDuration::fromComponents(true, 0, 0)); + + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qcommonvalues_p.h b/src/xmlpatterns/data/qcommonvalues_p.h new file mode 100644 index 0000000..cd3e270 --- /dev/null +++ b/src/xmlpatterns/data/qcommonvalues_p.h @@ -0,0 +1,228 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_CommonValues_H +#define Patternist_CommonValues_H + +#include "qdaytimeduration_p.h" +#include "qyearmonthduration_p.h" +#include "qemptyiterator_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short A collection of common values. + * + * @author Frans Englich + * @ingroup Patternist_xdm + * @todo Documentation is missing/incomplete + */ + class CommonValues + { + public: + /** + * An empty, zero-length string. + * + * @note It is not @c null, but empty. + */ + static const AtomicValue::Ptr EmptyString; + + /** + * The string "true", the lexical representation of + * @c xs:boolean's value @c true. + */ + static const AtomicValue::Ptr TrueString; + + /** + * The string "false", the lexical representation of + * @c xs:boolean's value @c false. + */ + static const AtomicValue::Ptr UntypedAtomicFalse; + + /** + * The string "true", the lexical representation of + * @c xs:boolean's value @c true. + */ + static const AtomicValue::Ptr UntypedAtomicTrue; + + /** + * The string "false", the lexical representation of + * @c xs:boolean's value @c false. + */ + static const AtomicValue::Ptr FalseString; + + /** + * @returns a Boolean instance carrying the boolean value @c true. + * Use this value instead of Boolean::fromValue() if you + * know what boolean value you need. + */ + static const AtomicValue::Ptr BooleanTrue; + + /** + * @returns a Boolean instance carrying the boolean value @c true. + * Use this value instead of Boolean::fromValue() if you + * know what boolean value you need. + */ + static const AtomicValue::Ptr BooleanFalse; + + /** + * Not-a-Numeric typed as @c xs:double. + */ + static const AtomicValue::Ptr DoubleNaN; + + /** + * Not-a-Number typed as @c xs:float, xs:float("NaN"). + */ + static const AtomicValue::Ptr FloatNaN; + + /** + * Zero(0) typed as @c xs:integer, xs:integer("0"). + */ + static const Item IntegerZero; + + /** + * An empty, "", @c xs:anyURI. + */ + static const AtomicValue::Ptr EmptyAnyURI; + + /** + * The empty sequence. + */ + static const EmptyIterator::Ptr emptyIterator; + + /** + * xs:float("-INF") + */ + static const AtomicValue::Ptr NegativeInfFloat; + + /** + * xs:float("INF") + */ + static const AtomicValue::Ptr InfFloat; + + /** + * xs:double("-INF") + */ + static const AtomicValue::Ptr NegativeInfDouble; + + /** + * xs:double("INF") + */ + static const AtomicValue::Ptr InfDouble; + + /** + * xs:float("1") + */ + static const AtomicValue::Ptr FloatOne; + /** + * xs:double("1") + */ + static const AtomicValue::Ptr DoubleOne; + /** + * xs:decimal("1") + */ + static const AtomicValue::Ptr DecimalOne; + + /** + * xs:integer("1") + */ + static const Item IntegerOne; + + /** + * xs:integer("-1") + */ + static const Item IntegerOneNegative; + + /** + * xs:double("0") + */ + static const AtomicValue::Ptr DoubleZero; + + /** + * xs:float("0") + */ + static const AtomicValue::Ptr FloatZero; + /** + * xs:integer("0") + */ + static const AtomicValue::Ptr DecimalZero; + + /** + * The @c xs:dayTimeDuration value PT0S + */ + static const DayTimeDuration::Ptr DayTimeDurationZero; + + /** + * The @c xs:yearMonthDuration value P0M + */ + static const DayTimeDuration::Ptr YearMonthDurationZero; + + private: + /** + * The constructor is private because this class is not meant to be instantiated, + * but should only be used via its static const members. + */ + inline CommonValues(); + + Q_DISABLE_COPY(CommonValues) + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qcomparisonfactory.cpp b/src/xmlpatterns/data/qcomparisonfactory.cpp new file mode 100644 index 0000000..66d72af --- /dev/null +++ b/src/xmlpatterns/data/qcomparisonfactory.cpp @@ -0,0 +1,154 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qatomiccomparators_p.h" +#include "qatomicstring_p.h" +#include "qcomparisonplatform_p.h" +#include "qvaluefactory_p.h" + +#include "qcomparisonfactory_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +/** + * @short Helper class for ComparisonFactory::fromLexical() which exposes + * CastingPlatform appropriately. + * + * @relates ComparisonFactory + */ +class PerformComparison : public ComparisonPlatform + , public SourceLocationReflection +{ +public: + PerformComparison(const SourceLocationReflection *const sourceLocationReflection, + const AtomicComparator::Operator op) : m_sourceReflection(sourceLocationReflection) + , m_operator(op) + { + Q_ASSERT(m_sourceReflection); + } + + bool operator()(const AtomicValue::Ptr &operand1, + const AtomicValue::Ptr &operand2, + const SchemaType::Ptr &type, + const ReportContext::Ptr &context) + { + const ItemType::Ptr asItemType((AtomicType::Ptr(type))); + + /* One area where the Query Transform world differs from the Schema + * world is that @c xs:duration is not considedered comparable, because + * it's according to Schema is partially comparable. This means + * ComparisonPlatform::fetchComparator() flags it as impossible, and + * hence we need to override that. + * + * SchemaType::wxsTypeMatches() will return true for sub-types of @c + * xs:duration as well, but that's ok since AbstractDurationComparator + * works for them too. */ + if(BuiltinTypes::xsDuration->wxsTypeMatches(type)) + prepareComparison(AtomicComparator::Ptr(new AbstractDurationComparator())); + else if (BuiltinTypes::xsGYear->wxsTypeMatches(type) || + BuiltinTypes::xsGYearMonth->wxsTypeMatches(type) || + BuiltinTypes::xsGMonth->wxsTypeMatches(type) || + BuiltinTypes::xsGMonthDay->wxsTypeMatches(type) || + BuiltinTypes::xsGDay->wxsTypeMatches(type)) + prepareComparison(AtomicComparator::Ptr(new AbstractDateTimeComparator())); + else + prepareComparison(fetchComparator(asItemType, asItemType, context)); + + return flexibleCompare(operand1, operand2, context); + } + + const SourceLocationReflection *actualReflection() const + { + return m_sourceReflection; + } + + AtomicComparator::Operator operatorID() const + { + return m_operator; + } + +private: + const SourceLocationReflection *const m_sourceReflection; + const AtomicComparator::Operator m_operator; +}; + +bool ComparisonFactory::compare(const AtomicValue::Ptr &operand1, + const AtomicComparator::Operator op, + const AtomicValue::Ptr &operand2, + const SchemaType::Ptr &type, + const ReportContext::Ptr &context, + const SourceLocationReflection *const sourceLocationReflection) +{ + Q_ASSERT(operand1); + Q_ASSERT(operand2); + Q_ASSERT(context); + Q_ASSERT(sourceLocationReflection); + Q_ASSERT(type); + Q_ASSERT_X(type->category() == SchemaType::SimpleTypeAtomic, Q_FUNC_INFO, + "We can only compare atomic values."); + + return PerformComparison(sourceLocationReflection, op)(operand1, operand2, type, context); +} + +bool ComparisonFactory::constructAndCompare(const DerivedString::Ptr &operand1, + const AtomicComparator::Operator op, + const DerivedString::Ptr &operand2, + const SchemaType::Ptr &type, + const ReportContext::Ptr &context, + const SourceLocationReflection *const sourceLocationReflection) +{ + Q_ASSERT(operand1); + Q_ASSERT(operand2); + Q_ASSERT(context); + Q_ASSERT(sourceLocationReflection); + Q_ASSERT(type); + Q_ASSERT_X(type->category() == SchemaType::SimpleTypeAtomic, Q_FUNC_INFO, + "We can only compare atomic values."); + + const AtomicValue::Ptr value1 = ValueFactory::fromLexical(operand1->stringValue(), type, context, sourceLocationReflection); + const AtomicValue::Ptr value2 = ValueFactory::fromLexical(operand2->stringValue(), type, context, sourceLocationReflection); + + return compare(value1, op, value2, type, context, sourceLocationReflection); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qcomparisonfactory_p.h b/src/xmlpatterns/data/qcomparisonfactory_p.h new file mode 100644 index 0000000..61f65b1 --- /dev/null +++ b/src/xmlpatterns/data/qcomparisonfactory_p.h @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ComparisonFactory_H +#define Patternist_ComparisonFactory_H + +#include "qatomiccomparator_p.h" +#include "qderivedstring_p.h" +#include "qitem_p.h" +#include "qreportcontext_p.h" +#include "qschematype_p.h" + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Provides compare(), which is a high-level helper function for + * comparing atomic values. + * + * This class wraps the helper class ComparisonPlatform with a more specific, + * high-level API. + * + * @see ComparisonPlatform + * @author Frans Englich + * @ingroup Patternist_schema + */ + class ComparisonFactory + { + public: + /** + * @short Returns the result of evaluating operator @p op applied to the atomic + * values @p operand1 and @p operand2. + * + * The caller guarantees that both values are of type @p type. + * + * ComparisonFactory does not take ownership of @p sourceLocationReflection. + */ + static bool compare(const AtomicValue::Ptr &operand1, + const AtomicComparator::Operator op, + const AtomicValue::Ptr &operand2, + const SchemaType::Ptr &type, + const ReportContext::Ptr &context, + const SourceLocationReflection *const sourceLocationReflection); + + /** + * @short Returns the result of evaluating operator @p op applied to the atomic + * values @p operand1 and @p operand2. + * + * In opposite to compare() it converts the operands from string type + * to @p type and compares these constructed types. + * + * The caller guarantees that both values are of type @p type. + * + * ComparisonFactory does not take ownership of @p sourceLocationReflection. + */ + static bool constructAndCompare(const DerivedString::Ptr &operand1, + const AtomicComparator::Operator op, + const DerivedString::Ptr &operand2, + const SchemaType::Ptr &type, + const ReportContext::Ptr &context, + const SourceLocationReflection *const sourceLocationReflection); + + private: + Q_DISABLE_COPY(ComparisonFactory) + }; +} + +QT_END_NAMESPACE +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qdate.cpp b/src/xmlpatterns/data/qdate.cpp new file mode 100644 index 0000000..cc0842b --- /dev/null +++ b/src/xmlpatterns/data/qdate.cpp @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" +#include "qitem_p.h" + +#include "qdate_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Date::Date(const QDateTime &dateTime) : AbstractDateTime(dateTime) +{ +} + +Date::Ptr Date::fromLexical(const QString &lexical) +{ + static const CaptureTable captureTable( // STATIC DATA + /* The extra paranthesis is a build fix for GCC 3.3. */ + (QRegExp(QLatin1String( + "^\\s*" /* Any preceding whitespace. */ + "(-?)" /* Any preceding minus. */ + "(\\d{4,})" /* The year part. */ + "-" /* Delimiter. */ + "(\\d{2})" /* The month part. */ + "-" /* Delimiter. */ + "(\\d{2})" /* The day part. */ + "(?:(\\+|-)(\\d{2}):(\\d{2})|(Z))?" /* The zone offset, "+08:24". */ + "\\s*$" /* Any terminating whitespace. */))), + /*zoneOffsetSignP*/ 5, + /*zoneOffsetHourP*/ 6, + /*zoneOffsetMinuteP*/ 7, + /*zoneOffsetUTCSymbolP*/ 8, + /*yearP*/ 2, + /*monthP*/ 3, + /*dayP*/ 4, + /*hourP*/ -1, + /*minutesP*/ -1, + /*secondsP*/ -1, + /*msecondsP*/ -1, + /*yearSign*/ 1); + + AtomicValue::Ptr err; + const QDateTime retval(create(err, lexical, captureTable)); + + return err ? err : Date::Ptr(new Date(retval)); +} + +Date::Ptr Date::fromDateTime(const QDateTime &date) +{ + /* Don't include the QTime; "reset" the time. */ + QDateTime result; + copyTimeSpec(date, result); + result.setDate(date.date()); + Q_ASSERT(date.isValid()); + + return Date::Ptr(new Date(result)); +} + +Item Date::fromValue(const QDateTime &dt) const +{ + Q_ASSERT(dt.isValid()); + return fromDateTime(dt); +} + +QString Date::stringValue() const +{ + return dateToString() + zoneOffsetToString(); +} + +ItemType::Ptr Date::type() const +{ + return BuiltinTypes::xsDate; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qdate_p.h b/src/xmlpatterns/data/qdate_p.h new file mode 100644 index 0000000..000da2e --- /dev/null +++ b/src/xmlpatterns/data/qdate_p.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_Date_H +#define Patternist_Date_H + +#include "qabstractdatetime_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the value instance of the @c xs:date type. + * + * @author Frans Englich + * @ingroup Patternist_xdm + */ + class Date : public AbstractDateTime + { + public: + typedef AtomicValue::Ptr Ptr; + + /** + * Creates an instance from the lexical representation @p string. + */ + static Date::Ptr fromLexical(const QString &string); + static Date::Ptr fromDateTime(const QDateTime &date); + + virtual ItemType::Ptr type() const; + virtual QString stringValue() const; + virtual Item fromValue(const QDateTime &dt) const; + + protected: + friend class CommonValues; + + Date(const QDateTime &dateTime); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qdaytimeduration.cpp b/src/xmlpatterns/data/qdaytimeduration.cpp new file mode 100644 index 0000000..e47144c --- /dev/null +++ b/src/xmlpatterns/data/qdaytimeduration.cpp @@ -0,0 +1,242 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qabstractdatetime_p.h" +#include "qbuiltintypes_p.h" +#include "qcommonvalues_p.h" + +#include "qdaytimeduration_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +DayTimeDuration::DayTimeDuration(const bool isPositiveP, + const DayCountProperty daysP, + const HourProperty hoursP, + const MinuteProperty minutesP, + const SecondProperty secs, + const MSecondProperty msecs) : AbstractDuration(isPositiveP), + m_days(daysP), + m_hours(hoursP), + m_minutes(minutesP), + m_seconds(secs), + m_mseconds(msecs) +{ +} + +DayTimeDuration::Ptr DayTimeDuration::fromLexical(const QString &lexical) +{ + static const CaptureTable captureTable( + /* The extra paranthesis is a build fix for GCC 3.3. */ + (QRegExp(QLatin1String( + "^\\s*" /* Any preceding whitespace. */ + "(-)?" /* Any minus sign. */ + "P" /* Delimiter. */ + "(?:(\\d+)D)?" /* Day part. */ + "(?:" /* Here starts the optional time part. */ + "(T)" /* SchemaTime delimiter. */ + "(?:(\\d+)H)?" /* Hour part. */ + "(?:(\\d+)M)?" /* Minute part. */ + "(?:(\\d+)(?:\\.(\\d+))?S)?" /* Seconds & milli seconds. */ + ")?" /* End of optional time part. */ + "\\s*$" /* Any terminating whitespace. */))), + /*yearP*/ -1, + /*monthP*/ -1, + /*dayP*/ 2, + /*tDelimiterP*/ 3, + /*hourP*/ 4, + /*minutesP*/ 5, + /*secondsP*/ 6, + /*msecondsP*/ 7); + + DayCountProperty days = 0; + HourProperty hours = 0; + MinuteProperty minutes = 0; + SecondProperty sec = 0; + MSecondProperty msec = 0; + bool isPos; + + const DayTimeDuration::Ptr err(create(captureTable, lexical, &isPos, 0, 0, &days, + &hours, &minutes, &sec, &msec)); + return err ? err : DayTimeDuration::Ptr(new DayTimeDuration(isPos, days, hours, minutes, + sec, msec)); +} + +DayTimeDuration::Ptr DayTimeDuration::fromComponents(const bool isPositive, + const DayCountProperty days, + const HourProperty hours, + const MinuteProperty minutes, + const SecondProperty seconds, + const MSecondProperty mseconds) +{ + return DayTimeDuration::Ptr(new DayTimeDuration(isPositive, + days, + hours, + minutes, + seconds, + mseconds)); +} + +DayTimeDuration::Ptr DayTimeDuration::fromSeconds(const SecondCountProperty sourceSecs, + const MSecondProperty msecs) +{ + Q_ASSERT(msecs >= 0); + const SecondCountProperty source = qAbs(sourceSecs); + const bool isPos = sourceSecs >= 0; + const SecondCountProperty secs = source % 60; + const MinuteCountProperty mins = (source / 60) % 60; + const HourCountProperty hours = source / (60 * 60) % 24; + const DayCountProperty days = source / (60 * 60) / 24; + + return DayTimeDuration::Ptr(new DayTimeDuration(isPos, days, hours, mins, secs, msecs)); +} + +QString DayTimeDuration::stringValue() const +{ + QString retval; + + if(!m_isPositive) + retval.append(QLatin1Char('-')); + + retval.append(QLatin1Char('P')); + + if(m_days) + { + retval.append(QString::number(m_days)); + retval.append(QLatin1Char('D')); + } + + if(!m_hours && !m_minutes && !m_seconds && !m_seconds) + { + if(!m_days) + return QLatin1String("PT0S"); + else + return retval; + } + + retval.append(QLatin1Char('T')); + + if(m_hours) + { + retval.append(QString::number(m_hours)); + retval.append(QLatin1Char('H')); + } + + if(m_minutes) + { + retval.append(QString::number(m_minutes)); + retval.append(QLatin1Char('M')); + } + + if(m_seconds || m_seconds) + { + retval.append(QString::number(m_seconds)); + + if(m_mseconds) + retval.append(serializeMSeconds(m_mseconds)); + + retval.append(QLatin1Char('S')); + } + else if(!m_days && !m_hours && !m_minutes) + retval.append(QLatin1String("0S")); + + return retval; +} + +AbstractDuration::Value DayTimeDuration::value() const +{ + return ((m_days * 24 * 60 * 60 * 1000) + + (m_hours * 60 * 60 * 1000) + + (m_minutes * 60 * 1000) + + (m_seconds * 1000) + + m_mseconds) * (m_isPositive ? 1 : -1); +} + +Item DayTimeDuration::fromValue(const Value val) const +{ + if(val == 0) + return toItem(CommonValues::DayTimeDurationZero); + else + return toItem(fromSeconds(val / 1000, qAbs(val) % 1000)); +} + +ItemType::Ptr DayTimeDuration::type() const +{ + return BuiltinTypes::xsDayTimeDuration; +} + +YearProperty DayTimeDuration::years() const +{ + return 0; +} + +MonthProperty DayTimeDuration::months() const +{ + return 0; +} + +DayCountProperty DayTimeDuration::days() const +{ + return m_days; +} + +HourProperty DayTimeDuration::hours() const +{ + return m_hours; +} + +MinuteProperty DayTimeDuration::minutes() const +{ + return m_minutes; +} + +SecondProperty DayTimeDuration::seconds() const +{ + return m_seconds; +} + +MSecondProperty DayTimeDuration::mseconds() const +{ + return m_mseconds; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qdaytimeduration_p.h b/src/xmlpatterns/data/qdaytimeduration_p.h new file mode 100644 index 0000000..f9eb524 --- /dev/null +++ b/src/xmlpatterns/data/qdaytimeduration_p.h @@ -0,0 +1,154 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_DayTimeDuration_H +#define Patternist_DayTimeDuration_H + +#include "qabstractduration_p.h" +#include "qitem_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the value instance of the @c xs:dayTimeDuration type. + * + * @author Frans Englich + * @ingroup Patternist_xdm + */ + class DayTimeDuration : public AbstractDuration + { + public: + + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Creates an instance from the lexical representation @p string. + */ + static DayTimeDuration::Ptr fromLexical(const QString &string); + + static DayTimeDuration::Ptr fromComponents(const bool isPositive, + const DayCountProperty days, + const HourProperty hours, + const MinuteProperty minutes, + const SecondProperty seconds, + const MSecondProperty mseconds); + /** + * Creates a DayTimeDuration that has the value expressed in seconds @p secs + * and milli seconds @p msecs. The signedness of @p secs communicates + * whether this DayTimeDuration is positive or negative. @p msecs must always + * be positive. + */ + static DayTimeDuration::Ptr fromSeconds(const SecondCountProperty secs, + const MSecondProperty msecs = 0); + + virtual ItemType::Ptr type() const; + virtual QString stringValue() const; + + /** + * @returns always 0. + */ + virtual YearProperty years() const; + + /** + * @returns always 0. + */ + virtual MonthProperty months() const; + virtual DayCountProperty days() const; + virtual HourProperty hours() const; + virtual MinuteProperty minutes() const; + virtual MSecondProperty mseconds() const; + virtual SecondProperty seconds() const; + + /** + * @returns the value of this xs:dayTimeDuration + * in milli seconds. + * @see XQuery 1.0 + * and XPath 2.0 Functions and Operators, 10.3.2.2 Calculating the value of a + * xs:dayTimeDuration from the lexical representation + */ + virtual Value value() const; + + /** + * Creates a DayTimeDuration containing the value @p val. @p val is + * expressed in milli seconds. + * + * If @p val is zero, is CommonValues::DayTimeDurationZero returned. + */ + virtual Item fromValue(const Value val) const; + + protected: + friend class CommonValues; + + DayTimeDuration(const bool isPositive, + const DayCountProperty days, + const HourProperty hours, + const MinuteProperty minutes, + const SecondProperty seconds, + const MSecondProperty mseconds); + + private: + const DayCountProperty m_days; + const HourProperty m_hours; + const MinuteProperty m_minutes; + const SecondProperty m_seconds; + const MSecondProperty m_mseconds; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qdecimal.cpp b/src/xmlpatterns/data/qdecimal.cpp new file mode 100644 index 0000000..0003a08 --- /dev/null +++ b/src/xmlpatterns/data/qdecimal.cpp @@ -0,0 +1,234 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qabstractfloat_p.h" +#include "qatomictype_p.h" +#include "qbuiltintypes_p.h" +#include "qvalidationerror_p.h" + +#include "qdecimal_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Decimal::Decimal(const xsDecimal num) : m_value(num) +{ +} + +Decimal::Ptr Decimal::fromValue(const xsDecimal num) +{ + return Decimal::Ptr(new Decimal(num)); +} + +AtomicValue::Ptr Decimal::fromLexical(const QString &strNumeric) +{ + /* QString::toDouble() handles the whitespace facet. */ + const QString strNumericTrimmed(strNumeric.trimmed()); + + /* Block these out, as QString::toDouble() supports them. */ + if(strNumericTrimmed.compare(QLatin1String("-INF"), Qt::CaseInsensitive) == 0 + || strNumericTrimmed.compare(QLatin1String("INF"), Qt::CaseInsensitive) == 0 + || strNumericTrimmed.compare(QLatin1String("+INF"), Qt::CaseInsensitive) == 0 + || strNumericTrimmed.compare(QLatin1String("nan"), Qt::CaseInsensitive) == 0 + || strNumericTrimmed.contains(QLatin1Char('e')) + || strNumericTrimmed.contains(QLatin1Char('E'))) + { + return ValidationError::createError(); + } + + bool conversionOk = false; + const xsDecimal num = strNumericTrimmed.toDouble(&conversionOk); + + if(conversionOk) + return AtomicValue::Ptr(new Decimal(num)); + else + return ValidationError::createError(); +} + +bool Decimal::evaluateEBV(const QExplicitlySharedDataPointer &) const +{ + return !Double::isEqual(m_value, 0.0); +} + +QString Decimal::stringValue() const +{ + return toString(m_value); +} + +QString Decimal::toString(const xsDecimal value) +{ + /* + * If SV is in the value space of xs:integer, that is, if there are no + * significant digits after the decimal point, then the value is converted + * from an xs:decimal to an xs:integer and the resulting xs:integer is + * converted to an xs:string using the rule above. + */ + if(Double::isEqual(::floor(value), value)) + { + /* The static_cast is identical to Integer::toInteger(). */ + return QString::number(static_cast(value)); + } + else + { + int sign; + int decimalPoint; + char *result = 0; + static_cast(qdtoa(value, 0, 0, &decimalPoint, &sign, 0, &result)); + /* If the copy constructor is used instead of QString::operator=(), + * it doesn't compile. I have no idea why. */ + const QString qret(QString::fromLatin1(result)); + delete result; + + QString valueAsString; + + if(sign) + valueAsString += QLatin1Char('-'); + + if(0 < decimalPoint) + { + valueAsString += qret.left(decimalPoint); + valueAsString += QLatin1Char('.'); + if (qret.size() <= decimalPoint) + valueAsString += QLatin1Char('0'); + else + valueAsString += qret.mid(decimalPoint); + } + else + { + valueAsString += QLatin1Char('0'); + valueAsString += QLatin1Char('.'); + + for(int d = decimalPoint; d < 0; d++) + valueAsString += QLatin1Char('0'); + + valueAsString += qret; + } + + return valueAsString; + } +} + +ItemType::Ptr Decimal::type() const +{ + return BuiltinTypes::xsDecimal; +} + +xsDouble Decimal::toDouble() const +{ + return static_cast(m_value); +} + +xsInteger Decimal::toInteger() const +{ + return static_cast(m_value); +} + +xsFloat Decimal::toFloat() const +{ + return static_cast(m_value); +} + +xsDecimal Decimal::toDecimal() const +{ + return m_value; +} + +qulonglong Decimal::toUnsignedInteger() const +{ + Q_ASSERT_X(false, Q_FUNC_INFO, + "It makes no sense to call this function, see Numeric::toUnsignedInteger()."); + return 0; +} + +Numeric::Ptr Decimal::round() const +{ + return Numeric::Ptr(new Decimal(roundFloat(m_value))); +} + +Numeric::Ptr Decimal::roundHalfToEven(const xsInteger /*scale*/) const +{ + return Numeric::Ptr(); +} + +Numeric::Ptr Decimal::floor() const +{ + return Numeric::Ptr(new Decimal(static_cast(::floor(m_value)))); +} + +Numeric::Ptr Decimal::ceiling() const +{ + return Numeric::Ptr(new Decimal(static_cast(ceil(m_value)))); +} + +Numeric::Ptr Decimal::abs() const +{ + return Numeric::Ptr(new Decimal(static_cast(fabs(m_value)))); +} + +bool Decimal::isNaN() const +{ + return false; +} + +bool Decimal::isInf() const +{ + return false; +} + +Item Decimal::toNegated() const +{ + if(AbstractFloat::isEqual(m_value, 0.0)) + return fromValue(0).data(); + else + return fromValue(-m_value).data(); +} + +bool Decimal::isSigned() const +{ + Q_ASSERT_X(false, Q_FUNC_INFO, + "It makes no sense to call this function, see Numeric::isSigned()."); + return false; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qdecimal_p.h b/src/xmlpatterns/data/qdecimal_p.h new file mode 100644 index 0000000..9b9a804 --- /dev/null +++ b/src/xmlpatterns/data/qdecimal_p.h @@ -0,0 +1,156 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_Decimal_H +#define Patternist_Decimal_H + +#include "qschemanumeric_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +/** + * Defined in QtCore's qlocale.cpp. + */ +Q_CORE_EXPORT char *qdtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp); + +namespace QPatternist +{ + + /** + * @short Implements the value instance of the @c xs:decimal type. + * + * @author Frans Englich + * @ingroup Patternist_xdm + * @todo Documentation is missing/incomplete + */ + class Decimal : public Numeric + { + public: + + static Decimal::Ptr fromValue(const xsDecimal num); + + /** + * Creates a Decimal from the lexical representation of @c xs:decimal stored in + * @p strNumeric. + * + * A possible optimization is to create an Integer if the string ends + * with ".0". But this is not conformant. For example, the user writes N.0 + * which according to the specification is an xs:decimal, but where the + * expression is, is an xs:integer is required. That would pass with + * such an optimization. + */ + static AtomicValue::Ptr fromLexical(const QString &strNumeric); + + /** + * Gets the Effective %Boolean Value of this number. + * + * @returns @c false if the number is 0 or @c NaN, otherwise @c true. + */ + bool evaluateEBV(const QExplicitlySharedDataPointer &) const; + + virtual QString stringValue() const; + + /** + * @returns always BuiltinTypes::xsDecimal + */ + virtual ItemType::Ptr type() const; + + virtual xsDouble toDouble() const; + virtual xsInteger toInteger() const; + virtual xsFloat toFloat() const; + virtual xsDecimal toDecimal() const; + virtual qulonglong toUnsignedInteger() const; + + virtual Numeric::Ptr round() const; + virtual Numeric::Ptr roundHalfToEven(const xsInteger scale) const; + virtual Numeric::Ptr floor() const; + virtual Numeric::Ptr ceiling() const; + virtual Numeric::Ptr abs() const; + + /** + * @returns always @c false, xs:decimal doesn't have + * not-a-number in its value space. + */ + virtual bool isNaN() const; + + /** + * @returns always @c false, xs:decimal doesn't have + * infinity in its value space. + */ + virtual bool isInf() const; + + virtual Item toNegated() const; + + /** + * Converts @p value into a canonical string representation for @c xs:decimal. This + * function is used internally by various classes. Users probably wants to call + * stringValue() which in turn calls this function. + */ + static QString toString(const xsDecimal value); + + virtual bool isSigned() const; + + protected: + + Decimal(const xsDecimal num); + + private: + const xsDecimal m_value; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qderivedinteger_p.h b/src/xmlpatterns/data/qderivedinteger_p.h new file mode 100644 index 0000000..0ef5b51 --- /dev/null +++ b/src/xmlpatterns/data/qderivedinteger_p.h @@ -0,0 +1,624 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_DerivedInteger_H +#define Patternist_DerivedInteger_H + +#include "qbuiltintypes_p.h" +#include "qinteger_p.h" +#include "qpatternistlocale_p.h" +#include "qvalidationerror_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @relates DerivedInteger + */ + enum DerivedIntegerLimitsUsage + { + None = 1, + LimitUpwards = 2, + LimitDownwards = 4, + LimitBoth = LimitUpwards | LimitDownwards + }; + + enum + { + IgnorableSignedValue = 0, + IgnorableUnsignedValue = 0 + }; + + template class DerivedInteger; + + template class DerivedIntegerDetails; + + template<> + class DerivedIntegerDetails + { + private: + friend class DerivedInteger; + typedef qint8 StorageType; + typedef xsInteger TemporaryStorageType; + static const StorageType maxInclusive = 127; + static const StorageType minInclusive = -128; + static const DerivedIntegerLimitsUsage limitsUsage = LimitBoth; + + /** + * Disable the default constructor. + */ + DerivedIntegerDetails() {} + + Q_DISABLE_COPY(DerivedIntegerDetails) + }; + + template<> + class DerivedIntegerDetails + { + private: + friend class DerivedInteger; + typedef qint32 StorageType; + typedef xsInteger TemporaryStorageType; + static const StorageType maxInclusive = Q_INT64_C(2147483647); + static const StorageType minInclusive = Q_INT64_C(-2147483648); + static const DerivedIntegerLimitsUsage limitsUsage = LimitBoth; + + /** + * Disable the default constructor. + */ + DerivedIntegerDetails() {} + + Q_DISABLE_COPY(DerivedIntegerDetails) + }; + + template<> + class DerivedIntegerDetails + { + private: + friend class DerivedInteger; + typedef qint64 StorageType; + typedef StorageType TemporaryStorageType; + static const StorageType maxInclusive = Q_INT64_C(9223372036854775807); + + /** + * This messy arithmetic expression ensures that we don't get a warning + * on neither GCC nor MSVC. + */ + static const StorageType minInclusive = -(Q_INT64_C(9223372036854775807)) - 1; + + static const DerivedIntegerLimitsUsage limitsUsage = LimitBoth; + + /** + * Disable the default constructor. + */ + DerivedIntegerDetails() {} + + Q_DISABLE_COPY(DerivedIntegerDetails) + }; + + template<> + class DerivedIntegerDetails + { + private: + friend class DerivedInteger; + typedef xsInteger StorageType; + typedef StorageType TemporaryStorageType; + static const StorageType maxInclusive = -1; + static const StorageType minInclusive = IgnorableSignedValue; + static const DerivedIntegerLimitsUsage limitsUsage = LimitUpwards; + + /** + * Disable the default constructor. + */ + DerivedIntegerDetails() {} + + Q_DISABLE_COPY(DerivedIntegerDetails) + }; + + template<> + class DerivedIntegerDetails + { + private: + friend class DerivedInteger; + typedef xsInteger StorageType; + typedef StorageType TemporaryStorageType; + static const StorageType maxInclusive = IgnorableSignedValue; + static const StorageType minInclusive = 0; + static const DerivedIntegerLimitsUsage limitsUsage = LimitDownwards; + + /** + * Disable the default constructor. + */ + DerivedIntegerDetails() {} + + Q_DISABLE_COPY(DerivedIntegerDetails) + }; + + template<> + class DerivedIntegerDetails + { + private: + friend class DerivedInteger; + typedef xsInteger StorageType; + typedef StorageType TemporaryStorageType; + static const StorageType maxInclusive = 0; + static const StorageType minInclusive = IgnorableSignedValue; + static const DerivedIntegerLimitsUsage limitsUsage = LimitUpwards; + + /** + * Disable the default constructor. + */ + DerivedIntegerDetails() {} + + Q_DISABLE_COPY(DerivedIntegerDetails) + }; + + template<> + class DerivedIntegerDetails + { + private: + friend class DerivedInteger; + typedef xsInteger StorageType; + typedef StorageType TemporaryStorageType; + static const StorageType maxInclusive = IgnorableSignedValue; + static const StorageType minInclusive = 1; + static const DerivedIntegerLimitsUsage limitsUsage = LimitDownwards; + + /** + * Disable the default constructor. + */ + DerivedIntegerDetails() {} + + Q_DISABLE_COPY(DerivedIntegerDetails) + }; + + template<> + class DerivedIntegerDetails + { + private: + friend class DerivedInteger; + typedef qint16 StorageType; + typedef xsInteger TemporaryStorageType; + static const StorageType maxInclusive = 32767; + static const StorageType minInclusive = -32768; + static const DerivedIntegerLimitsUsage limitsUsage = LimitBoth; + + /** + * Disable the default constructor. + */ + DerivedIntegerDetails() {} + + Q_DISABLE_COPY(DerivedIntegerDetails) + }; + + template<> + class DerivedIntegerDetails + { + private: + friend class DerivedInteger; + typedef quint8 StorageType; + typedef qint64 TemporaryStorageType; + static const StorageType maxInclusive = 255; + static const StorageType minInclusive = 0; + static const DerivedIntegerLimitsUsage limitsUsage = LimitBoth; + + /** + * Disable the default constructor. + */ + DerivedIntegerDetails() {} + + Q_DISABLE_COPY(DerivedIntegerDetails) + }; + + template<> + class DerivedIntegerDetails + { + private: + friend class DerivedInteger; + typedef quint32 StorageType; + typedef qint64 TemporaryStorageType; + static const StorageType maxInclusive = Q_UINT64_C(4294967295); + static const StorageType minInclusive = 0; + static const DerivedIntegerLimitsUsage limitsUsage = LimitBoth; + + /** + * Disable the default constructor. + */ + DerivedIntegerDetails() {} + + Q_DISABLE_COPY(DerivedIntegerDetails) + }; + + template<> + class DerivedIntegerDetails + { + private: + friend class DerivedInteger; + typedef quint64 StorageType; + typedef StorageType TemporaryStorageType; + static const StorageType maxInclusive = Q_UINT64_C(18446744073709551615); + static const StorageType minInclusive = 0; + static const DerivedIntegerLimitsUsage limitsUsage = LimitBoth; + + /** + * Disable the default constructor. + */ + DerivedIntegerDetails() {} + + Q_DISABLE_COPY(DerivedIntegerDetails) + }; + + template<> + class DerivedIntegerDetails + { + private: + friend class DerivedInteger; + typedef quint16 StorageType; + typedef qint64 TemporaryStorageType; + static const StorageType maxInclusive = 65535; + static const StorageType minInclusive = 0; + static const DerivedIntegerLimitsUsage limitsUsage = LimitBoth; + + /** + * Disable the default constructor. + */ + DerivedIntegerDetails() {} + + Q_DISABLE_COPY(DerivedIntegerDetails) + }; + + /** + * @short Represents instances of derived @c xs:integer types, such as @c + * xs:byte. + * + * @author Frans Englich + * @ingroup Patternist_xdm + */ + template + class DerivedInteger : public Numeric + { + private: + typedef typename DerivedIntegerDetails::StorageType StorageType; + typedef typename DerivedIntegerDetails::TemporaryStorageType TemporaryStorageType; + + static const StorageType maxInclusive = DerivedIntegerDetails::maxInclusive; + static const StorageType minInclusive = DerivedIntegerDetails::minInclusive; + static const DerivedIntegerLimitsUsage limitsUsage = DerivedIntegerDetails::limitsUsage; + + const StorageType m_value; + + inline DerivedInteger(const StorageType num) : m_value(num) + { + } + + /** + * By refactoring out the simple comparison below into a template + * function, we avoid the warning "warning: comparison of unsigned expression < 0 is always false" with gcc + * when the class is instantiated with TypeUnsignedLong. The warning is + * a false positive since we check wehther LimitUpwards is set before + * instantiating. + * + * This template function exists for no other reason. */ + template + static bool lessThan(const A &a, const B &b) + { + return a < b; + } + + /** + * This function exists for the same reason that lessThan() do. + */ + template + static bool largerOrEqual(const A &a, const B &b) + { + return qint64(a) >= b; + } + + public: + + static ItemType::Ptr itemType() + { + switch(DerivedType) + { + case TypeByte: return BuiltinTypes::xsByte; + case TypeInt: return BuiltinTypes::xsInt; + case TypeLong: return BuiltinTypes::xsLong; + case TypeNegativeInteger: return BuiltinTypes::xsNegativeInteger; + case TypeNonNegativeInteger: return BuiltinTypes::xsNonNegativeInteger; + case TypeNonPositiveInteger: return BuiltinTypes::xsNonPositiveInteger; + case TypePositiveInteger: return BuiltinTypes::xsPositiveInteger; + case TypeShort: return BuiltinTypes::xsShort; + case TypeUnsignedByte: return BuiltinTypes::xsUnsignedByte; + case TypeUnsignedInt: return BuiltinTypes::xsUnsignedInt; + case TypeUnsignedLong: return BuiltinTypes::xsUnsignedLong; + case TypeUnsignedShort: return BuiltinTypes::xsUnsignedShort; + } + + Q_ASSERT(false); + return ItemType::Ptr(); + } + + static AtomicValue::Ptr fromValue(const NamePool::Ptr &np, const TemporaryStorageType num) + { + /* If we use minInclusive when calling lessThan(), we for some + * reason get a linker error with GCC. Using this temporary + * variable solves it. */ + const StorageType minimum = minInclusive; + + if((limitsUsage & LimitUpwards) && + num > maxInclusive) + { + return ValidationError::createError(QtXmlPatterns::tr( + "Value %1 of type %2 exceeds maximum (%3).") + .arg(QPatternist::formatData(static_cast(num))) + .arg(formatType(np, itemType())) + .arg(QPatternist::formatData(static_cast(maxInclusive)))); + } + else if((limitsUsage & LimitDownwards) && + lessThan(num, minimum)) + { + return ValidationError::createError(QtXmlPatterns::tr( + "Value %1 of type %2 is below minimum (%3).") + .arg(QPatternist::formatData(static_cast(num))) + .arg(formatType(np, itemType())) + .arg(QPatternist::formatData(static_cast(minInclusive)))); + } + else + return AtomicValue::Ptr(new DerivedInteger(num)); + } + + static AtomicValue::Ptr fromValueUnchecked(const TemporaryStorageType num) + { + return AtomicValue::Ptr(new DerivedInteger(num)); + } + + /** + * Constructs an instance from the lexical + * representation @p strNumeric. + */ + static AtomicValue::Ptr fromLexical(const NamePool::Ptr &np, const QString &strNumeric) + { + bool conversionOk = false; + TemporaryStorageType num; + + /* Depending on the type, we need to call different conversion + * functions on QString. */ + switch(DerivedType) + { + case TypeUnsignedLong: + { + /* Qt decides to flag '-' as invalid, so remove it before. */ + if(strNumeric.contains(QLatin1Char('-'))) + { + num = QString(strNumeric).remove(QLatin1Char('-')).toULongLong(&conversionOk); + + if(num != 0) + conversionOk = false; + } + else + num = strNumeric.toULongLong(&conversionOk); + + break; + } + default: + { + num = strNumeric.toLongLong(&conversionOk); + break; + } + } + + if(conversionOk) + return fromValue(np, num); + else + return ValidationError::createError(); + } + + inline StorageType storedValue() const + { + return m_value; + } + + /** + * Determines the Effective %Boolean Value of this number. + * + * @returns @c false if the number is 0, otherwise @c true. + */ + bool evaluateEBV(const QExplicitlySharedDataPointer &) const + { + return m_value != 0; + } + + virtual QString stringValue() const + { + return QString::number(m_value); + } + + virtual ItemType::Ptr type() const + { + return itemType(); + } + + virtual xsDouble toDouble() const + { + return static_cast(m_value); + } + + virtual xsInteger toInteger() const + { + return m_value; + } + + virtual xsFloat toFloat() const + { + return static_cast(m_value); + } + + virtual xsDecimal toDecimal() const + { + return static_cast(m_value); + } + + virtual Numeric::Ptr round() const + { + /* xs:integerS never have a mantissa. */ + return Numeric::Ptr(static_cast(const_cast(Integer::fromValue(m_value).asAtomicValue()))); + } + + virtual Numeric::Ptr roundHalfToEven(const xsInteger) const + { + return Numeric::Ptr(static_cast(const_cast(Integer::fromValue(m_value).asAtomicValue()))); + } + + virtual Numeric::Ptr floor() const + { + return Numeric::Ptr(static_cast(const_cast(Integer::fromValue(m_value).asAtomicValue()))); + } + + virtual Numeric::Ptr ceiling() const + { + return Numeric::Ptr(static_cast(const_cast(Integer::fromValue(m_value).asAtomicValue()))); + } + + virtual Numeric::Ptr abs() const + { + /* We unconditionally create an Integer even if we're a positive + * value, because one part of this is the type change to + * xs:integer. + * + * We've manually inlined qAbs() and invoke xsInteger's + * constructor. The reason being that we other gets truncation down + * to StorageType. See for instance XQTS test case absint1args-1. */ + return Numeric::Ptr(static_cast(const_cast(Integer::fromValue(largerOrEqual(m_value, 0) ? xsInteger(m_value) : -xsInteger(m_value)).asAtomicValue()))); + } + + /** + * @returns always @c false, @c xs:DerivedInteger doesn't have + * not-a-number in its value space. + */ + virtual bool isNaN() const + { + return false; + } + + /** + * @returns always @c false, @c xs:DerivedInteger doesn't have + * infinity in its value space. + */ + virtual bool isInf() const + { + return false; + } + + virtual Item toNegated() const + { + return Integer::fromValue(-xsInteger(m_value)); + } + + virtual bool isSigned() const + { + switch(DerivedType) + { + /* Fallthrough all these. */ + case TypeByte: + case TypeInt: + case TypeLong: + case TypeNegativeInteger: + case TypeNonNegativeInteger: + case TypeNonPositiveInteger: + case TypePositiveInteger: + case TypeShort: + return true; + /* Fallthrough all these. */ + case TypeUnsignedByte: + case TypeUnsignedInt: + case TypeUnsignedLong: + case TypeUnsignedShort: + return false; + } + return false; + } + + virtual qulonglong toUnsignedInteger() const + { + switch(DerivedType) + { + /* Fallthrough all these. */ + case TypeByte: + case TypeInt: + case TypeLong: + case TypeNegativeInteger: + case TypeNonNegativeInteger: + case TypeNonPositiveInteger: + case TypePositiveInteger: + case TypeShort: + Q_ASSERT_X(false, Q_FUNC_INFO, + "It makes no sense to call this function, see Numeric::toUnsignedInteger()."); + /* Fallthrough all these. */ + case TypeUnsignedByte: + case TypeUnsignedInt: + case TypeUnsignedLong: + case TypeUnsignedShort: + return m_value; + } + return 0; + } + + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qderivedstring_p.h b/src/xmlpatterns/data/qderivedstring_p.h new file mode 100644 index 0000000..9142b87 --- /dev/null +++ b/src/xmlpatterns/data/qderivedstring_p.h @@ -0,0 +1,341 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_DerivedString_H +#define Patternist_DerivedString_H + +#include + +#include "private/qxmlutils_p.h" +#include "qbuiltintypes_p.h" +#include "qpatternistlocale_p.h" +#include "qvalidationerror_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Represents instances of derived @c xs:string types, such as @c + * xs:normalizedString. + * + * Whitespace is a significant part for creating values from the lexical + * space. Of course the specification is tricky here. Here's some pointers: + * + * - From XML Schema Part 2: Datatypes + * Second Edition, 4.3.6 whiteSpace: + * "For all atomic datatypes other than string (and types + * derived by restriction from it) the value of whiteSpace is + * collapse and cannot be changed by a schema author; for string the + * value of whiteSpace is preserve; for any type derived by + * restriction from string the value of whiteSpace can be any of the + * three legal values." + * - From XML Schema Part 1: Structures + * Second Edition, 3.1.4 White Space Normalization during Validation: + * "[Definition:] The normalized value of an element or attribute + * information item is an initial value whose white space, if any, + * has been normalized according to the value of the whiteSpace facet of + * the simple type definition used in its validation." + * + * @author Frans Englich + * @ingroup Patternist_xdm + * @todo Documentation is missing + */ + template + class DerivedString : public AtomicValue + { + private: + static inline ItemType::Ptr itemType() + { + switch(DerivedType) + { + case TypeNormalizedString: return BuiltinTypes::xsNormalizedString; + case TypeToken: return BuiltinTypes::xsToken; + case TypeLanguage: return BuiltinTypes::xsLanguage; + case TypeNMTOKEN: return BuiltinTypes::xsNMTOKEN; + case TypeName: return BuiltinTypes::xsName; + case TypeNCName: return BuiltinTypes::xsNCName; + case TypeID: return BuiltinTypes::xsID; + case TypeIDREF: return BuiltinTypes::xsIDREF; + case TypeENTITY: return BuiltinTypes::xsENTITY; + case TypeString: return BuiltinTypes::xsString; + } + + Q_ASSERT_X(false, Q_FUNC_INFO, "This line is not supposed to be reached."); + return ItemType::Ptr(); + } + + const QString m_value; + + inline DerivedString(const QString &value) : m_value(value) + { + } + + /** + * @short This is an incomplete test for whether @p ch conforms to + * the XML 1.0 NameChar production. + */ + static inline bool isNameChar(const QChar &ch) + { + return ch.isLetter() || + ch.isDigit() || + ch == QLatin1Char('.') || + ch == QLatin1Char('-') || + ch == QLatin1Char('_') || + ch == QLatin1Char(':'); + } + + /** + * @returns @c true if @p input is a valid @c xs:Name. + * @see Extensible + * Markup Language (XML) 1.0 (Fourth Edition), [5] Name + */ + static inline bool isValidName(const QString &input) + { + if(input.isEmpty()) + return false; + + const QChar first(input.at(0)); + + if(first.isLetter() || + first == QLatin1Char('_') || + first == QLatin1Char(':')) + { + const int len = input.length(); + + if(len == 1) + return true; + + /* Since we've checked the first character above, we start at + * position 1. */ + for(int i = 1; i < len; ++i) + { + if(!isNameChar(input.at(i))) + return false; + } + + return true; + } + else + return false; + } + + /** + * @returns @c true if @p input conforms to the XML 1.0 @c Nmtoken product. + * + * @see Extensible + * Markup Language (XML) 1.0 (Second Edition), [7] Nmtoken + */ + static inline bool isValidNMTOKEN(const QString &input) + { + const int len = input.length(); + + if(len == 0) + return false; + + for(int i = 0; i < len; ++i) + { + if(!isNameChar(input.at(i))) + return false; + } + + return true; + } + + /** + * @short Performs attribute value normalization as if @p input was not + * from a @c CDATA section. + * + * Each whitespace character in @p input that's not a space, such as tab + * or new line character, is replaced with a space. This algorithm + * differs from QString::simplified() in that it doesn't collapse + * subsequent whitespace characters to a single one, or remove trailing + * and leading space. + * + * @see Extensible + * Markup Language (XML) 1.0 (Second Edition), 3.3.3 [E70]Attribute-Value Normalization + */ + static QString attributeNormalize(const QString &input) + { + QString retval(input); + const int len = retval.length(); + const QLatin1Char space(' '); + + for(int i = 0; i < len; ++i) + { + const QChar ati(retval.at(i)); + + if(ati.isSpace() && ati != space) + retval[i] = space; + } + + return retval; + } + + static AtomicValue::Ptr error(const NamePool::Ptr &np, const QString &invalidValue) + { + return ValidationError::createError(QString::fromLatin1("%1 is not a valid value for " + "type %2.").arg(formatData(invalidValue)) + .arg(formatType(np, itemType()))); + } + + public: + + /** + * @note This function doesn't perform any cleanup/normalizaiton of @p + * value. @p value must be a canonical value space of the type. + * + * If you want cleanup to be performed and/or the lexical space + * checked, use fromLexical(). + */ + static AtomicValue::Ptr fromValue(const QString &value) + { + return AtomicValue::Ptr(new DerivedString(value)); + } + + /** + * Constructs an instance from the lexical + * representation @p lexical. + */ + static AtomicValue::Ptr fromLexical(const NamePool::Ptr &np, const QString &lexical) + { + switch(DerivedType) + { + case TypeString: + return AtomicValue::Ptr(new DerivedString(lexical)); + case TypeNormalizedString: + return AtomicValue::Ptr(new DerivedString(attributeNormalize(lexical))); + case TypeToken: + return AtomicValue::Ptr(new DerivedString(lexical.simplified())); + case TypeLanguage: + { + const QString simplified(lexical.trimmed()); + + const QRegExp validate(QLatin1String("[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*")); + Q_ASSERT(validate.isValid()); + + if(validate.exactMatch(simplified)) + return AtomicValue::Ptr(new DerivedString(lexical.simplified())); + else + return error(np, simplified); + } + case TypeNMTOKEN: + { + const QString trimmed(lexical.trimmed()); + + if(isValidNMTOKEN(trimmed)) + return AtomicValue::Ptr(new DerivedString(trimmed)); + else + return error(np, trimmed); + } + case TypeName: + { + const QString simplified(lexical.simplified()); + + if(isValidName(simplified)) + return AtomicValue::Ptr(new DerivedString(simplified)); + else + return error(np, simplified); + } + case TypeID: + /* Fallthrough. */ + case TypeIDREF: + /* Fallthrough. */ + case TypeENTITY: + /* Fallthrough. */ + case TypeNCName: + { + /* We treat xs:ID, xs:ENTITY, xs:IDREF and xs:NCName in the exact same + * way, except for the type annotation. + * + * We use trimmed() instead of simplified() because it's + * faster and whitespace isn't allowed between + * non-whitespace characters anyway, for these types. */ + const QString trimmed(lexical.trimmed()); + + if(QXmlUtils::isNCName(trimmed)) + return AtomicValue::Ptr(new DerivedString(trimmed)); + else + return error(np, trimmed); + } + default: + { + Q_ASSERT_X(false, Q_FUNC_INFO, "This line is not supposed to be reached."); + return AtomicValue::Ptr(); + } + } + } + + virtual QString stringValue() const + { + return m_value; + } + + virtual bool evaluateEBV(const QExplicitlySharedDataPointer &) const + { + return m_value.length() > 0; + } + + virtual ItemType::Ptr type() const + { + return itemType(); + } + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qduration.cpp b/src/xmlpatterns/data/qduration.cpp new file mode 100644 index 0000000..6849a8b --- /dev/null +++ b/src/xmlpatterns/data/qduration.cpp @@ -0,0 +1,244 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qabstractdatetime_p.h" +#include "qbuiltintypes_p.h" +#include "qitem_p.h" + +#include "qduration_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Duration::Duration(const bool isPositiveP, + const YearProperty yearsP, + const MonthProperty monthsP, + const DayCountProperty daysP, + const HourProperty hoursP, + const MinuteProperty mins, + const SecondProperty secs, + const MSecondProperty msecs) : AbstractDuration(isPositiveP), + m_years(yearsP), + m_months(monthsP), + m_days(daysP), + m_hours(hoursP), + m_minutes(mins), + m_seconds(secs), + m_mseconds(msecs) +{ +} + +Duration::Ptr Duration::fromLexical(const QString &lexical) +{ + static const CaptureTable captureTable( + /* The extra paranthesis is a build fix for GCC 3.3. */ + (QRegExp(QLatin1String( + "^\\s*" /* Any preceding whitespace. */ + "(-)?" /* Any minus sign. */ + "P" /* Delimiter. */ + "(?:(\\d+)Y)?" /* Year part. */ + "(?:(\\d+)M)?" /* Month part. */ + "(?:(\\d+)D)?" /* Day part. */ + "(?:" /* Here starts the optional time part. */ + "(T)" /* SchemaTime delimiter. */ + "(?:(\\d+)H)?" /* Hour part. */ + "(?:(\\d+)M)?" /* Minute part. */ + "(?:(\\d+)(?:\\.(\\d+))?S)?" /* Seconds & milli seconds. */ + ")?" /* End of optional time part. */ + "\\s*$" /* Any terminating whitespace. */))), + /*yearP*/ 2, + /*monthP*/ 3, + /*dayP*/ 4, + /*tDelimiterP*/ 5, + /*hourP*/ 6, + /*minutesP*/ 7, + /*secondsP*/ 8, + /*msecondsP*/ 9); + + YearProperty years = 0; + MonthProperty months = 0; + DayCountProperty days = 0; + HourProperty hours = 0; + MinuteProperty minutes = 0; + SecondProperty sec = 0; + MSecondProperty msec = 0; + bool isPos; + + const AtomicValue::Ptr err(create(captureTable, lexical, &isPos, &years, &months, + &days, &hours, &minutes, &sec, &msec)); + + return err ? err : Duration::Ptr(new Duration(isPos, years, months, days, hours, + minutes, sec, msec)); +} + +Duration::Ptr Duration::fromComponents(const bool isPositive, + const YearProperty years, + const MonthProperty months, + const DayCountProperty days, + const HourProperty hours, + const MinuteProperty minutes, + const SecondProperty seconds, + const MSecondProperty mseconds) +{ + return Duration::Ptr(new Duration(isPositive, years, months, days, + hours, minutes, seconds, mseconds)); +} + +AbstractDuration::Value Duration::value() const +{ + Q_ASSERT_X(false, Q_FUNC_INFO, + "Calling Duration::value() makes no sense"); + return 0; +} + +Item Duration::fromValue(const Value) const +{ + Q_ASSERT_X(false, Q_FUNC_INFO, + "Calling Duration::fromValue() makes no sense"); + return Item(); +} + +QString Duration::stringValue() const +{ + QString retval; + + if(!m_isPositive) + retval.append(QLatin1Char('-')); + + retval.append(QLatin1Char('P')); + + if(m_years) + { + retval.append(QString::number(m_years)); + retval.append(QLatin1Char('Y')); + } + + if(m_months) + { + retval.append(QString::number(m_months)); + retval.append(QLatin1Char('M')); + } + + if(m_days) + { + retval.append(QString::number(m_days)); + retval.append(QLatin1Char('D')); + } + + if(!m_hours && !m_minutes && !m_seconds && !m_seconds) + { + if(!m_years && !m_months && !m_days) + return QLatin1String("PT0S"); + else + return retval; + } + + retval.append(QLatin1Char('T')); + + if(m_hours) + { + retval.append(QString::number(m_hours)); + retval.append(QLatin1Char('H')); + } + + if(m_minutes) + { + retval.append(QString::number(m_minutes)); + retval.append(QLatin1Char('M')); + } + + if(m_seconds || m_seconds) + { + retval.append(QString::number(m_seconds)); + + if(m_mseconds) + retval.append(serializeMSeconds(m_mseconds)); + + retval.append(QLatin1Char('S')); + } + else if(!m_years && !m_months && !m_days && !m_hours && !m_minutes) + retval.append(QLatin1String("0S")); + + return retval; +} + +YearProperty Duration::years() const +{ + return m_years; +} + +MonthProperty Duration::months() const +{ + return m_months; +} + +DayCountProperty Duration::days() const +{ + return m_days; +} + +HourProperty Duration::hours() const +{ + return m_hours; +} + +MinuteProperty Duration::minutes() const +{ + return m_minutes; +} + +SecondProperty Duration::seconds() const +{ + return m_seconds; +} + +MSecondProperty Duration::mseconds() const +{ + return m_mseconds; +} + +ItemType::Ptr Duration::type() const +{ + return BuiltinTypes::xsDuration; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qduration_p.h b/src/xmlpatterns/data/qduration_p.h new file mode 100644 index 0000000..de84a1a --- /dev/null +++ b/src/xmlpatterns/data/qduration_p.h @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_Duration_H +#define Patternist_Duration_H + +#include "qabstractduration_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the value instance of the @c xs:duration type. + * + * @author Frans Englich + * @ingroup Patternist_xdm + */ + class Duration : public AbstractDuration + { + public: + typedef AtomicValue::Ptr Ptr; + + /** + * Creates an instance from the lexical representation @p string. + */ + static Duration::Ptr fromLexical(const QString &string); + static Duration::Ptr fromComponents(const bool isPositive, + const YearProperty years, + const MonthProperty months, + const DayCountProperty days, + const HourProperty hours, + const MinuteProperty minutes, + const SecondProperty seconds, + const MSecondProperty mseconds); + + virtual ItemType::Ptr type() const; + virtual QString stringValue() const; + + /** + * Always results in an assert crash. Calling this function makes no + * sense due to that the value space of xs:duration is not well defined. + */ + virtual Value value() const; + + /** + * Always results in an assert crash. Calling this function makes no + * sense due to that the value space of xs:duration is not well defined. + */ + virtual Item fromValue(const Value val) const; + + virtual YearProperty years() const; + virtual MonthProperty months() const; + virtual DayCountProperty days() const; + virtual HourProperty hours() const; + virtual MinuteProperty minutes() const; + virtual SecondProperty seconds() const; + virtual MSecondProperty mseconds() const; + + protected: + friend class CommonValues; + + Duration(const bool isPositive, + const YearProperty years, + const MonthProperty months, + const DayCountProperty days, + const HourProperty hours, + const MinuteProperty minutes, + const SecondProperty seconds, + const MSecondProperty mseconds); + private: + const YearProperty m_years; + const MonthProperty m_months; + const DayCountProperty m_days; + const HourProperty m_hours; + const MinuteProperty m_minutes; + const SecondProperty m_seconds; + const MSecondProperty m_mseconds; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qgday.cpp b/src/xmlpatterns/data/qgday.cpp new file mode 100644 index 0000000..c11acbd --- /dev/null +++ b/src/xmlpatterns/data/qgday.cpp @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" + +#include "qgday_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +GDay::GDay(const QDateTime &dateTime) : AbstractDateTime(dateTime) +{ +} + +GDay::Ptr GDay::fromLexical(const QString &lexical) +{ + static const CaptureTable captureTable( // STATIC DATA + /* The extra paranthesis is a build fix for GCC 3.3. */ + (QRegExp(QLatin1String( + "^\\s*" /* Any preceding whitespace. */ + "---" /* Delimiter. */ + "(\\d{2})" /* The day part, "03". */ + "(?:(?:(\\+|-))(\\d{2}):(\\d{2})|(Z))?" /* Timezone, "+08:24". */ + "\\s*$" /* Any whitespace at the end. */))), + /*zoneOffsetSignP*/ 2, + /*zoneOffsetHourP*/ 3, + /*zoneOffsetMinuteP*/ 4, + /*zoneOffsetUTCSymbolP*/ 5, + /*yearP*/ -1, + /*monthP*/ -1, + /*dayP*/ 1); + + AtomicValue::Ptr err; + const QDateTime retval(create(err, lexical, captureTable)); + + return err ? err : GDay::Ptr(new GDay(retval)); +} + +GDay::Ptr GDay::fromDateTime(const QDateTime &dt) +{ + QDateTime result(QDate(DefaultYear, DefaultMonth, dt.date().day())); + copyTimeSpec(dt, result); + + return GDay::Ptr(new GDay(result)); +} + +QString GDay::stringValue() const +{ + return m_dateTime.toString(QLatin1String("---dd")) + zoneOffsetToString(); +} + +ItemType::Ptr GDay::type() const +{ + return BuiltinTypes::xsGDay; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qgday_p.h b/src/xmlpatterns/data/qgday_p.h new file mode 100644 index 0000000..b958769 --- /dev/null +++ b/src/xmlpatterns/data/qgday_p.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_GDay_H +#define Patternist_GDay_H + +#include "qabstractdatetime_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the value instance of the @c xs:gDay type. + * + * @author Frans Englich + * @ingroup Patternist_xdm + */ + class GDay : public AbstractDateTime + { + public: + typedef AtomicValue::Ptr Ptr; + + /** + * Creates an instance from the lexical representation @p string. + */ + static GDay::Ptr fromLexical(const QString &string); + static GDay::Ptr fromDateTime(const QDateTime &dt); + + virtual ItemType::Ptr type() const; + virtual QString stringValue() const; + + protected: + friend class CommonValues; + + GDay(const QDateTime &dateTime); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qgmonth.cpp b/src/xmlpatterns/data/qgmonth.cpp new file mode 100644 index 0000000..1651735 --- /dev/null +++ b/src/xmlpatterns/data/qgmonth.cpp @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" + +#include "qgmonth_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +GMonth::GMonth(const QDateTime &dateTime) : AbstractDateTime(dateTime) +{ +} + +GMonth::Ptr GMonth::fromLexical(const QString &lexical) +{ + static const CaptureTable captureTable( // STATIC DATA + /* The extra paranthesis is a build fix for GCC 3.3. */ + (QRegExp(QLatin1String( + "^\\s*" /* Any preceding whitespace. */ + "--" /* Delimier. */ + "(\\d{2})" /* The month part, "03". */ + "(?:(\\+|-)(\\d{2}):(\\d{2})|(Z))?" /* Timezone, "+08:24". */ + "\\s*$" /* Any terminating whitespace. */))), + /*zoneOffsetSignP*/ 2, + /*zoneOffsetHourP*/ 3, + /*zoneOffsetMinuteP*/ 4, + /*zoneOffsetUTCSymbolP*/ 5, + /*yearP*/ -1, + /*monthP*/ 1); + + AtomicValue::Ptr err; + const QDateTime retval(create(err, lexical, captureTable)); + + return err ? err : GMonth::Ptr(new GMonth(retval)); +} + +GMonth::Ptr GMonth::fromDateTime(const QDateTime &dt) +{ + QDateTime result(QDate(DefaultYear, dt.date().month(), DefaultDay)); + copyTimeSpec(dt, result); + + return GMonth::Ptr(new GMonth(result)); +} + +QString GMonth::stringValue() const +{ + return m_dateTime.toString(QLatin1String("--MM")) + zoneOffsetToString(); +} + +ItemType::Ptr GMonth::type() const +{ + return BuiltinTypes::xsGMonth; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qgmonth_p.h b/src/xmlpatterns/data/qgmonth_p.h new file mode 100644 index 0000000..2ff766a --- /dev/null +++ b/src/xmlpatterns/data/qgmonth_p.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_GMonth_H +#define Patternist_GMonth_H + +#include "qabstractdatetime_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the value instance of the @c xs:gMonth type. + * + * @author Frans Englich + * @ingroup Patternist_xdm + */ + class GMonth : public AbstractDateTime + { + public: + typedef AtomicValue::Ptr Ptr; + + /** + * Creates an instance from the lexical representation @p string. + */ + static GMonth::Ptr fromLexical(const QString &string); + static GMonth::Ptr fromDateTime(const QDateTime &dt); + + virtual ItemType::Ptr type() const; + virtual QString stringValue() const; + + protected: + friend class CommonValues; + + GMonth(const QDateTime &dateTime); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qgmonthday.cpp b/src/xmlpatterns/data/qgmonthday.cpp new file mode 100644 index 0000000..fe1210d --- /dev/null +++ b/src/xmlpatterns/data/qgmonthday.cpp @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" + +#include "qgmonthday_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +GMonthDay::GMonthDay(const QDateTime &dateTime) : AbstractDateTime(dateTime) +{ +} + +GMonthDay::Ptr GMonthDay::fromLexical(const QString &lexical) +{ + static const CaptureTable captureTable( // STATIC DATA + /* The extra paranthesis is a build fix for GCC 3.3. */ + (QRegExp(QLatin1String( + "^\\s*" /* Any preceding whitespace. */ + "--" /* Delimiter. */ + "(\\d{2})" /* The month part. */ + "-" /* Delimiter. */ + "(\\d{2})" /* The day part. */ + "(?:(\\+|-)(\\d{2}):(\\d{2})|(Z))?" /* The zone offset, "+08:24". */ + "\\s*$" /* Any terminating whitespace. */))), + /*zoneOffsetSignP*/ 3, + /*zoneOffsetHourP*/ 4, + /*zoneOffsetMinuteP*/ 5, + /*zoneOffsetUTCSymbolP*/ 6, + /*yearP*/ -1, + /*monthP*/ 1, + /*dayP*/ 2); + + AtomicValue::Ptr err; + const QDateTime retval(create(err, lexical, captureTable)); + + return err ? err : GMonthDay::Ptr(new GMonthDay(retval)); +} + +GMonthDay::Ptr GMonthDay::fromDateTime(const QDateTime &dt) +{ + QDateTime result(QDate(DefaultYear, dt.date().month(), dt.date().day())); + copyTimeSpec(dt, result); + + return GMonthDay::Ptr(new GMonthDay(result)); +} + +QString GMonthDay::stringValue() const +{ + return m_dateTime.toString(QLatin1String("--MM-dd")) + zoneOffsetToString(); +} + +ItemType::Ptr GMonthDay::type() const +{ + return BuiltinTypes::xsGMonthDay; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qgmonthday_p.h b/src/xmlpatterns/data/qgmonthday_p.h new file mode 100644 index 0000000..a979646 --- /dev/null +++ b/src/xmlpatterns/data/qgmonthday_p.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_GMonthDay_H +#define Patternist_GMonthDay_H + +#include "qabstractdatetime_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the value instance of the @c xs:gYearMonth type. + * + * @author Frans Englich + * @ingroup Patternist_xdm + */ + class GMonthDay : public AbstractDateTime + { + public: + typedef AtomicValue::Ptr Ptr; + + /** + * Creates an instance from the lexical representation @p string. + */ + static GMonthDay::Ptr fromLexical(const QString &string); + static GMonthDay::Ptr fromDateTime(const QDateTime &dt); + + virtual ItemType::Ptr type() const; + + virtual QString stringValue() const; + + protected: + friend class CommonValues; + + GMonthDay(const QDateTime &dateTime); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qgyear.cpp b/src/xmlpatterns/data/qgyear.cpp new file mode 100644 index 0000000..488cd5e --- /dev/null +++ b/src/xmlpatterns/data/qgyear.cpp @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" + +#include "qgyear_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +GYear::GYear(const QDateTime &dateTime) : AbstractDateTime(dateTime) +{ +} + +GYear::Ptr GYear::fromLexical(const QString &lexical) +{ + static const CaptureTable captureTable( // STATIC DATA + /* The extra paranthesis is a build fix for GCC 3.3. */ + (QRegExp(QLatin1String( + "^\\s*" /* Any preceding whitespace. */ + "(-?)" /* Any preceding minus. */ + "(-?\\d{4,})" /* The year part, "1999". */ + "(?:(\\+|-)(\\d{2}):(\\d{2})|(Z))?" /* The zone offset, "+08:24". */ + "\\s*$" /* Any terminating whitespace. */))), + /*zoneOffsetSignP*/ 3, + /*zoneOffsetHourP*/ 4, + /*zoneOffsetMinuteP*/ 5, + /*zoneOffsetUTCSymbolP*/ 6, + /*yearP*/ 2, + /*monthP*/ -1, + /*dayP*/ -1, + /*hourP*/ -1, + /*minutesP*/ -1, + /*secondsP*/ -1, + /*msecondsP*/ -1, + /*yearSign*/ 1); + + AtomicValue::Ptr err; + const QDateTime retval(create(err, lexical, captureTable)); + + return err ? err : GYear::Ptr(new GYear(retval)); +} + +GYear::Ptr GYear::fromDateTime(const QDateTime &dt) +{ + QDateTime result(QDate(dt.date().year(), DefaultMonth, DefaultDay)); + copyTimeSpec(dt, result); + + return GYear::Ptr(new GYear(result)); +} + +QString GYear::stringValue() const +{ + return m_dateTime.toString(QLatin1String("yyyy")) + zoneOffsetToString(); +} + +ItemType::Ptr GYear::type() const +{ + return BuiltinTypes::xsGYear; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qgyear_p.h b/src/xmlpatterns/data/qgyear_p.h new file mode 100644 index 0000000..a02f0c2 --- /dev/null +++ b/src/xmlpatterns/data/qgyear_p.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_GYear_H +#define Patternist_GYear_H + +#include "qabstractdatetime_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the value instance of the @c xs:gYear type. + * + * @author Frans Englich + * @ingroup Patternist_xdm + */ + class GYear : public AbstractDateTime + { + public: + typedef AtomicValue::Ptr Ptr; + + /** + * Creates an instance from the lexical representation @p string. + */ + static GYear::Ptr fromLexical(const QString &string); + static GYear::Ptr fromDateTime(const QDateTime &dt); + + virtual ItemType::Ptr type() const; + virtual QString stringValue() const; + + protected: + friend class CommonValues; + + GYear(const QDateTime &dateTime); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qgyearmonth.cpp b/src/xmlpatterns/data/qgyearmonth.cpp new file mode 100644 index 0000000..665059b --- /dev/null +++ b/src/xmlpatterns/data/qgyearmonth.cpp @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" + +#include "qgyearmonth_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +GYearMonth::GYearMonth(const QDateTime &dateTime) : AbstractDateTime(dateTime) +{ +} + +GYearMonth::Ptr GYearMonth::fromLexical(const QString &lexical) +{ + static const CaptureTable captureTable( // STATIC DATA + /* The extra paranthesis is a build fix for GCC 3.3. */ + (QRegExp(QLatin1String( + "^\\s*" /* Any preceding whitespace. */ + "(-?)" /* Any preceding minus. */ + "(\\d{4,})" /* The year part. */ + "-" /* Delimiter. */ + "(\\d{2})" /* The month part. */ + "(?:(\\+|-)(\\d{2}):(\\d{2})|(Z))?" /* The zone offset, "+08:24". */ + "\\s*$" /* Any terminating whitespace. */))), + /*zoneOffsetSignP*/ 4, + /*zoneOffsetHourP*/ 5, + /*zoneOffsetMinuteP*/ 6, + /*zoneOffsetUTCSymbolP*/ 7, + /*yearP*/ 2, + /*monthP*/ 3, + /*dayP*/ -1, + /*hourP*/ -1, + /*minutesP*/ -1, + /*secondsP*/ -1, + /*msecondsP*/ -1, + /*yearSign*/ 1); + + AtomicValue::Ptr err; + const QDateTime retval(create(err, lexical, captureTable)); + + return err ? err : GYearMonth::Ptr(new GYearMonth(retval)); +} + +GYearMonth::Ptr GYearMonth::fromDateTime(const QDateTime &dt) +{ + QDateTime result(QDate(dt.date().year(), dt.date().month(), DefaultDay)); + copyTimeSpec(dt, result); + + return GYearMonth::Ptr(new GYearMonth(result)); +} + +QString GYearMonth::stringValue() const +{ + return m_dateTime.toString(QLatin1String("yyyy-MM")) + zoneOffsetToString(); +} + +ItemType::Ptr GYearMonth::type() const +{ + return BuiltinTypes::xsGYearMonth; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qgyearmonth_p.h b/src/xmlpatterns/data/qgyearmonth_p.h new file mode 100644 index 0000000..6d74d8e --- /dev/null +++ b/src/xmlpatterns/data/qgyearmonth_p.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_GYearMonth_H +#define Patternist_GYearMonth_H + +#include "qabstractdatetime_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the value instance of the @c xs:gYearMonth type. + * + * @author Frans Englich + * @ingroup Patternist_xdm + */ + class GYearMonth : public AbstractDateTime + { + public: + typedef AtomicValue::Ptr Ptr; + + /** + * Creates an instance from the lexical representation @p string. + */ + static GYearMonth::Ptr fromLexical(const QString &string); + static GYearMonth::Ptr fromDateTime(const QDateTime &dt); + + virtual ItemType::Ptr type() const; + virtual QString stringValue() const; + + protected: + friend class CommonValues; + + GYearMonth(const QDateTime &dateTime); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qhexbinary.cpp b/src/xmlpatterns/data/qhexbinary.cpp new file mode 100644 index 0000000..c9360fe --- /dev/null +++ b/src/xmlpatterns/data/qhexbinary.cpp @@ -0,0 +1,151 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qbase64binary_p.h" +#include "qbuiltintypes_p.h" +#include "qpatternistlocale_p.h" +#include "qvalidationerror_p.h" + +#include "qhexbinary_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +HexBinary::HexBinary(const QByteArray &val) : Base64Binary(val) +{ +} + +qint8 HexBinary::fromHex(const QChar &c) +{ + if(c.unicode() > 'f') + return -1; + + const char *const range = "0123456789ABCDEFabcdef"; + + const char *const in = strchr(range, c.unicode()); + + if(!in) + return -1; + + /* Pointer arithmetic. */ + int digit = in - range; + + if(digit > 15) + digit -= 6; + + return digit; +} + +AtomicValue::Ptr HexBinary::fromLexical(const NamePool::Ptr &np, const QString &str) +{ + const QString lexical(str.trimmed()); + const int len = lexical.length(); + + if(len == 0) + return AtomicValue::Ptr(new HexBinary(QByteArray())); + + if((len & 1) != 0) + { + /* Catch a common case. */ + return ValidationError::createError(QtXmlPatterns::tr( + "A value of type %1 must contain an even number of " + "digits. The value %2 does not.") + .arg(formatType(np, BuiltinTypes::xsHexBinary), + formatData(QString::number(len)))); + } + + QByteArray val; + val.resize(len / 2); + + for(int i = 0; i < len / 2; ++i) + { + qint8 p1 = fromHex(lexical[i * 2]); + qint8 p2 = fromHex(lexical[i * 2 + 1]); + + if(p1 == -1 || p2 == -1) + { + const QString hex(QString::fromLatin1("%1%2").arg(lexical[i * 2], lexical[i * 2 + 1])); + + return ValidationError::createError(QtXmlPatterns::tr( + "%1 is not valid as a value of type %2.") + .arg(formatData(hex), + formatType(np, BuiltinTypes::xsHexBinary))); + } + + val[i] = static_cast(p1 * 16 + p2); + } + Q_ASSERT(!val.isEmpty()); + + return AtomicValue::Ptr(new HexBinary(val)); +} + +HexBinary::Ptr HexBinary::fromValue(const QByteArray &data) +{ + return HexBinary::Ptr(new HexBinary(data)); +} + +QString HexBinary::stringValue() const +{ + static const char s_toHex[] = "0123456789ABCDEF"; + const int len = m_value.count(); + QString result; + result.reserve(len * 2); + + for(int i = 0; i < len; ++i) + { + // This cast is significant. + const unsigned char val = static_cast(m_value.at(i)); + result += QLatin1Char(s_toHex[val >> 4]); + result += QLatin1Char(s_toHex[val & 0x0F]); + } + + return result; +} + +ItemType::Ptr HexBinary::type() const +{ + return BuiltinTypes::xsHexBinary; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qhexbinary_p.h b/src/xmlpatterns/data/qhexbinary_p.h new file mode 100644 index 0000000..5dd1624 --- /dev/null +++ b/src/xmlpatterns/data/qhexbinary_p.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_HexBinary_H +#define Patternist_HexBinary_H + +#include "qbase64binary_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Implements the value instance of the @c xs:hexBinary type. + * + * HexBinary inherits from Base64Binary for implementation reasons. The two + * classes are similar, and inheritance therefore save code. + * + * @author Frans Englich + * @ingroup Patternist_xdm + * @todo Documentation is missing + */ + class HexBinary : public Base64Binary + { + public: + friend class CommonValues; + + typedef AtomicValue::Ptr Ptr; + + virtual QString stringValue() const; + virtual ItemType::Ptr type() const; + + /** + * Creates a @c xs:hexBinary from the lexical representation @p value. + */ + static AtomicValue::Ptr fromLexical(const NamePool::Ptr &np, const QString &value); + + /** + * Creates an instance representing @p value. + */ + static HexBinary::Ptr fromValue(const QByteArray &data); + + protected: + HexBinary(const QByteArray &val); + + private: + /** + * @short Returns -1 on invalid input. + */ + static inline qint8 fromHex(const QChar &c); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qinteger.cpp b/src/xmlpatterns/data/qinteger.cpp new file mode 100644 index 0000000..7fc6b3d --- /dev/null +++ b/src/xmlpatterns/data/qinteger.cpp @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" +#include "qitem_p.h" +#include "qvalidationerror_p.h" + +#include "qinteger_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Item Integer::fromValue(const xsInteger num) +{ + return toItem(Integer::Ptr(new Integer(num))); +} + +AtomicValue::Ptr Integer::fromLexical(const QString &strNumeric) +{ + bool conversionOk = false; + const xsInteger num = strNumeric.toLongLong(&conversionOk); + + if(conversionOk) + return AtomicValue::Ptr(new Integer(num)); + else + return ValidationError::createError(); +} + +Integer::Integer(const xsInteger num) : m_value(num) +{ +} + +bool Integer::evaluateEBV(const QExplicitlySharedDataPointer &) const +{ + return m_value != 0; +} + +QString Integer::stringValue() const +{ + return QString::number(m_value); +} + +ItemType::Ptr Integer::type() const +{ + return BuiltinTypes::xsInteger; +} + +xsDouble Integer::toDouble() const +{ + return static_cast(m_value); +} + +xsInteger Integer::toInteger() const +{ + return m_value; +} + +xsFloat Integer::toFloat() const +{ + return static_cast(m_value); +} + +xsDecimal Integer::toDecimal() const +{ + return static_cast(m_value); +} + +Numeric::Ptr Integer::round() const +{ + /* xs:integerS never has a mantissa. */ + return Numeric::Ptr(const_cast(this)); +} + +Numeric::Ptr Integer::roundHalfToEven(const xsInteger /*scale*/) const +{ + return Numeric::Ptr(const_cast(this)); +} + +Numeric::Ptr Integer::floor() const +{ + return Numeric::Ptr(const_cast(this)); +} + +Numeric::Ptr Integer::ceiling() const +{ + return Numeric::Ptr(const_cast(this)); +} + +Numeric::Ptr Integer::abs() const +{ + /* No reason to allocate an Integer if we're already absolute. */ + if(m_value < 0) + return Numeric::Ptr(new Integer(qAbs(m_value))); + else + return Numeric::Ptr(const_cast(this)); +} + +bool Integer::isNaN() const +{ + return false; +} + +bool Integer::isInf() const +{ + return false; +} + +Item Integer::toNegated() const +{ + return fromValue(-m_value); +} + +bool Integer::isSigned() const +{ + return true; +} + +qulonglong Integer::toUnsignedInteger() const +{ + Q_ASSERT_X(false, Q_FUNC_INFO, + "It makes no sense to call this function, see Numeric::toUnsignedInteger()."); + return 0; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qinteger_p.h b/src/xmlpatterns/data/qinteger_p.h new file mode 100644 index 0000000..20a5931 --- /dev/null +++ b/src/xmlpatterns/data/qinteger_p.h @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_Integer_H +#define Patternist_Integer_H + +#include "qschemanumeric_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the value instance of the @c xs:integer type. + * + * @author Frans Englich + * @ingroup Patternist_xdm + * @todo Documentation is missing + */ + class Integer : public Numeric + { + public: + + typedef Numeric::Ptr Ptr; + + /** + * Constructs an instance from the lexical + * representation @p strNumeric. + * + * @todo Type error handling. + */ + static AtomicValue::Ptr fromLexical(const QString &strNumeric); + + static Item fromValue(const xsInteger num); + + /** + * Determines the Effective %Boolean Value of this number. + * + * @returns @c false if the number is 0, otherwise @c true. + */ + bool evaluateEBV(const QExplicitlySharedDataPointer &) const; + + virtual QString stringValue() const; + + /** + * @returns always BuiltinTypes::xsInteger + */ + virtual ItemType::Ptr type() const; + + virtual xsDouble toDouble() const; + virtual xsInteger toInteger() const; + virtual xsFloat toFloat() const; + virtual xsDecimal toDecimal() const; + + virtual Numeric::Ptr round() const; + virtual Numeric::Ptr roundHalfToEven(const xsInteger scale) const; + virtual Numeric::Ptr floor() const; + virtual Numeric::Ptr ceiling() const; + virtual Numeric::Ptr abs() const; + virtual qulonglong toUnsignedInteger() const; + + /** + * @returns always @c false, @c xs:integer doesn't have + * not-a-number in its value space. + */ + virtual bool isNaN() const; + + /** + * @returns always @c false, @c xs:integer doesn't have + * infinity in its value space. + */ + virtual bool isInf() const; + virtual Item toNegated() const; + + /** + * @short Returns always @c true. + */ + virtual bool isSigned() const; + protected: + Integer(const xsInteger num); + + private: + const xsInteger m_value; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qitem.cpp b/src/xmlpatterns/data/qitem.cpp new file mode 100644 index 0000000..4302fa8 --- /dev/null +++ b/src/xmlpatterns/data/qitem.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" + +#include "qitem_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Item::Iterator::Ptr Item::sequencedTypedValue() const +{ + if(isAtomicValue()) + return makeSingletonIterator(Item(atomicValue)); + else + return asNode().sequencedTypedValue(); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qitem_p.h b/src/xmlpatterns/data/qitem_p.h new file mode 100644 index 0000000..8184b25 --- /dev/null +++ b/src/xmlpatterns/data/qitem_p.h @@ -0,0 +1,546 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_Item_H +#define Patternist_Item_H + +#include +#include +#include +#include + +#include +#include + +/** + * @file + * @short Due to strong interdependencies, this file contains the definitions for + * the classes Item, QXmlNodeModelIndex, QAbstractXmlNodeModel and AtomicValue. The implementations are + * in their respective source files. + */ + +/** + * @class QSharedData + * @short Qt's base class for reference counting. + */ + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +template class QList; +template class QVector; +template class QAbstractXmlForwardIterator; + +class QSourceLocation; +class QAbstractXmlReceiver; + +namespace QPatternist +{ + class DynamicContext; + class Item; + class ItemType; + class QObjectNodeModel; + template class EmptyIterator; + template class ListIterator; + + /** + * @short Base class for all classes representing atomic values. + * + * Instantiating AtomicValues sub classes from a value of somekind, + * for a certain type is done in three different ways: + * + * - The static factory fromLexical which available in most classes. This + * function attempts to create a value from a QString that is considered + * a lexical representation of the value. Thus, this function performs validation, takes + * care of whitespace facets, and everything else related to instantiating a value from + * a lexical representation. + * - The static factory function fromValue. This function exists for + * values where a C++ type exists which corresponds to the type's value space. + * - By using instances available in CommonValues. This is the preferred method + * since it uses existing singleton instances and thus saves memory. CommonValues + * should be used whenever possible, it can be thought as a collection of constant values. + * + * For types that does not distinguish the value space and lexical space, such as xs:string, + * only the fromValue() function exist, and fromLexical() is omitted. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class AtomicValue : public QSharedData + , public CppCastingHelper + { + public: + virtual ~AtomicValue(); + + /** + * A smart pointer wrapping AtomicValue instances. + */ + typedef QExplicitlySharedDataPointer Ptr; + + /** + * A list if smart pointers wrapping AtomicValue instances. + */ + typedef QList List; + + /** + * Determines whether this atomic value has an error. This is used + * for implementing casting. + * + * @returns always @c false + */ + virtual bool hasError() const; + + /** + * Always fails by issuing the type error ReportContext::FORG0006. Sub-classes + * whose represented type do allow EBV to be extracted from, must thus + * re-implement this function. + */ + virtual bool evaluateEBV(const QExplicitlySharedDataPointer &context) const; + + virtual QString stringValue() const = 0; + virtual ItemType::Ptr type() const = 0; + + /** + * Converts @p value to a QVariant. + */ + static QVariant toQt(const AtomicValue *const value); + + static inline QVariant toQt(const AtomicValue::Ptr &value) + { + return toQt(value.data()); + } + + static Item toXDM(const QVariant &value); + + static ItemType::Ptr qtToXDMType(const QXmlItem &item); + protected: + inline AtomicValue() + { + } + }; + + /** + * @short Represents an item in the XPath 2.0 Data Model. + * + * There exists two types of items: nodes and atomic values. + * + * The XQuery 1.0 and XPath 2.0 Data Model and XML Path Language (XPath) 2.0 specification + * makes a very strong distinction between a sequence of items and an atomized sequence. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class Item + { + friend class QT_PREPEND_NAMESPACE(QXmlItem); + + public: + /** + * A smart pointer wrapping an Item instance. + */ + typedef QAbstractXmlForwardIterator Iterator; + + /** + * A list of Item instances, each wrapped in a smart pointer. + */ + typedef QList List; + + /** + * A vector of Item instances, each wrapped in a smart pointer. + */ + typedef QVector Vector; + + typedef QPatternist::SingletonIterator SingletonIterator; + typedef QPatternist::EmptyIterator EmptyIterator; + + /** + * Default constructor. + */ + inline Item() + { + /* Note that this function should be equal to reset(). */ + + /* This is the area which atomicValue uses. Becauase we want as() + * to return null on null-constructed objects, we initialize it. */ + node.data = 0; + + /* This signals that we're not an atomic value. */ + node.model = 0; + } + + inline Item(const QXmlNodeModelIndex &n) : node(n.m_storage) + { + } + + inline Item(const Item &other) : node(other.node) + { + Q_ASSERT_X(sizeof(QXmlNodeModelIndex) >= sizeof(AtomicValue), Q_FUNC_INFO, + "Since we're only copying the node member, it must be the largest."); + if(isAtomicValue()) + atomicValue->ref.ref(); + } + + inline Item(const AtomicValue::Ptr &a) + { + if(a) + { + atomicValue = a.data(); + atomicValue->ref.ref(); + + /* Signal that we're housing an atomic value. */ + node.model = reinterpret_cast(~0); + } + else + node.model = 0; /* Like the default constructor. */ + } + + inline Item(const AtomicValue *const a) + { + /* Note, the implementation is a copy of the constructor above. */ + + if(a) + { + atomicValue = a; + atomicValue->ref.ref(); + + /* Signal that we're housing an atomic value. */ + node.model = reinterpret_cast(~0); + } + else + node.model = 0; /* Like the default constructor. */ + } + + inline ~Item() + { + if(isAtomicValue() && !atomicValue->ref.deref()) + delete atomicValue; + } + + inline Item &operator=(const Item &other) + { + Q_ASSERT_X(sizeof(QXmlNodeModelIndex) >= sizeof(AtomicValue *), Q_FUNC_INFO, + "If this doesn't hold, we won't copy all data."); + + if(other.isAtomicValue()) + other.atomicValue->ref.ref(); + + if(isAtomicValue()) + { + if(!atomicValue->ref.deref()) + delete atomicValue; + } + + node = other.node; + + return *this; + } + + template + inline TCastTarget *as() const + { +#if defined(Patternist_DEBUG) && !defined(Q_CC_XLC) +/* At least on aix-xlc-64, the compiler cries when it sees dynamic_cast. */ + Q_ASSERT_X(atomicValue == 0 || dynamic_cast(atomicValue), + Q_FUNC_INFO, + "The cast is invalid. This class does not inherit the cast target."); +#endif + return const_cast(static_cast(atomicValue)); + } + + /** + * @short Returns the string value of this Item. + * + * In the case of a node, it is the node value corresponding to + * the particular node type. For atomic values, it is equivalent + * to the value cast as xs:string. + * + * Conceptually, this functions corresponds to the dm:string-value accessor. + * + * @see XQuery 1.0 and + * XPath 2.0 Data Model, 5.13 string-value Accessor + * @returns the string value. + */ + inline QString stringValue() const + { + if(isAtomicValue()) + return atomicValue->stringValue(); + else + return asNode().stringValue(); + } + + /** + * @short Returns the typed value of this item. + * + * Conceptually, this functions corresponds to the dm:typed-value accessor. Here are + * examples of what the typed value of an Item is: + * + * - The typed value of an atomic value is always the atomic value itself. + * - A comment node has always a typed value of type @c xs:string + * - For attribute and element nodes, the typed value can be arbitrary. For example, an + * element can have a sequence of @c xs:dateTime instances. + * + * @returns the typed value of this item + * @see XQuery 1.0 and + * XPath 2.0 Data Model, 5.15 typed-value Accessor + */ + Item::Iterator::Ptr sequencedTypedValue() const; + + /** + * @short Determines whether this item is an atomic value, or a node. + * + * If this Item is @c null, @c false is returned. + * + * @see isNode() + * @returns @c true if it is an atomic value, otherwise @c false. + */ + inline bool isAtomicValue() const + { + /* Setting node.model to ~0, signals that it's an atomic value. */ + return node.model == reinterpret_cast(~0); + } + + /** + * @short Determines whether this item is an atomic value, or a node. + * + * If this Item is @c null, false is returned. + * + * @see isAtomicValue() + * @returns @c true if this item is a node, otherwise @c false. + */ + inline bool isNode() const + { + //return !isAtomicValue(); + return node.model && node.model != reinterpret_cast(~0); + } + + /** + * @short Returns the ItemType this Item is of. + * + * For example, if this Item is an XML node, more specifically a text node, + * text() is returned. That is, BuiltinTypes::text. However, if this + * Item is an atomic value of type xs:long that is what's returned, + * BuiltinTypes::xsLong. + * + * @returns the type of this Item. + */ + inline QExplicitlySharedDataPointer type() const + { + if(isAtomicValue()) + return atomicValue->type(); + else + return asNode().type(); + } + + inline const AtomicValue *asAtomicValue() const + { + Q_ASSERT(isAtomicValue()); + return atomicValue; + } + + inline const QXmlNodeModelIndex &asNode() const + { + Q_ASSERT_X(isNode() || isNull(), Q_FUNC_INFO, + "This item isn't a valid QXmlNodeModelIndex."); + Q_ASSERT_X(sizeof(QXmlNodeModelIndex) == sizeof(QPatternist::NodeIndexStorage), Q_FUNC_INFO, + "If this doesn't hold, something is wrong."); + + return reinterpret_cast(node); + } + + inline operator bool() const + { + return node.model; + } + + inline bool isNull() const + { + return !node.model; + } + + inline void reset() + { + /* Note that this function should be equal to the default + * constructor. */ + node.model = 0; + node.data = 0; + } + + static inline Item fromPublic(const QXmlItem &i) + { + const Item it(i.m_node); + if(it.isAtomicValue()) + it.asAtomicValue()->ref.ref(); + + return it; + } + + static inline QXmlItem toPublic(const Item &i) + { + return QXmlItem(i); + } + + private: + union + { + NodeIndexStorage node; + const AtomicValue *atomicValue; + }; + }; + + template + inline Item toItem(const QExplicitlySharedDataPointer atomicValue) + { + return Item(atomicValue.data()); + } + + /** + * This is an overload, provided for convenience. + * @relates QXmlNodeModelIndex + */ + static inline QString formatData(const QXmlNodeModelIndex node) + { + return node.stringValue(); // This can be improved a lot. + } +} + + inline QXmlName QXmlNodeModelIndex::name() const + { + return m_storage.model->name(*this); + } + + inline QXmlNodeModelIndex QXmlNodeModelIndex::root() const + { + return m_storage.model->root(*this); + } + + inline QXmlNodeModelIndex::Iterator::Ptr QXmlNodeModelIndex::iterate(const QXmlNodeModelIndex::Axis axis) const + { + return m_storage.model->iterate(*this, axis); + } + + inline QUrl QXmlNodeModelIndex::documentUri() const + { + return m_storage.model->documentUri(*this); + } + + inline QUrl QXmlNodeModelIndex::baseUri() const + { + return m_storage.model->baseUri(*this); + } + + inline QXmlNodeModelIndex::NodeKind QXmlNodeModelIndex::kind() const + { + return m_storage.model->kind(*this); + } + + inline bool QXmlNodeModelIndex::isDeepEqual(const QXmlNodeModelIndex &other) const + { + return m_storage.model->isDeepEqual(*this, other); + } + + inline QXmlNodeModelIndex::DocumentOrder QXmlNodeModelIndex::compareOrder(const QXmlNodeModelIndex &other) const + { + Q_ASSERT_X(model() == other.model(), Q_FUNC_INFO, "The API docs guarantees the two nodes are from the same model"); + return m_storage.model->compareOrder(*this, other); + } + + inline bool QXmlNodeModelIndex::is(const QXmlNodeModelIndex &other) const + { + return m_storage.model == other.m_storage.model && + m_storage.data == other.m_storage.data && + m_storage.additionalData == other.m_storage.additionalData; + } + + inline void QXmlNodeModelIndex::sendNamespaces(QAbstractXmlReceiver *const receiver) const + { + m_storage.model->sendNamespaces(*this, receiver); + } + + inline QVector QXmlNodeModelIndex::namespaceBindings() const + { + return m_storage.model->namespaceBindings(*this); + } + + inline QXmlName::NamespaceCode QXmlNodeModelIndex::namespaceForPrefix(const QXmlName::PrefixCode prefix) const + { + return m_storage.model->namespaceForPrefix(*this, prefix); + } + + inline QString QXmlNodeModelIndex::stringValue() const + { + return m_storage.model->stringValue(*this); + } + + inline QPatternist::ItemType::Ptr QXmlNodeModelIndex::type() const + { + return m_storage.model->type(*this); + } + + inline QExplicitlySharedDataPointer > QXmlNodeModelIndex::sequencedTypedValue() const + { + return m_storage.model->sequencedTypedValue(*this); + } + + inline QXmlItem::QXmlItem(const QPatternist::Item &i) : m_node(i.node) + { + if(isAtomicValue()) + m_atomicValue->ref.ref(); + } + +Q_DECLARE_TYPEINFO(QPatternist::Item::Iterator::Ptr, Q_MOVABLE_TYPE); +Q_DECLARE_TYPEINFO(QPatternist::AtomicValue, Q_MOVABLE_TYPE); + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qnodebuilder.cpp b/src/xmlpatterns/data/qnodebuilder.cpp new file mode 100644 index 0000000..2463a4d --- /dev/null +++ b/src/xmlpatterns/data/qnodebuilder.cpp @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qnodebuilder_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qnodebuilder_p.h b/src/xmlpatterns/data/qnodebuilder_p.h new file mode 100644 index 0000000..e311d63 --- /dev/null +++ b/src/xmlpatterns/data/qnodebuilder_p.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_NodeBuilder_H +#define Patternist_NodeBuilder_H + +#include "qitem_p.h" +#include "qabstractxmlreceiver.h" +#include "qautoptr_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Receives QAbstractXmlReceiver events and builds a node tree + * in memory that afterwards can be retrieved via builtNode() + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class NodeBuilder : public QAbstractXmlReceiver + { + public: + typedef AutoPtr Ptr; + + inline NodeBuilder() + { + } + + /** + * @short Returns the document that has been built. + * + * If this function is called before any events have been received, the result is undefined. + * + * The top node that was constructed can be retrieved by calling + * NodeModel::root() on the returned NodeModel. + * + * This function is not @c const, because some implementations delay + * the node construction until the node is needed. Also, text nodes are + * difficult, at best, to construct until one knows that all text content + * has been received(which a call to this function in a natural way + * signals). + */ + virtual QAbstractXmlNodeModel::Ptr builtDocument() = 0; + + /** + * @short Creates a copy of this NodeBuilder, that operates independently of + * this NodeBuilder. + * + * The caller owns the returned instance. + */ + virtual NodeBuilder::Ptr create(const QUrl &baseURI) const = 0; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qnodemodel.cpp b/src/xmlpatterns/data/qnodemodel.cpp new file mode 100644 index 0000000..5d713c3 --- /dev/null +++ b/src/xmlpatterns/data/qnodemodel.cpp @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qnamespaceresolver_p.h" + +#include "qitem_p.h" + +QT_BEGIN_NAMESPACE + + + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qqnamevalue.cpp b/src/xmlpatterns/data/qqnamevalue.cpp new file mode 100644 index 0000000..72ab6eb --- /dev/null +++ b/src/xmlpatterns/data/qqnamevalue.cpp @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qanyuri_p.h" +#include "qbuiltintypes_p.h" +#include "qxpathhelper_p.h" + +#include "qqnamevalue_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +QNameValue::QNameValue(const NamePool::Ptr &np, const QXmlName name) : m_qName(name) + , m_namePool(np) +{ + Q_ASSERT(!name.isNull()); + Q_ASSERT(m_namePool); +} + +QNameValue::Ptr QNameValue::fromValue(const NamePool::Ptr &np, const QXmlName name) +{ + Q_ASSERT(!name.isNull()); + return QNameValue::Ptr(new QNameValue(np, name)); +} + +QString QNameValue::stringValue() const +{ + return m_namePool->toLexical(m_qName); +} + +ItemType::Ptr QNameValue::type() const +{ + return BuiltinTypes::xsQName; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qqnamevalue_p.h b/src/xmlpatterns/data/qqnamevalue_p.h new file mode 100644 index 0000000..93edbc7 --- /dev/null +++ b/src/xmlpatterns/data/qqnamevalue_p.h @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_QNameValue_H +#define Patternist_QNameValue_H + +#include "qitem_p.h" +#include "qxmlname.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the value instance of the @c xs:QName type. + * + * @author Frans Englich + * @ingroup Patternist_xdm + * @see QNameConstructor::expandQName() + * @see XPathHelper::isQName() + * @see QXmlUtils + */ + class QNameValue : public AtomicValue + { + public: + friend class CommonValues; + friend class QNameComparator; + + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Constructs a QNameValue that represents @p name. + * + * @param name the QName. May not be @c null. + * @param np the NamePool. + * @see QNameConstructor::expandQName() + * @see XPathHelper::isQName() + * @see QXmlUtils + */ + static QNameValue::Ptr fromValue(const NamePool::Ptr &np, const QXmlName name); + + virtual QString stringValue() const; + + virtual ItemType::Ptr type() const; + + inline QXmlName qName() const + { + return m_qName; + } + + private: + QNameValue(const NamePool::Ptr &np, const QXmlName name); + + const QXmlName m_qName; + const NamePool::Ptr m_namePool; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qresourceloader.cpp b/src/xmlpatterns/data/qresourceloader.cpp new file mode 100644 index 0000000..c727253 --- /dev/null +++ b/src/xmlpatterns/data/qresourceloader.cpp @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + + +#include "qresourceloader_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +ResourceLoader::~ResourceLoader() +{ +} + +bool ResourceLoader::isUnparsedTextAvailable(const QUrl &uri, + const QString &encoding) +{ + Q_ASSERT(uri.isValid()); + Q_ASSERT(!uri.isRelative()); + Q_UNUSED(uri); /* Needed when compiling in release mode. */ + Q_UNUSED(encoding); + return false; +} + +ItemType::Ptr ResourceLoader::announceUnparsedText(const QUrl &uri) +{ + Q_ASSERT(uri.isValid()); + Q_ASSERT(!uri.isRelative()); + Q_UNUSED(uri); /* Needed when compiling in release mode. */ + return ItemType::Ptr(); +} + +Item ResourceLoader::openUnparsedText(const QUrl &uri, + const QString &encoding, + const ReportContext::Ptr &context, + const SourceLocationReflection *const where) +{ + Q_ASSERT(uri.isValid()); + Q_ASSERT(!uri.isRelative()); + Q_UNUSED(uri); /* Needed when compiling in release mode. */ + Q_UNUSED(encoding); + Q_UNUSED(context); + Q_UNUSED(where); + return Item(); +} + +Item ResourceLoader::openDocument(const QUrl &uri, + const ReportContext::Ptr &context) +{ + Q_ASSERT(uri.isValid()); + Q_ASSERT(!uri.isRelative()); + Q_UNUSED(uri); /* Needed when compiling in release mode. */ + Q_UNUSED(context); /* Needed when compiling in release mode. */ + return Item(); +} + +SequenceType::Ptr ResourceLoader::announceDocument(const QUrl &uri, const Usage) +{ + Q_ASSERT(uri.isValid()); + Q_ASSERT(!uri.isRelative()); + Q_UNUSED(uri); /* Needed when compiling in release mode. */ + return SequenceType::Ptr(); +} + +bool ResourceLoader::isDocumentAvailable(const QUrl &uri) +{ + Q_ASSERT(uri.isValid()); + Q_ASSERT(!uri.isRelative()); + Q_UNUSED(uri); /* Needed when compiling in release mode. */ + return false; +} + +Item::Iterator::Ptr ResourceLoader::openCollection(const QUrl &uri) +{ + Q_ASSERT(uri.isValid()); + Q_ASSERT(!uri.isRelative()); + Q_UNUSED(uri); /* Needed when compiling in release mode. */ + return Item::Iterator::Ptr(); +} + +SequenceType::Ptr ResourceLoader::announceCollection(const QUrl &uri) +{ + Q_ASSERT(uri.isValid()); + Q_ASSERT(!uri.isRelative()); + Q_UNUSED(uri); /* Needed when compiling in release mode. */ + return SequenceType::Ptr(); +} + +void ResourceLoader::clear(const QUrl &uri) +{ + Q_UNUSED(uri); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qresourceloader_p.h b/src/xmlpatterns/data/qresourceloader_p.h new file mode 100644 index 0000000..4ed4342 --- /dev/null +++ b/src/xmlpatterns/data/qresourceloader_p.h @@ -0,0 +1,320 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ResourceLoader_H +#define Patternist_ResourceLoader_H + +#include "qitem_p.h" +#include "qreportcontext_p.h" +#include "qsequencetype_p.h" +#include "qsourcelocationreflection_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QUrl; + +namespace QPatternist +{ + /** + * @short Responsible for handling requests for opening files and node collections. + * + * ResourceLoader is a callback used for opening files, requested + * via the functions fn:document() and fn:unparsed-text(); + * and node collections, requested via fn:collection(). Patternist uses the + * ResourceLoader at compile time, + * via StaticContext::resourceLoader(), and at runtime, via DynamicContext::resourceLoader(). + * + * The ResourceLoader takes care of loading "external resources" in a way specific to the data + * model Patternist is using. For example, perhaps the opening of documents should pass + * a security policy, or a collection should map to nodes in a virtual filesystem or a database. + * + * From Patternist's perspective, the ResourceLoader provides two things: + * + * - At compile time, it calls announceDocument(), announceCollection() and announceUnparsedText() + * if it knows the URIs at compile time in order to retrieve the static types of the data the URIs + * maps to. This is used for more efficiently compiling the query and to better report errors + * at compile time. + * - To open document and node collections at runtime. + * + * From the user's or the data model's perspective, the ResourceLoader most notably provides + * a hint to what resources a query will load at runtime, and therefore provides an opportunity + * to prepare in advance for that. For example, between the compile and runtime stage, + * the ResourceLoader sub-class can be asked to pre-load documents in an asynchronous + * and simultaneous way, such that the runtime stage is faster and doesn't + * freeze a graphical interface. + * + * The announce functions are not guaranteed to be called. The loading functions can be called + * with an URI that an announce function hasn't been called with. + * + * The default implementations of ResourceLoader's virtual functions all signals that no + * resources can be loaded. This means ResourceLoader must be sub-classed, in order to + * be able to load resources. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class Q_AUTOTEST_EXPORT ResourceLoader : public QSharedData + { + public: + enum Usage + { + /** + * Communicates that the URI may be used during query evaluation. + * For example, zero times or very many times. + * + * Typically this hint is given when the URI is available at + * compile-time, but it is used inside a conditional statement + * whose branching cannot be determined at compile time. + */ + MayUse, + + /** + * Communicates that the URI will always be used at query + * evaluation. + */ + WillUse + }; + + typedef QExplicitlySharedDataPointer Ptr; + inline ResourceLoader() {} + virtual ~ResourceLoader(); + + /** + * @short Calls to this function are generated by calls to the + * fn:unparsed-text-available() function. + * + * @param uri A URI identifying the resource to retrieve. The URI is guaranteed + * to be valid(QUrl::isValid() returns @c true) and to be absolute(QUrl::isRelative() + * returns @c false). + * @returns @c true if calling openUnparsedText() while passing @p uri will successfully load + * the document. + * @see XSL Transformations + * (XSLT) Version 2.0, 16.2 Reading Text Files + */ + virtual bool isUnparsedTextAvailable(const QUrl &uri, + const QString &encoding); + + /** + * @short May be called by the compilation framework at compile time to report that an + * unparsed text(plain text) file referenced by @p uri will be loaded at runtime. + * + * This function can be called an arbitrary amount of times for the same URI. How many times + * it is called for a URI has no meaning(beyond the first call, that is). For what queries + * the compilation framework can determine what always will be loaded is generally undefined. It + * depends on factors such as how simple the query is what information that is statically + * available and subsequently what optimizations that can apply. + * + * Calls to this function are generated by calls to the fn:unparsed-text() function. + * + * @param uri A URI identifying the resource to retrieve. The URI is guaranteed + * to be valid(QUrl::isValid() returns @c true) and to be absolute(QUrl::isRelative() + * returns @c false). + * @see XSL Transformations + * (XSLT) Version 2.0, 16.2 Reading Text Files + * @returns + * - @c null if no unparsed file can be loaded for @p uri + * - The item type that the value loaded by @p uri will be an instance of. This is + * typically @c xs:string + */ + virtual ItemType::Ptr announceUnparsedText(const QUrl &uri); + + /** + * @short Calls to this function are generated by calls to the fn:unparsed-text() function. + * + * @param uri A URI identifying the resource to retrieve. The URI is guaranteed + * to be valid(QUrl::isValid() returns @c true) and to be absolute(QUrl::isRelative() + * returns @c false). + * @param encoding the encoding to use. If empty, the user hasn't + * expressed any encoding to use. + * @see XSL Transformations + * (XSLT) Version 2.0, 16.2 Reading Text Files + * @returns + * - @c null if no unparsed file can be loaded for @p uri + * - An @c xs:string value(or subtype) containing the content of the file identified + * by @p uri as text. Remember that its type must match the sequence type + * returned by announceUnparsedText() + */ + virtual Item openUnparsedText(const QUrl &uri, + const QString &encoding, + const ReportContext::Ptr &context, + const SourceLocationReflection *const where); + + /** + * @short Calls to this function are generated by calls to the fn:document() + * or fn:doc() function. + * + * @note This function is responsible for execution stability. Subsequent calls + * to this function with the same URI should result in QXmlNodeModelIndex instances that have + * the same identity. However, in some cases this stability is not of interest, see + * the specification for details. + * @param uri A URI identifying the resource to retrieve. The URI is guaranteed + * to be valid(QUrl::isValid() returns @c true) and to be absolute(QUrl::isRelative() + * returns @c false). + * @see QXmlNodeModelIndex::identity() + * @see XQuery 1.0 + * and XPath 2.0 Functions and Operators, 15.5.4 fn:doc + * @see XSL Transformations + * (XSLT) Version 2.0, 16.1 Multiple Source Documents + * @returns + * - @c null if no document can be loaded for @p uri + * - A QXmlNodeModelIndex representing the document identified by @p uri. Remember that the QXmlNodeModelIndex + * must match the sequence type returned by announceDocument() + */ + virtual Item openDocument(const QUrl &uri, + const ReportContext::Ptr &context); + + /** + * @short May be called by the compilation framework at compile time to report that an + * XML document referenced by @p uri will be loaded at runtime. + * + * This function can be called an arbitrary amount of times for the same URI, but different + * @p usageHint values. How many times it is called for a URI has no meaning(beyond the first call, + * that is). For what queries the compilation framework can determine what always will be + * loaded is generally undefined. It + * depends on factors such as the complexity of the query, what information that is statically + * available and subsequently what optimizations that can be applied. + * + * Calls to this function are generated by calls to the fn:document() + * or fn:doc() function. + * + * @param uri A URI identifying the resource to retrieve. The URI is guaranteed + * to be valid(QUrl::isValid() returns @c true) and to be absolute(QUrl::isRelative() + * returns @c false). + * @param usageHint A hint to how the URI will be used. + * @returns + * - @c null if the ResourceLoader can determine at this stage that no document + * referenced by @p uri will ever be possible to load. + * - The appropriate sequence type if loading @p uri succeeds at runtime. This must be + * CommonSequenceTypes::zeroOrOneDocument, CommonSequenceTypes::exactlyOneDocument or + * a sequence type that is a sub type of it. + * @see XQuery 1.0 + * and XPath 2.0 Functions and Operators, 15.5.4 fn:doc + * @see XSL Transformations + * (XSLT) Version 2.0, 16.1 Multiple Source Documents + */ + virtual SequenceType::Ptr announceDocument(const QUrl &uri, const Usage usageHint); + + /** + * @short Calls to this function are generated by calls to the fn:doc-available() function. + * + * @param uri A URI identifying the resource to retrieve. The URI is guaranteed + * to be valid(QUrl::isValid() returns @c true) and to be absolute(QUrl::isRelative() + * returns @c false). + * @returns @c true if calling openDocument() while passing @p uri will successfully load + * the document. + * @see XQuery 1.0 + * and XPath 2.0 Functions and Operators, 15.5.5 fn:doc-available + * @see XSL Transformations + * (XSLT) Version 2.0, 16.1 Multiple Source Documents + */ + virtual bool isDocumentAvailable(const QUrl &uri); + + /** + * @short Calls to this function are generated by calls to the fn:collection() function. + * + * @param uri A URI identifying the resource to retrieve. The URI is guaranteed + * to be valid(QUrl::isValid() returns @c true) and to be absolute(QUrl::isRelative() + * returns @c false). + * @see XQuery 1.0 + * and XPath 2.0 Functions and Operators, 15.5.6 fn:collection + * @returns + * - @c null if no node collection can be loaded for @p uri + * - An QAbstractXmlForwardIterator representing the content identified by @p uri. Remember that the content + * of the QAbstractXmlForwardIterator must match the sequence type returned by announceCollection() + */ + virtual Item::Iterator::Ptr openCollection(const QUrl &uri); + + /** + * @short May be called by the compilation framework at compile time to report that an + * node collection referenced by @p uri will be loaded at runtime. + * + * This function can be called an arbitrary amount of times for the same URI. How many times + * it is called for a URI has no meaning(beyond the first call, that is). For what queries + * the compilation framework can determine what always will be loaded is generally undefined. It + * depends on factors such as how simple the query is what information that is statically + * available and subsequently what optimizations that can apply. + * + * Calls to this function are generated by calls to the fn:collection() function. + * + * @note This function is responsible for execution stability. Subsequent calls + * to this function with the same URI should result in QXmlNodeModelIndex instances that have + * the same identity. However, in some cases this stability is not of interest, see + * the specification for details. + * @param uri A URI identifying the resource to retrieve. The URI is guaranteed + * to be valid(QUrl::isValid() returns @c true) and to be absolute(QUrl::isRelative() + * returns @c false). + * @returns + * - @c null if the ResourceLoader can determine at this stage that no document + * referenced by @p uri will ever be possible to load. + * - The appropriate sequence type if loading @p uri succeeds at runtime. This must be + * CommonSequenceTypes::zeroOrMoreNodes or a sequence type that is a sub type of it. + * @see XQuery 1.0 + * and XPath 2.0 Functions and Operators, 15.5.6 fn:collection + */ + virtual SequenceType::Ptr announceCollection(const QUrl &uri); + + /** + * @short Asks to unload @p uri from its document pool, such that a + * subsequent request will require a new read. + * + * The default implementation does nothing. + */ + virtual void clear(const QUrl &uri); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qschemadatetime.cpp b/src/xmlpatterns/data/qschemadatetime.cpp new file mode 100644 index 0000000..b91f5f1 --- /dev/null +++ b/src/xmlpatterns/data/qschemadatetime.cpp @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" +#include "qitem_p.h" + +#include "qschemadatetime_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +DateTime::DateTime(const QDateTime &dateTime) : AbstractDateTime(dateTime) +{ +} + +DateTime::Ptr DateTime::fromLexical(const QString &lexical) +{ + static const CaptureTable captureTable( // STATIC DATA + /* The extra paranthesis is a build fix for GCC 3.3. */ + (QRegExp(QLatin1String( + "^\\s*" /* Any preceding whitespace. */ + "(-?)" /* Any preceding minus. */ + "(\\d{4,})" /* The year part. */ + "-" /* Delimiter. */ + "(\\d{2})" /* The month part. */ + "-" /* Delimiter. */ + "(\\d{2})" /* The day part. */ + "T" /* Delimiter. */ + "(\\d{2})" /* Hour part */ + ":" /* Delimiter. */ + "(\\d{2})" /* Minutes part */ + ":" /* Delimiter. */ + "(\\d{2,})" /* Seconds part. */ + "(?:\\.(\\d+))?" /* Milli seconds part. */ + "(?:(\\+|-)(\\d{2}):(\\d{2})|(Z))?" /* The zone offset, "+08:24". */ + "\\s*$" /* Any whitespace at the end. */))), + /*zoneOffsetSignP*/ 9, + /*zoneOffsetHourP*/ 10, + /*zoneOffsetMinuteP*/ 11, + /*zoneOffsetUTCSymbolP*/ 12, + /*yearP*/ 2, + /*monthP*/ 3, + /*dayP*/ 4, + /*hourP*/ 5, + /*minutesP*/ 6, + /*secondsP*/ 7, + /*msecondsP*/ 8, + /*yearSignP*/ 1); + + AtomicValue::Ptr err; + const QDateTime retval(create(err, lexical, captureTable)); + + return err ? err : DateTime::Ptr(new DateTime(retval)); +} + +DateTime::Ptr DateTime::fromDateTime(const QDateTime &dt) +{ + Q_ASSERT(dt.isValid()); + return DateTime::Ptr(new DateTime(dt)); +} + +Item DateTime::fromValue(const QDateTime &dt) const +{ + Q_ASSERT(dt.isValid()); + return fromDateTime(dt); +} + +QString DateTime::stringValue() const +{ + return dateToString() + QLatin1Char('T') + timeToString() + zoneOffsetToString(); +} + +ItemType::Ptr DateTime::type() const +{ + return BuiltinTypes::xsDateTime; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qschemadatetime_p.h b/src/xmlpatterns/data/qschemadatetime_p.h new file mode 100644 index 0000000..a92b27b --- /dev/null +++ b/src/xmlpatterns/data/qschemadatetime_p.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_DateTime_H +#define Patternist_DateTime_H + +#include "qabstractdatetime_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +/** + * @file + * @short Contains class DateTime. This file was originally called qdatetime_p.h, + * but various build systems cannot handle that that name happens to be + * identical to another one, the one in QtCore. + */ + +namespace QPatternist +{ + /** + * @short Implements the value instance of the @c xs:dateTime type. + * + * @author Frans Englich + * @ingroup Patternist_xdm + */ + class DateTime : public AbstractDateTime + { + public: + typedef AtomicValue::Ptr Ptr; + + /** + * Creates an instance from the lexical representation @p string. + */ + static DateTime::Ptr fromLexical(const QString &string); + static DateTime::Ptr fromDateTime(const QDateTime &dt); + virtual ItemType::Ptr type() const; + virtual QString stringValue() const; + virtual Item fromValue(const QDateTime &dt) const; + + protected: + friend class CommonValues; + + DateTime(const QDateTime &dateTime); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qschemanumeric.cpp b/src/xmlpatterns/data/qschemanumeric.cpp new file mode 100644 index 0000000..f5cc323 --- /dev/null +++ b/src/xmlpatterns/data/qschemanumeric.cpp @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qabstractfloat_p.h" +#include "qboolean_p.h" +#include "qbuiltintypes_p.h" +#include "qcommonvalues_p.h" +#include "qdecimal_p.h" +#include "qinteger_p.h" + +#include "qschemanumeric_p.h" + +/** + * @file Contains class Numeric. This file was originally called qnumeric.cpp, + * but was renamed to stay consistent with qschemanumeric_p.h + */ + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +AtomicValue::Ptr Numeric::fromLexical(const QString &number) +{ + Q_ASSERT(!number.isEmpty()); + Q_ASSERT_X(!number.contains(QLatin1Char('e')) && + !number.contains(QLatin1Char('E')), + Q_FUNC_INFO, "Should not contain any e/E"); + + if(number.contains(QLatin1Char('.'))) /* an xs:decimal. */ + return Decimal::fromLexical(number); + else /* It's an integer, of some sort. E.g, -3, -2, -1, 0, 1, 2, 3 */ + return Integer::fromLexical(number); +} + +xsDouble Numeric::roundFloat(const xsDouble val) +{ + if(qIsInf(val) || AbstractFloat::isEqual(val, 0.0)) + return val; + else if(qIsNaN(val)) + return val; + else + { + if(val >= -0.5 && val < 0) + return -0.0; + else + return ::floor(val + 0.5); + + } +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qschemanumeric_p.h b/src/xmlpatterns/data/qschemanumeric_p.h new file mode 100644 index 0000000..792eb58 --- /dev/null +++ b/src/xmlpatterns/data/qschemanumeric_p.h @@ -0,0 +1,235 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_Numeric_H +#define Patternist_Numeric_H + +#include "qitem_p.h" +#include "qprimitives_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +/** + * @file + * @short Contains class Numeric. This file was originally called qnumeric_p.h, + * but various build systems cannot handle that that name happens to be + * identical to another one, the one in QtCore. + */ + +namespace QPatternist +{ + /** + * @short Base class for all numeric values. + * + * @section creation Creating Instances + * + * @todo + * - Depending on what type of val + * - Numeric::createFromString + * - Various classes has ::Zero(), ::PosINF(), ::NaN(), NegINF() + * - Never use constructor, use createFromNative, or createFromString. + * + * @see XQuery 1.0 + * and XPath 2.0 Functions and Operators, 6 Functions and Operators on Numerics + * @see XQuery 1.0 + * and XPath 2.0 Functions and Operators, 1.2 Function Overloading + * @author Frans Englich + * @ingroup Patternist_xdm + * @todo discuss data hierarchy the non existatnt number data type + */ + class Numeric : public AtomicValue + { + public: + + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Creates a Numeric sub-class that is appropriate for @p number. + * + * @note usages of e/E is not handled; Double::fromLexical should + * be used in that case. There is no function similar to fromLexical that also + * takes double values into account(because that distinction is done in the scanner). + * + * Currently used in the parser to create appropriate expressions. + */ + static AtomicValue::Ptr fromLexical(const QString &number); + + /** + * @returns the particular number's value as a native representation of + * the type xs:double. This can be considered that the value is cast to + * xs:double. + */ + virtual xsDouble toDouble() const = 0; + + /** + * @returns the particular number's value as a native representation of + * the type xs:integer. This can be considered that the value is cast to + * xs:integer. + */ + virtual xsInteger toInteger() const = 0; + + /** + * @returns the number as an unsigned integer. If the value is not + * unsigned, the code asserts and behavior is undefined. + */ + virtual qulonglong toUnsignedInteger() const = 0; + + /** + * @returns the particular number's value as a native representation of + * the type xs:float. This can be considered that the value is cast to + * xs:float. + */ + virtual xsFloat toFloat() const = 0; + + /** + * @returns the particular number's value as a native representation of + * the type xs:decimal. This can be considered that the value is cast to + * xs:decimal. + */ + virtual xsFloat toDecimal() const = 0; + + /** + * Performs the algorithm specified for the function fn:round on this Numeric, + * and whose result is returned. + * + * @see XQuery 1.0 + * and XPath 2.0 Functions and Operators, 6.4.4 fn:round + */ + virtual Numeric::Ptr round() const = 0; + + /** + * Performs rounding as defined for the fn:round-half-to-even on this Numeric, + * and whose result is returned. + * + * @see XQuery 1.0 + * and XPath 2.0 Functions and Operators, 6.4.5 fn:round-half-to-even + */ + virtual Numeric::Ptr roundHalfToEven(const xsInteger scale) const = 0; + + /** + * Performs the algorithm specified for the function fn:floor on this Numeric, + * and whose result is returned. + * + * @see XQuery 1.0 + * and XPath 2.0 Functions and Operators, 6.4.3 fn:floor + */ + virtual Numeric::Ptr floor() const = 0; + + /** + * Performs the algorithm specified for the function fn:ceiling on this Numeric, + * and whose result is returned. + * + * @see XQuery 1.0 + * and XPath 2.0 Functions and Operators, 6.4.2 fn:ceiling + */ + virtual Numeric::Ptr ceiling() const = 0; + + /** + * Performs the algorithm specified for the function fn:abs on this Numeric, + * and whose result is returned. + * + * @see XQuery 1.0 + * and XPath 2.0 Functions and Operators, 6.4.1 fn:abs + */ + virtual Numeric::Ptr abs() const = 0; + + /** + * Determines whether this Numeric is not-a-number, @c NaN. For numeric types + * that cannot represent @c NaN, this function should return @c false. + * + * @returns @c true if this Numeric is @c NaN + */ + virtual bool isNaN() const = 0; + + /** + * Determines whether this Numeric is an infinite number. Signedness + * is irrelevant, -INF as well as INF is considered infinity. + * + * For numeric types that cannot represent infinity, such as xs:integer + * , this function should return @c false. + * + * @returns @c true if this Numeric is an infinite number + */ + virtual bool isInf() const = 0; + + /** + * Unary minus. + */ + virtual Item toNegated() const = 0; + + /** + * @short Returns @c true if this value is signed. If @c false is + * returned, the value is unsigned. + * + * For float and decimal values, @c xs:double, @c xs:float and @c + * xs:decimal, the code asserts and behavior is undefined. + */ + virtual bool isSigned() const = 0; + + protected: + /** + * @short Implements @c fn:round() for types implemented with floating + * point. + * + * MS Windows and at least IRIX does not have C99's nearbyint() function(see the man + * page), so we reinvent it. + */ + static xsDouble roundFloat(const xsDouble val); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qschematime.cpp b/src/xmlpatterns/data/qschematime.cpp new file mode 100644 index 0000000..dc382d8 --- /dev/null +++ b/src/xmlpatterns/data/qschematime.cpp @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" +#include "qitem_p.h" + +#include "qschematime_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +SchemaTime::SchemaTime(const QDateTime &dateTime) : AbstractDateTime(dateTime) +{ +} + +SchemaTime::Ptr SchemaTime::fromLexical(const QString &lexical) +{ + static const CaptureTable captureTable( // STATIC DATA + /* The extra paranthesis is a build fix for GCC 3.3. */ + (QRegExp(QLatin1String( + "^\\s*" /* Any preceding whitespace. */ + "(\\d{2})" /* Hour part */ + ":" /* Delimiter. */ + "(\\d{2})" /* Minutes part */ + ":" /* Delimiter. */ + "(\\d{2,})" /* Seconds part. */ + "(?:\\.(\\d+))?" /* Milli seconds part. */ + "(?:(\\+|-)(\\d{2}):(\\d{2})|(Z))?" /* The zone offset, "+08:24". */ + "\\s*$" /* Any terminating whitespace. */))), + /*zoneOffsetSignP*/ 5, + /*zoneOffsetHourP*/ 6, + /*zoneOffsetMinuteP*/ 7, + /*zoneOffsetUTCSymbolP*/ 8, + /*yearP*/ -1, + /*monthP*/ -1, + /*dayP*/ -1, + /*hourP*/ 1, + /*minutesP*/ 2, + /*secondsP*/ 3, + /*msecondsP*/ 4); + + AtomicValue::Ptr err; + const QDateTime retval(create(err, lexical, captureTable)); + + return err ? err : SchemaTime::Ptr(new SchemaTime(retval)); +} + +SchemaTime::Ptr SchemaTime::fromDateTime(const QDateTime &dt) +{ + Q_ASSERT(dt.isValid()); + /* Singleton value, allocated once instead of each time it's needed. */ + // STATIC DATA + static const QDate time_defaultDate(AbstractDateTime::DefaultYear, + AbstractDateTime::DefaultMonth, + AbstractDateTime::DefaultDay); + + QDateTime result; + copyTimeSpec(dt, result); + + result.setDate(time_defaultDate); + result.setTime(dt.time()); + + return SchemaTime::Ptr(new SchemaTime(result)); +} + +Item SchemaTime::fromValue(const QDateTime &dt) const +{ + Q_ASSERT(dt.isValid()); + return fromDateTime(dt); +} + +QString SchemaTime::stringValue() const +{ + return timeToString() + zoneOffsetToString(); +} + +ItemType::Ptr SchemaTime::type() const +{ + return BuiltinTypes::xsTime; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qschematime_p.h b/src/xmlpatterns/data/qschematime_p.h new file mode 100644 index 0000000..1d89bc5 --- /dev/null +++ b/src/xmlpatterns/data/qschematime_p.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_Time_H +#define Patternist_Time_H + +#include "qabstractdatetime_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the value instance of the @c xs:time type. + * + * The header file for this class was originally called Time.h, but this + * clashed with a system header on MinGW. + * + * @author Frans Englich + * @ingroup Patternist_xdm + */ + class SchemaTime : public AbstractDateTime + { + public: + typedef AtomicValue::Ptr Ptr; + + /** + * Creates an instance from the lexical representation @p string. + */ + static SchemaTime::Ptr fromLexical(const QString &string); + static SchemaTime::Ptr fromDateTime(const QDateTime &dt); + + virtual ItemType::Ptr type() const; + virtual QString stringValue() const; + virtual Item fromValue(const QDateTime &dt) const; + + protected: + friend class CommonValues; + + SchemaTime(const QDateTime &dateTime); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qsequencereceiver.cpp b/src/xmlpatterns/data/qsequencereceiver.cpp new file mode 100644 index 0000000..212c514 --- /dev/null +++ b/src/xmlpatterns/data/qsequencereceiver.cpp @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qitem_p.h" + +#include "qabstractxmlreceiver.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +QAbstractXmlReceiver::~QAbstractXmlReceiver() +{ +} + +template +void QAbstractXmlReceiver::sendFromAxis(const QXmlNodeModelIndex &node) +{ + Q_ASSERT(!node.isNull()); + const QXmlNodeModelIndex::Iterator::Ptr it(node.iterate(axis)); + QXmlNodeModelIndex next(it->next()); + + while(!next.isNull()) + { + sendAsNode(next); + next = it->next(); + } +} + +void QAbstractXmlReceiver::sendAsNode(const Item &outputItem) +{ + Q_ASSERT(outputItem); + Q_ASSERT(outputItem.isNode()); + const QXmlNodeModelIndex asNode = outputItem.asNode(); + + switch(asNode.kind()) + { + case QXmlNodeModelIndex::Attribute: + { + attribute(asNode.name(), outputItem.stringValue()); + break; + } + case QXmlNodeModelIndex::Element: + { + startElement(asNode.name()); + + /* First the namespaces, then attributes, then the children. */ + asNode.sendNamespaces(Ptr(const_cast(this))); + sendFromAxis(asNode); + sendFromAxis(asNode); + + endElement(); + + break; + } + case QXmlNodeModelIndex::Text: + { + characters(outputItem.stringValue()); + break; + } + case QXmlNodeModelIndex::ProcessingInstruction: + { + processingInstruction(asNode.name(), outputItem.stringValue()); + break; + } + case QXmlNodeModelIndex::Comment: + { + comment(outputItem.stringValue()); + break; + } + case QXmlNodeModelIndex::Document: + { + sendFromAxis(asNode); + break; + } + case QXmlNodeModelIndex::Namespace: + Q_ASSERT_X(false, Q_FUNC_INFO, "Not implemented"); + } +} + +void QAbstractXmlReceiver::whitespaceOnly(const QStringRef &value) +{ + Q_ASSERT_X(value.toString().trimmed().isEmpty(), Q_FUNC_INFO, + "The caller must guarantee only whitespace is passed. Use characters() in other cases."); + characters(value.toString()); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qsequencereceiver_p.h b/src/xmlpatterns/data/qsequencereceiver_p.h new file mode 100644 index 0000000..b5490fd --- /dev/null +++ b/src/xmlpatterns/data/qsequencereceiver_p.h @@ -0,0 +1,192 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_SequenceReceiver_H +#define Patternist_SequenceReceiver_H + +#include + +#include "qitem_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A push interface for the XPath Data Model. Similar to SAX's + * ContentHandler. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class QAbstractXmlReceiver : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + inline QAbstractXmlReceiver() + { + } + + virtual ~QAbstractXmlReceiver(); + + /** + * @short Signals the start of an element by name @p name. + */ + virtual void startElement(const QXmlName name) = 0; + + /** + * @short Signals the presence of the namespace declaration @p nb. + * + * This event is received @c after startElement(), as opposed to + * SAX, and before any attribute() events. + */ + virtual void namespaceBinding(const QXmlName &nb) = 0; + + /** + * @short Signals the end of the current element. + */ + virtual void endElement() = 0; + + /** + * @short Signals the presence of an attribute node. + * + * This function is guaranteed by the caller to always be + * called after a call to startElement() or attribute(). + * + * @param name the name of the attribute. Guaranteed to always be + * non-null. + * @param value the value of the attribute. Guaranteed to always be + * non-null. + */ + virtual void attribute(const QXmlName name, + const QString &value) = 0; + + virtual void processingInstruction(const QXmlName name, + const QString &value) = 0; + virtual void comment(const QString &value) = 0; + + /** + * @short Sends an Item to this QAbstractXmlReceiver that may be a QXmlNodeModelIndex or an + * AtomicValue. + */ + virtual void item(const Item &item) = 0; + + /** + * Sends a text node with value @p value. Adjascent text nodes + * may be sent. There's no restrictions on @p value, beyond that it + * must be valid XML characters. For instance, @p value may contain + * only whitespace. + * + * @see whitespaceOnly() + */ + virtual void characters(const QString &value) = 0; + + /** + * This function may be called instead of characters() if, and only if, + * @p value consists only of whitespace. + * + * The caller gurantees that @p value, is not empty. + * + * By whitespace is meant a sequence of characters that are either + * spaces, tabs, or the two new line characters, in any order. In + * other words, the whole of Unicode's whitespace category is not + * considered whitespace. + * + * However, there's no guarantee or requirement that whitespaceOnly() + * is called for text nodes containing whitespace only, characters() + * may be called just as well. This is why the default implementation + * for whitespaceOnly() calls characters(). + * + * @see characters() + */ + virtual void whitespaceOnly(const QStringRef &value); + + /** + * Start of a document node. + */ + virtual void startDocument() = 0; + + /** + * End of a document node. + */ + virtual void endDocument() = 0; + + protected: + /** + * Treats @p outputItem as an node and calls the appropriate function, + * such as attribute() or comment(), depending on its QXmlNodeModelIndex::NodeKind. + * + * This a helper function sub-classes can use to multi-plex Nodes received + * via item(). + * + * @param outputItem must be a QXmlNodeModelIndex. + */ + void sendAsNode(const Item &outputItem); + + private: + /** + * Call sendAsNode() for each child of @p node. As consistent with the + * XPath Data Model, this does not include attribute nodes. + */ + template + inline void sendFromAxis(const QXmlNodeModelIndex &node); + Q_DISABLE_COPY(QAbstractXmlReceiver) + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qsorttuple.cpp b/src/xmlpatterns/data/qsorttuple.cpp new file mode 100644 index 0000000..598e67b --- /dev/null +++ b/src/xmlpatterns/data/qsorttuple.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qbuiltintypes_p.h" +#include "qsorttuple_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +bool SortTuple::isAtomicValue() const +{ + Q_ASSERT_X(false, Q_FUNC_INFO, + "It makes no sense to call this function."); + return false; +} + +QString SortTuple::stringValue() const +{ + return QLatin1String("SortTuple"); +} + +bool SortTuple::isNode() const +{ + Q_ASSERT_X(false, Q_FUNC_INFO, + "It makes no sense to call this function."); + return false; +} + +bool SortTuple::hasError() const +{ + Q_ASSERT_X(false, Q_FUNC_INFO, + "It makes no sense to call this function."); + return false; +} + +Item::Iterator::Ptr SortTuple::typedValue() const +{ + Q_ASSERT_X(false, Q_FUNC_INFO, + "It makes no sense to call this function."); + return Item::Iterator::Ptr(); +} + +ItemType::Ptr SortTuple::type() const +{ + return BuiltinTypes::xsAnyAtomicType; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qsorttuple_p.h b/src/xmlpatterns/data/qsorttuple_p.h new file mode 100644 index 0000000..b407274 --- /dev/null +++ b/src/xmlpatterns/data/qsorttuple_p.h @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_SortTuple_H +#define Patternist_SortTuple_H + +#include "qitem_p.h" +#include "qitem_p.h" +#include "qitemtype_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Represents a value and its sort keys + * in FLOWR's order by clause. + * + * SortTuple doesn't correspond to anything in the XPath Data Model and + * can therefore well be described as an exotic implementation detail. + * Most of its functions asserts because it makes no sense to + * call them. + * + * SortTuple exclusively exists for use with the expressions OrderBy and + * ReturnOrderBy, and acts as a carrier between those two for sort keys and + * source values. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class SortTuple : public AtomicValue + { + public: + /** + * @p aSortKeys may be empty. + */ + inline SortTuple(const Item::Iterator::Ptr &aValue, + const Item::Vector &aSortKeys) : m_sortKeys(aSortKeys), + m_value(aValue) + { + Q_ASSERT(m_value); + Q_ASSERT(!m_sortKeys.isEmpty()); + } + + /** + * A smart pointer wrapping SortTuple instances. + */ + typedef QExplicitlySharedDataPointer Ptr; + + /** + * This function is sometimes called by Literal::description(). + * This function simply returns "SortTuple". + */ + virtual QString stringValue() const; + + /** + * @short Always asserts. + */ + virtual Item::Iterator::Ptr typedValue() const; + + /** + * @short Always asserts. + */ + virtual bool isAtomicValue() const; + + /** + * @short Always asserts. + */ + virtual bool isNode() const; + + /** + * @short Always asserts. + */ + virtual bool hasError() const; + + virtual ItemType::Ptr type() const; + + inline const Item::Vector &sortKeys() const + { + return m_sortKeys; + } + + inline const Item::Iterator::Ptr &value() const + { + return m_value; + } + + private: + const Item::Vector m_sortKeys; + const Item::Iterator::Ptr m_value; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/quntypedatomic.cpp b/src/xmlpatterns/data/quntypedatomic.cpp new file mode 100644 index 0000000..ccb65d7 --- /dev/null +++ b/src/xmlpatterns/data/quntypedatomic.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" + +#include "quntypedatomic_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +UntypedAtomic::UntypedAtomic(const QString &s) : AtomicString(s) +{ +} + +UntypedAtomic::Ptr UntypedAtomic::fromValue(const QString &value) +{ + return UntypedAtomic::Ptr(new UntypedAtomic(value)); +} + +ItemType::Ptr UntypedAtomic::type() const +{ + return BuiltinTypes::xsUntypedAtomic; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/quntypedatomic_p.h b/src/xmlpatterns/data/quntypedatomic_p.h new file mode 100644 index 0000000..45665ac --- /dev/null +++ b/src/xmlpatterns/data/quntypedatomic_p.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_UntypedAtomic_H +#define Patternist_UntypedAtomic_H + +#include "qatomicstring_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Implements the value instance of the @c xs:untypedAtomic type. + * + * @author Frans Englich + * @ingroup Patternist_xdm + */ + class UntypedAtomic : public AtomicString + { + public: + friend class CommonValues; + + /** + * Creates an instance representing @p value. + * + * This fromValue function takes no context argument because it doesn't need it -- it + * casting to xs:untypedAtomic always succeeds. + * + * @note This function does not remove the string literal escaping allowed in XPath 2.0 + */ + static UntypedAtomic::Ptr fromValue(const QString &value); + + virtual ItemType::Ptr type() const; + + protected: + + UntypedAtomic(const QString &value); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qvalidationerror.cpp b/src/xmlpatterns/data/qvalidationerror.cpp new file mode 100644 index 0000000..c07b036 --- /dev/null +++ b/src/xmlpatterns/data/qvalidationerror.cpp @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include "qvalidationerror_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +ValidationError::ValidationError(const QString &msg, + const ReportContext::ErrorCode code) : m_message(msg), + m_code(code) +{ +} + +AtomicValue::Ptr ValidationError::createError(const QString &description, + const ReportContext::ErrorCode code) +{ + return ValidationError::Ptr(new ValidationError(description, code)); +} + +bool ValidationError::hasError() const +{ + return true; +} + +QString ValidationError::stringValue() const +{ + Q_ASSERT_X(false, Q_FUNC_INFO, "stringValue() asked for ValidationError -- it makes no sense."); + return QString(); +} + +QString ValidationError::message() const +{ + return m_message; +} + +ItemType::Ptr ValidationError::type() const +{ + Q_ASSERT_X(false, Q_FUNC_INFO, + "This function should never be called, the caller " + "didn't check whether the AtomicValue was an ValidationError."); + return ItemType::Ptr(); +} + +ReportContext::ErrorCode ValidationError::errorCode() const +{ + return m_code; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qvalidationerror_p.h b/src/xmlpatterns/data/qvalidationerror_p.h new file mode 100644 index 0000000..d93f6cb --- /dev/null +++ b/src/xmlpatterns/data/qvalidationerror_p.h @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ValidationError_H +#define Patternist_ValidationError_H + +#include "qitem_p.h" +#include "qreportcontext_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Used for signalling casting errors. + * + * @author Frans Englich + * @ingroup Patternist_xdm + */ + class ValidationError : public AtomicValue + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * Creates a ValidationError instance that represents a type error. + * + * @param description A detailed description of what that made the cast fail, + * if any. If @c null, which QString() creates, a generic message + * will be used. + */ + static AtomicValue::Ptr createError(const QString &description = QString(), + const ReportContext::ErrorCode = ReportContext::FORG0001); + + /** + * A human readable, translated message describing the error. + */ + QString message() const; + + /** + * @returns always @c true + */ + virtual bool hasError() const; + + /** + * Always results in an assert crash. + */ + virtual ItemType::Ptr type() const; + + /** + * Always results in an assert crash. + */ + virtual QString stringValue() const; + + /** + * @returns the error code this ValidationError represents. Typically, this + * is ReportContext::FORG0001. + */ + ReportContext::ErrorCode errorCode() const; + + protected: + ValidationError(const QString &msg, const ReportContext::ErrorCode code); + + const QString m_message; + const ReportContext::ErrorCode m_code; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qvaluefactory.cpp b/src/xmlpatterns/data/qvaluefactory.cpp new file mode 100644 index 0000000..8f7e5a3 --- /dev/null +++ b/src/xmlpatterns/data/qvaluefactory.cpp @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qatomiccaster_p.h" +#include "qatomicstring_p.h" +#include "qcastingplatform_p.h" +#include "qvaluefactory_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +/** + * @short Helper class for ValueFactory::fromLexical() which exposes + * CastingPlatform appropriately. + * + * @relates ValueFactory + */ +class PerformValueConstruction : public CastingPlatform + , public SourceLocationReflection +{ +public: + PerformValueConstruction(const SourceLocationReflection *const sourceLocationReflection, + const SchemaType::Ptr &toType) : m_sourceReflection(sourceLocationReflection) + , m_targetType(AtomicType::Ptr(toType)) + { + Q_ASSERT(m_sourceReflection); + } + + AtomicValue::Ptr operator()(const AtomicValue::Ptr &lexicalValue, + const SchemaType::Ptr & /*type*/, + const ReportContext::Ptr &context) + { + prepareCasting(context, BuiltinTypes::xsString); + return AtomicValue::Ptr(const_cast(cast(lexicalValue, context).asAtomicValue())); + } + + const SourceLocationReflection *actualReflection() const + { + return m_sourceReflection; + } + + ItemType::Ptr targetType() const + { + return m_targetType; + } + +private: + const SourceLocationReflection *const m_sourceReflection; + const ItemType::Ptr m_targetType; +}; + +AtomicValue::Ptr ValueFactory::fromLexical(const QString &lexicalValue, + const SchemaType::Ptr &type, + const ReportContext::Ptr &context, + const SourceLocationReflection *const sourceLocationReflection) +{ + Q_ASSERT(context); + Q_ASSERT(type); + Q_ASSERT_X(type->category() == SchemaType::SimpleTypeAtomic, Q_FUNC_INFO, + "We can only construct for atomic values."); + + return PerformValueConstruction(sourceLocationReflection, type)(AtomicString::fromValue(lexicalValue), + type, + context); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qvaluefactory_p.h b/src/xmlpatterns/data/qvaluefactory_p.h new file mode 100644 index 0000000..e383d27 --- /dev/null +++ b/src/xmlpatterns/data/qvaluefactory_p.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ValueFactory_H +#define Patternist_ValueFactory_H + +#include "qitem_p.h" +#include "qreportcontext_p.h" +#include "qschematype_p.h" + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Provides fromLexical(), which allows instantiation of atomic + * values from arbitrary types. + * + * This class wraps the helper class CastingPlatform with a more specific, + * high-level API. + * + * @see CastingPlatform + * @author Frans Englich + * @ingroup Patternist_schema + */ + class ValueFactory + { + public: + /** + * @short Returns an AtomicValue of type @p type from the lexical space + * @p lexicalValue, and raise an error through @p context if that's + * impossible. + * + * ValueFactory does not take ownership of @p sourceLocationReflection. + */ + static AtomicValue::Ptr fromLexical(const QString &lexicalValue, + const SchemaType::Ptr &type, + const ReportContext::Ptr &context, + const SourceLocationReflection *const sourceLocationReflection); + + private: + Q_DISABLE_COPY(ValueFactory) + }; +} + +QT_END_NAMESPACE +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/data/qyearmonthduration.cpp b/src/xmlpatterns/data/qyearmonthduration.cpp new file mode 100644 index 0000000..5ff60a5 --- /dev/null +++ b/src/xmlpatterns/data/qyearmonthduration.cpp @@ -0,0 +1,186 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" +#include "qcommonvalues_p.h" + +#include "qyearmonthduration_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +YearMonthDuration::YearMonthDuration(const bool isPositiveP, + const YearProperty yearsP, + const MonthProperty monthsP) : AbstractDuration(isPositiveP), + m_years(yearsP), + m_months(monthsP) +{ + Q_ASSERT(monthsP < 32 && monthsP > -32); +} + +YearMonthDuration::Ptr YearMonthDuration::fromLexical(const QString &lexical) +{ + static const CaptureTable captureTable( + /* The extra paranthesis is a build fix for GCC 3.3. */ + (QRegExp(QLatin1String( + "^\\s*" /* Any preceding whitespace. */ + "(-)?" /* Sign, if any. */ + "P" /* Delimiter. */ + "(?:(\\d+)Y)?" /* The years part. */ + "(?:(\\d+)M)?" /* The months part. */ + "\\s*$" /* Any terminating whitespace. */))), + 2, /* yearP. */ + 3 /* monthP. */); + + YearProperty years = 0; + MonthProperty months = 0; + bool isPos; + + const AtomicValue::Ptr err(create(captureTable, lexical, &isPos, &years, + &months, 0, 0, 0, 0, 0)); + + return err ? err : YearMonthDuration::Ptr(new YearMonthDuration(isPos, years, months)); +} + +YearMonthDuration::Ptr YearMonthDuration::fromComponents(const bool isPositive, + const YearProperty years, + const MonthProperty months) +{ + return YearMonthDuration::Ptr(new YearMonthDuration(isPositive, years, months)); +} + +QString YearMonthDuration::stringValue() const +{ + QString retval; + + if(!m_isPositive) + retval.append(QLatin1Char('-')); + + retval.append(QLatin1Char('P')); + + /* When years == 0 and months == 0, we get "P0M", which + * is the correct canonical form. */ + if(m_years) + { + retval.append(QString::number(m_years)); + retval.append(QLatin1Char('Y')); + + if(m_months) + { + retval.append(QString::number(m_months)); + retval.append(QLatin1Char('M')); + } + } + else + { + if(m_months) + { + retval.append(QString::number(m_months)); + retval.append(QLatin1Char('M')); + } + else + return QLatin1String("P0M"); /* Ensure the canonical form. */ + } + + return retval; +} + +AbstractDuration::Value YearMonthDuration::value() const +{ + return (m_years * 12 + m_months) * (m_isPositive ? 1 : -1); +} + +Item YearMonthDuration::fromValue(const Value val) const +{ + if(val == 0) + return toItem(CommonValues::YearMonthDurationZero); + else + { + const Value absValue = qAbs(val); + return toItem(YearMonthDuration::fromComponents(val >= 0, + absValue / 12, + absValue % 12)); + } +} + +ItemType::Ptr YearMonthDuration::type() const +{ + return BuiltinTypes::xsYearMonthDuration; +} + +YearProperty YearMonthDuration::years() const +{ + return m_years; +} + +MonthProperty YearMonthDuration::months() const +{ + return m_months; +} + +DayCountProperty YearMonthDuration::days() const +{ + return 0; +} + +HourProperty YearMonthDuration::hours() const +{ + return 0; +} + +MinuteProperty YearMonthDuration::minutes() const +{ + return 0; +} + +SecondProperty YearMonthDuration::seconds() const +{ + return 0; +} + +MSecondProperty YearMonthDuration::mseconds() const +{ + return 0; +} + + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/data/qyearmonthduration_p.h b/src/xmlpatterns/data/qyearmonthduration_p.h new file mode 100644 index 0000000..ca53325 --- /dev/null +++ b/src/xmlpatterns/data/qyearmonthduration_p.h @@ -0,0 +1,151 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_YearMonthDuration_H +#define Patternist_YearMonthDuration_H + +#include "qabstractduration_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the value instance of the @c xs:yearMonthDuration type. + * + * @author Frans Englich + * @ingroup Patternist_xdm + */ + class YearMonthDuration : public AbstractDuration + { + public: + typedef AtomicValue::Ptr Ptr; + + /** + * Creates an instance from the lexical representation @p string. + */ + static YearMonthDuration::Ptr fromLexical(const QString &string); + + static YearMonthDuration::Ptr fromComponents(const bool isPositive, + const YearProperty years, + const MonthProperty months); + + virtual ItemType::Ptr type() const; + virtual QString stringValue() const; + + /** + * @returns the value of this @c xs:yearMonthDuration in months. + * @see XQuery 1.0 + * and XPath 2.0 Functions and Operators, 10.3.2.2 Calculating the value of a + * xs:dayTimeDuration from the lexical representation + */ + virtual Value value() const; + + /** + * If @p val is zero, is CommonValues::YearMonthDurationZero returned. + */ + virtual Item fromValue(const Value val) const; + + /** + * @returns the years component. Always positive. + */ + virtual YearProperty years() const; + + /** + * @returns the months component. Always positive. + */ + virtual MonthProperty months() const; + + /** + * @returns always 0. + */ + virtual DayCountProperty days() const; + + /** + * @returns always 0. + */ + virtual HourProperty hours() const; + + /** + * @returns always 0. + */ + virtual MinuteProperty minutes() const; + + /** + * @returns always 0. + */ + virtual SecondProperty seconds() const; + + /** + * @returns always 0. + */ + virtual MSecondProperty mseconds() const; + + protected: + friend class CommonValues; + + YearMonthDuration(const bool isPositive, + const YearProperty years, + const MonthProperty months); + + private: + const YearProperty m_years; + const MonthProperty m_months; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/documentationGroups.dox b/src/xmlpatterns/documentationGroups.dox new file mode 100644 index 0000000..d3b1d28 --- /dev/null +++ b/src/xmlpatterns/documentationGroups.dox @@ -0,0 +1,150 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +/** + * @file + * @short Contains Doxygen documentation for groups. + */ + +namespace QPatternist +{ + /** + * @short The abstract syntax tree nodes that implements the builtin + * functions, such as @c fn:concat(). + * + * @defgroup Patternist_functions Function Implementations + * @author Frans Englich + */ + + /** + * @short The abstract syntax tree nodes that is generated for XPath, + * XQuery, and XSL-T code. + * + * XPath's approach of compilation is traditional. An Abstract Syntax + * Tree(AST) is built, where the Expression class is the abstract base + * class for all kinds of implementations of expressions. + * + * What perhaps can be said to be characteristic for Patternist is that the + * base class, Expression, performs a lot of work, and that sub-classes + * declares what specific behaviors they need, which the Expression's + * functions then bring into action. + * + * XPath expressions often have different amount of operands. For example, + * the 'and' expression takes two, the context item(".") none, and the + * if-expression three. To help expression implementations with that, there + * exist the abstract EmptyContainer, SingleContainer, PairContainer, + * TripleContainer, and UnlimitedContainer classes for avoiding duplicating + * code. + * + * @defgroup Patternist_expressions Expressions + * @author Frans Englich + */ + + /** + * @short Various classes that contains small utility functions. + * + * @defgroup Patternist Utility Classes + * @author Frans Englich + */ + + /** + * @short Classes for the type system in the XQuery & XSL-T language. + * + * @defgroup Patternist_types Type system + * @author Frans Englich + */ + + /** + * @defgroup Patternist_xdm XQuery/XPath Data Model + * @author Frans Englich + */ + + /** + * @short Patternist's family of iterators in one of the most central parts + * of Patternist's API, and are responsible for carrying, and typically + * also creating, data. + * + * An iterator, which always is an Iterator sub-class, is similar to a + * Java-style iterator. What signifies Patternist's iterators is that they + * almost always contains business logic(which is the cause to their + * efficiency). + * + * An example which illustrates this principle is the RangeIterator. When + * the RangeExpression is told to create a sequence of integers between 1 + * and 1000, it doesn't enter a loop that allocates 1000 Integer instances, + * but instead return an RangeIterator that incrementally creates the + * numbers when asked to do so via its RangeIterator::next() function. If + * it turns out that the expression that has the range expression as + * operand only needs three items from it, that is what gets created, not + * 1000. + * + * All iterators operates by that principle, perhaps suitably labeled as + * "pull-based", "lazy loaded" or "serialized". Central for the XPath + * language is that it filters and selects data, and the iterators supports + * this well by letting the demand of the filter expressions(the callees) + * decide how "much" source that gets computed. In this way the evaluation + * of an expression tree can lead to a chain of pipelined iterators, where + * the first asks the second for data and then performs its specific + * operations, the second subsequently asks the third, and so forth. + * + * However, the iterators are not limited to be used for representing + * sequences of items in the XPath Data Model. The Iterator is + * parameterized on one argument, meaning any type of "units" can be + * iterated, be it Item or any other. One use of this is in the + * ExpressionSequence(which implements the comma operator) where it creates + * Iterator instances over Expression instances -- its operands. The + * parameterization is often used in combination with the MappingIterator + * and the MappingCallback. + * + * @defgroup Patternist_iterators Iterators + * @author Frans Englich + */ +} diff --git a/src/xmlpatterns/environment/createReportContext.sh b/src/xmlpatterns/environment/createReportContext.sh new file mode 100755 index 0000000..f39e146 --- /dev/null +++ b/src/xmlpatterns/environment/createReportContext.sh @@ -0,0 +1,53 @@ +#!/bin/sh +############################################################################# +## +## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +## All rights reserved. +## Contact: Nokia Corporation (qt-info@nokia.com) +## +## This file is the build configuration utility of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:LGPL$ +## No Commercial Usage +## This file contains pre-release code and may not be distributed. +## You may use this file in accordance with the terms and conditions +## contained in the Technology Preview License Agreement accompanying +## this package. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 2.1 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 2.1 requirements +## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +## +## In addition, as a special exception, Nokia gives you certain additional +## rights. These rights are described in the Nokia Qt LGPL Exception +## version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +## +## If you have questions regarding the use of this file, please contact +## Nokia at qt-info@nokia.com. +## +## +## +## +## +## +## +## +## $QT_END_LICENSE$ +## +############################################################################# + +# Generate ReportContext.h by invoking createReportContext.xsl, which +# in turns performs a transformation on the specs, fetched from http://www.w3.org/. + +target="qreportcontext_p.h" +tmpFile=".reportContextInput.tmp.xml" +echo "" > $tmpFile +p4 revert $target +p4 edit $target +xsltproc createReportContext.xsl $tmpFile > $target +p4 revert -a $target +rm -f $tmpFile diff --git a/src/xmlpatterns/environment/createReportContext.xsl b/src/xmlpatterns/environment/createReportContext.xsl new file mode 100644 index 0000000..ee0b143 --- /dev/null +++ b/src/xmlpatterns/environment/createReportContext.xsl @@ -0,0 +1,559 @@ + + + + + + + + + + + + + + + + + + + + + + + +#include +#include + +#include "qnamepool_p.h" +#include "qxmlname.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QAbstractMessageHandler; +class QSourceLocation; +class QString; + +namespace QPatternist +{ + class SourceLocationReflection; + + /** + * @short A callback for reporting errors. + * + * ReportContext receives messages of various severity and type via its + * functions warning() and error(). In turn, ReportContext create Message instances + * and submit them to the QAbstractMessageHandler instance returned by messageHandler(). + * + * The Message attributes are set as follows: + * + * - Message::description() - A translated, human-readable description + * - Message::type() - Message::Error if a static, dynamic or type error was encountered + * that halted compilation or evaluation, or Message::Warning in case of a warning + * - Message::identifier() - This is a URI consisting of the error namespace with the + * error code as fragment. For example, a Message representing a syntax error + * would return the type "http://www.w3.org/2005/xqt-errors#XPST0003". The convenience + * function codeFromURI() can be used to extract the error code. The error namespace + * is typically the namespace for XPath and XQuery errors(as in the previous example), but + * can also be user defined. + * + * @see XML Path Language + * (XPath) 2.0, 2.3.2 Identifying and Reporting Errors + * @see XQuery 1.0 and + * XPath 2.0 Functions and Operators, 3 The Error Function + * @author Frans Englich + * @warning This file is auto-generated from extractErrorCodes.xsl. Any + * modifications done to this file are lost. + */ + class Q_AUTOTEST_EXPORT ReportContext : public QSharedData + { + public: + typedef QHash LocationHash; + + /** + * A smart pointer wrapping ReportContext instances. + */ + typedef QExplicitlySharedDataPointer Ptr; + + /** + * @short Default constructors. + * + * For some reason GCC fails to synthesize it, so we provide an empty + * one here. + */ + inline ReportContext() {} + + virtual ~ReportContext(); + + /** + * Error codes that corresponds to the error codes defined in the + * relevant specifications. They are used throughout the API for + * identifying error conditions. + * + * While strings could have been used for identifying errors, enums + * reduces bugs by providing type safety. + * + * @see XML + * Path Language (XPath) 2.0, 2.3 Error Handling + * @see XQuery 1.0 + * and XPath 2.0 Functions and Operators, C Error Summary + * @see XSL Transformations + * (XSLT) Version 2.0, E Summary of Error Conditions (Non-Normative) + * @note The enumerator values' Doxygen documentation is copied from the + * W3C documents + * XQuery 1.0 and XPath + * 2.0 Functions and Operators, + * XML Path Language (XPath) 2.0, and + * XSL Transformations (XSLT) + * Version 2.0, respectively. The doxygen documentation is therefore covered + * by the following legal notice: + * "Copyright @ 2005 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C + * liability, + * trademark and + * document + * use rules apply." + * @warning This enumerator is auto-generated from the relevant specifications + * by the XSL-T stylesheet extractErrorCodes.xsl. Hence, any modifications + * done to this file, in contrary to the stylesheet, are therefore lost. + */]]> + enum ErrorCode + { + /** + * XML Schema error code. + */ + XSDError, + + + + + + + }; +XML Path Language (XPath) 2.0, + * 2.3 Error Handling + * @param message the message to be read by the user. + * @param sourceLocation the location of where the warning originates from. + */ + void warning(const QString &message, const QSourceLocation &sourceLocation = QSourceLocation()); + + /** + * Issues an error. May be used at the static analysis phase or + * the dynamic evaluation phase. + * + * For SourceLocationReflection instances, the overload taking an SouourceLocationReflection should be used. + * + * @see XML Path Language (XPath) 2.0, + * 2.3 Error Handling + * @param message the message to be read by the user. + * @param errorCode identifies the error condition, as described + * @param sourceLocation the location of where the error originates from + * in "XML Path Language (XPath) 2.0" section "G Error Conditions" + */ + void error(const QString &message, + const ReportContext::ErrorCode errorCode, + const QSourceLocation &sourceLocation); + + /** + * Overload. + * + * Same as the above, but passes the SourceLocationReflection as reference for error reporting. + */ + void error(const QString &message, + const ReportContext::ErrorCode errorCode, + const SourceLocationReflection *reflection); + + /** + * Issues an error which is not identified in the XPath specifications. This function + * is among other things used for implementing the fn:error() function. + */ + void error(const QString &message, + const QXmlName qName, + const SourceLocationReflection *const r); + + /** + * @return the QAbstractMessageHandler which functions such as warning() and + * error() should submit messages to. This function + * may never return @c null; a valid QAbstractMessageHandler pointer must always be returned. + */ + virtual QAbstractMessageHandler *messageHandler() const = 0; + + virtual NamePool::Ptr namePool() const = 0; + + /** + * Returns a string representation of the error code @p code. + * + * @see ReportContext::ErrorCode + * @param errorCode identifies the error condition, as described + * in XML Path + * Language (XPath) 2.0, G Error Conditions + */ + static QString codeToString(const ReportContext::ErrorCode errorCode); + + /** + * @returns the error code part of @p typeURI and sets @p uri to the error namespace. Note + * that the error namespace not necessarily is the namespace for XPath and + * XQuery errors, http://www.w3.org/2005/xqt-errors, but can be user defined. + */ + static QString codeFromURI(const QString &typeURI, + QString &uri); + + /** + * @short Returns the source location applying for @p reflection. + */ + virtual QSourceLocation locationFor(const SourceLocationReflection *const reflection) const = 0; + + /** + * Resolves @p relative against @p baseURI, possibly using a URI resolver. + */ + QUrl resolveURI(const QUrl &relative, + const QUrl &baseURI) const; + + /** + * @short The URI resolver in use. + * + * If no URI resolver is in use, a @c null pointer is returned. + * + * @note You should probably use resolveURI(), which handles the case of + * when uriResolver() is @c null. + */ + virtual QAbstractUriResolver *uriResolver() const = 0; + + private: + void createError(const QString &description, + const QtMsgType type, + const QUrl &id, + const QSourceLocation &sourceLocation) const; + static inline QString finalizeDescription(const QString &desc); + QSourceLocation lookupSourceLocation(const SourceLocationReflection *const ref) const; + + Q_DISABLE_COPY(ReportContext) + }; + + /** + * @short This is the class type that is being thrown when a query error occur. + * + * @relates ReportContext + */ + typedef bool Exception; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif]]> + + + + + + + + + + + + + /** + + + */ + , + + + + + + + + + + + + + /** + + + */ + , + + + + + + + + + + + + /** + + + */ + + + , + + + + + + + + + + + + + /** + + + */ + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + * + + + + + + * + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/xmlpatterns/environment/environment.pri b/src/xmlpatterns/environment/environment.pri new file mode 100644 index 0000000..b8a2b65 --- /dev/null +++ b/src/xmlpatterns/environment/environment.pri @@ -0,0 +1,32 @@ +HEADERS += $$PWD/qcurrentitemcontext_p.h \ + $$PWD/qdelegatingdynamiccontext_p.h \ + $$PWD/qdelegatingstaticcontext_p.h \ + $$PWD/qdynamiccontext_p.h \ + $$PWD/qfocus_p.h \ + $$PWD/qgenericdynamiccontext_p.h \ + $$PWD/qgenericstaticcontext_p.h \ + $$PWD/qreceiverdynamiccontext_p.h \ + $$PWD/qreportcontext_p.h \ + $$PWD/qstackcontextbase_p.h \ + $$PWD/qstaticbaseuricontext_p.h \ + $$PWD/qstaticcontext_p.h \ + $$PWD/qstaticcurrentcontext_p.h \ + $$PWD/qstaticfocuscontext_p.h \ + $$PWD/qstaticcompatibilitycontext_p.h \ + $$PWD/qstaticnamespacecontext_p.h + +SOURCES += $$PWD/qcurrentitemcontext.cpp \ + $$PWD/qdelegatingdynamiccontext.cpp \ + $$PWD/qdelegatingstaticcontext.cpp \ + $$PWD/qdynamiccontext.cpp \ + $$PWD/qfocus.cpp \ + $$PWD/qgenericdynamiccontext.cpp \ + $$PWD/qgenericstaticcontext.cpp \ + $$PWD/qreceiverdynamiccontext.cpp \ + $$PWD/qreportcontext.cpp \ + $$PWD/qstaticbaseuricontext.cpp \ + $$PWD/qstaticcontext.cpp \ + $$PWD/qstaticcurrentcontext.cpp \ + $$PWD/qstaticfocuscontext.cpp \ + $$PWD/qstaticcompatibilitycontext.cpp \ + $$PWD/qstaticnamespacecontext.cpp diff --git a/src/xmlpatterns/environment/qcurrentitemcontext.cpp b/src/xmlpatterns/environment/qcurrentitemcontext.cpp new file mode 100644 index 0000000..0924d08 --- /dev/null +++ b/src/xmlpatterns/environment/qcurrentitemcontext.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdaytimeduration_p.h" + +#include "qcurrentitemcontext_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +CurrentItemContext::CurrentItemContext(const Item &item, + const DynamicContext::Ptr &prevContext) : DelegatingDynamicContext(prevContext) + , m_currentItem(item) +{ + Q_ASSERT(prevContext); +} + +Item CurrentItemContext::currentItem() const +{ + return m_currentItem; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/environment/qcurrentitemcontext_p.h b/src/xmlpatterns/environment/qcurrentitemcontext_p.h new file mode 100644 index 0000000..894dde3 --- /dev/null +++ b/src/xmlpatterns/environment/qcurrentitemcontext_p.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_CurrentItemContext_H +#define Patternist_CurrentItemContext_H + +#include "qdelegatingdynamiccontext_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A DynamicContext that maintains the focus, a sequence + * of items. + * + * CurrentItemContext implements both the outer and inner focus. The focus is one of + * the things that characterizes the XPath language. The focus is what's + * iterated over in a predicate, whose current item can be received + * via the context item expression, .(the dot), + * and whose size is retrievable via the function fn:last(). + * + * @since 4.5 + * @author Frans Englich + */ + class CurrentItemContext : public DelegatingDynamicContext + { + public: + CurrentItemContext(const Item &item, + const DynamicContext::Ptr &prevContext); + + virtual Item currentItem() const; + + private: + const Item m_currentItem; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/environment/qdelegatingdynamiccontext.cpp b/src/xmlpatterns/environment/qdelegatingdynamiccontext.cpp new file mode 100644 index 0000000..4cf6bac --- /dev/null +++ b/src/xmlpatterns/environment/qdelegatingdynamiccontext.cpp @@ -0,0 +1,212 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qdaytimeduration_p.h" +#include "qtemplatemode_p.h" + +#include "qdelegatingdynamiccontext_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +DelegatingDynamicContext::DelegatingDynamicContext(const DynamicContext::Ptr &prevContext) + : m_prevContext(prevContext) +{ + Q_ASSERT(m_prevContext); +} + +ItemCacheCell &DelegatingDynamicContext::itemCacheCell(const VariableSlotID slot) +{ + return m_prevContext->itemCacheCell(slot); +} + +ItemSequenceCacheCell::Vector &DelegatingDynamicContext::itemSequenceCacheCells(const VariableSlotID slot) +{ + return m_prevContext->itemSequenceCacheCells(slot); +} + +xsInteger DelegatingDynamicContext::contextPosition() const +{ + return m_prevContext->contextPosition(); +} + +Item DelegatingDynamicContext::contextItem() const +{ + return m_prevContext->contextItem(); +} + +xsInteger DelegatingDynamicContext::contextSize() +{ + return m_prevContext->contextSize(); +} + +void DelegatingDynamicContext::setFocusIterator(const Item::Iterator::Ptr &it) +{ + m_prevContext->setFocusIterator(it); +} + +Item::Iterator::Ptr DelegatingDynamicContext::positionIterator(const VariableSlotID slot) const +{ + return m_prevContext->positionIterator(slot); +} + +void DelegatingDynamicContext::setPositionIterator(const VariableSlotID slot, + const Item::Iterator::Ptr &newValue) +{ + m_prevContext->setPositionIterator(slot, newValue); +} + +void DelegatingDynamicContext::setRangeVariable(const VariableSlotID slotNumber, + const Item &newValue) +{ + m_prevContext->setRangeVariable(slotNumber, newValue); +} + +Item::Iterator::Ptr DelegatingDynamicContext::focusIterator() const +{ + return m_prevContext->focusIterator(); +} + +Item DelegatingDynamicContext::rangeVariable(const VariableSlotID slotNumber) const +{ + return m_prevContext->rangeVariable(slotNumber); +} + +void DelegatingDynamicContext::setExpressionVariable(const VariableSlotID slotNumber, + const Expression::Ptr &newValue) +{ + m_prevContext->setExpressionVariable(slotNumber, newValue); +} + +Expression::Ptr DelegatingDynamicContext::expressionVariable(const VariableSlotID slotNumber) const +{ + return m_prevContext->expressionVariable(slotNumber); +} + +QAbstractMessageHandler * DelegatingDynamicContext::messageHandler() const +{ + return m_prevContext->messageHandler(); +} + +QExplicitlySharedDataPointer DelegatingDynamicContext::implicitTimezone() const +{ + return m_prevContext->implicitTimezone(); +} + +QDateTime DelegatingDynamicContext::currentDateTime() const +{ + return m_prevContext->currentDateTime(); +} + +QAbstractXmlReceiver *DelegatingDynamicContext::outputReceiver() const +{ + return m_prevContext->outputReceiver(); +} + +NodeBuilder::Ptr DelegatingDynamicContext::nodeBuilder(const QUrl &baseURI) const +{ + return m_prevContext->nodeBuilder(baseURI); +} + +ResourceLoader::Ptr DelegatingDynamicContext::resourceLoader() const +{ + return m_prevContext->resourceLoader(); +} + +ExternalVariableLoader::Ptr DelegatingDynamicContext::externalVariableLoader() const +{ + return m_prevContext->externalVariableLoader(); +} + +NamePool::Ptr DelegatingDynamicContext::namePool() const +{ + return m_prevContext->namePool(); +} + +QSourceLocation DelegatingDynamicContext::locationFor(const SourceLocationReflection *const reflection) const +{ + return m_prevContext->locationFor(reflection); +} + +void DelegatingDynamicContext::addNodeModel(const QAbstractXmlNodeModel::Ptr &nm) +{ + m_prevContext->addNodeModel(nm); +} + +const QAbstractUriResolver *DelegatingDynamicContext::uriResolver() const +{ + return m_prevContext->uriResolver(); +} + +ItemCacheCell &DelegatingDynamicContext::globalItemCacheCell(const VariableSlotID slot) +{ + return m_prevContext->globalItemCacheCell(slot); +} + +ItemSequenceCacheCell::Vector &DelegatingDynamicContext::globalItemSequenceCacheCells(const VariableSlotID slot) +{ + return m_prevContext->globalItemSequenceCacheCells(slot); +} + +Item DelegatingDynamicContext::currentItem() const +{ + return m_prevContext->currentItem(); +} + +DynamicContext::TemplateParameterHash &DelegatingDynamicContext::templateParameterStore() +{ + return m_prevContext->templateParameterStore(); +} + +DynamicContext::Ptr DelegatingDynamicContext::previousContext() const +{ + return m_prevContext; +} + +QExplicitlySharedDataPointer DelegatingDynamicContext::currentTemplateMode() const +{ + return m_prevContext->currentTemplateMode(); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/environment/qdelegatingdynamiccontext_p.h b/src/xmlpatterns/environment/qdelegatingdynamiccontext_p.h new file mode 100644 index 0000000..552ef7c --- /dev/null +++ b/src/xmlpatterns/environment/qdelegatingdynamiccontext_p.h @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_DelegatingDynamicContext_H +#define Patternist_DelegatingDynamicContext_H + +#include "qdynamiccontext_p.h" +#include "qexpression_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Base class for dynamic contexts that are + * created from an existing one. + * + * In some cases multiple DynamicContext instances must be used in + * order to maintain somekind of scope. This class delegates + * the DynamicContext interface onto another DynamicContext instance, + * allowing the sub-class to only implement what it needs to. + * + * @author Frans Englich + */ + class DelegatingDynamicContext : public DynamicContext + { + public: + virtual xsInteger contextPosition() const; + virtual Item contextItem() const; + virtual xsInteger contextSize(); + + virtual ItemCacheCell &itemCacheCell(const VariableSlotID slot); + virtual ItemSequenceCacheCell::Vector &itemSequenceCacheCells(const VariableSlotID slot); + + virtual void setRangeVariable(const VariableSlotID slotNumber, + const Item &newValue); + virtual Item rangeVariable(const VariableSlotID slotNumber) const; + + virtual void setExpressionVariable(const VariableSlotID slotNumber, + const Expression::Ptr &newValue); + virtual Expression::Ptr expressionVariable(const VariableSlotID slotNumber) const; + + virtual void setFocusIterator(const Item::Iterator::Ptr &it); + virtual Item::Iterator::Ptr focusIterator() const; + + virtual Item::Iterator::Ptr positionIterator(const VariableSlotID slot) const; + virtual void setPositionIterator(const VariableSlotID slot, + const Item::Iterator::Ptr &newValue); + + virtual QAbstractMessageHandler * messageHandler() const; + virtual QExplicitlySharedDataPointer implicitTimezone() const; + virtual QDateTime currentDateTime() const; + virtual QAbstractXmlReceiver *outputReceiver() const; + virtual NodeBuilder::Ptr nodeBuilder(const QUrl &baseURI) const; + virtual ResourceLoader::Ptr resourceLoader() const; + virtual ExternalVariableLoader::Ptr externalVariableLoader() const; + virtual NamePool::Ptr namePool() const; + virtual QSourceLocation locationFor(const SourceLocationReflection *const reflection) const; + virtual void addNodeModel(const QAbstractXmlNodeModel::Ptr &nm); + virtual const QAbstractUriResolver *uriResolver() const; + virtual ItemCacheCell &globalItemCacheCell(const VariableSlotID slot); + virtual ItemSequenceCacheCell::Vector &globalItemSequenceCacheCells(const VariableSlotID slot); + virtual Item currentItem() const; + virtual TemplateParameterHash &templateParameterStore(); + + virtual DynamicContext::Ptr previousContext() const; + virtual QExplicitlySharedDataPointer currentTemplateMode() const; + + protected: + DelegatingDynamicContext(const DynamicContext::Ptr &prevContext); + + const DynamicContext::Ptr m_prevContext; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/environment/qdelegatingstaticcontext.cpp b/src/xmlpatterns/environment/qdelegatingstaticcontext.cpp new file mode 100644 index 0000000..6ad183e --- /dev/null +++ b/src/xmlpatterns/environment/qdelegatingstaticcontext.cpp @@ -0,0 +1,261 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* Patternist */ +#include "qbasictypesfactory_p.h" +#include "qfunctionfactorycollection_p.h" +#include "qgenericnamespaceresolver_p.h" +#include "qcommonnamespaces_p.h" +#include "qgenericdynamiccontext_p.h" + +#include "qstaticfocuscontext_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +DelegatingStaticContext::DelegatingStaticContext(const StaticContext::Ptr &context) : m_context(context) +{ + Q_ASSERT(context); +} + +NamespaceResolver::Ptr DelegatingStaticContext::namespaceBindings() const +{ + return m_context->namespaceBindings(); +} + +FunctionFactory::Ptr DelegatingStaticContext::functionSignatures() const +{ + return m_context->functionSignatures(); +} + +DynamicContext::Ptr DelegatingStaticContext::dynamicContext() const +{ + return m_context->dynamicContext(); +} + +SchemaTypeFactory::Ptr DelegatingStaticContext::schemaDefinitions() const +{ + return m_context->schemaDefinitions(); +} + +QUrl DelegatingStaticContext::baseURI() const +{ + return m_context->baseURI(); +} + +void DelegatingStaticContext::setBaseURI(const QUrl &uri) +{ + m_context->setBaseURI(uri); +} + +bool DelegatingStaticContext::compatModeEnabled() const +{ + return m_context->compatModeEnabled(); +} + +QUrl DelegatingStaticContext::defaultCollation() const +{ + return m_context->defaultCollation(); +} + +QAbstractMessageHandler * DelegatingStaticContext::messageHandler() const +{ + return m_context->messageHandler(); +} + +void DelegatingStaticContext::setDefaultCollation(const QUrl &uri) +{ + m_context->setDefaultCollation(uri); +} + +void DelegatingStaticContext::setNamespaceBindings(const NamespaceResolver::Ptr &resolver) +{ + m_context->setNamespaceBindings(resolver); +} + +StaticContext::BoundarySpacePolicy DelegatingStaticContext::boundarySpacePolicy() const +{ + return m_context->boundarySpacePolicy(); +} + +void DelegatingStaticContext::setBoundarySpacePolicy(const BoundarySpacePolicy policy) +{ + m_context->setBoundarySpacePolicy(policy); +} + +StaticContext::ConstructionMode DelegatingStaticContext::constructionMode() const +{ + return m_context->constructionMode(); +} + +void DelegatingStaticContext::setConstructionMode(const ConstructionMode mode) +{ + m_context->setConstructionMode(mode); +} + +StaticContext::OrderingMode DelegatingStaticContext::orderingMode() const +{ + return m_context->orderingMode(); +} + +void DelegatingStaticContext::setOrderingMode(const OrderingMode mode) +{ + m_context->setOrderingMode(mode); +} + +StaticContext::OrderingEmptySequence DelegatingStaticContext::orderingEmptySequence() const +{ + return m_context->orderingEmptySequence(); +} + +void DelegatingStaticContext::setOrderingEmptySequence(const OrderingEmptySequence ordering) +{ + m_context->setOrderingEmptySequence(ordering); +} + +QString DelegatingStaticContext::defaultFunctionNamespace() const +{ + return m_context->defaultFunctionNamespace(); +} + +void DelegatingStaticContext::setDefaultFunctionNamespace(const QString &ns) +{ + m_context->setDefaultFunctionNamespace(ns); +} + +QString DelegatingStaticContext::defaultElementNamespace() const +{ + return m_context->defaultElementNamespace(); +} + +void DelegatingStaticContext::setDefaultElementNamespace(const QString &ns) +{ + m_context->setDefaultElementNamespace(ns); +} + +StaticContext::InheritMode DelegatingStaticContext::inheritMode() const +{ + return m_context->inheritMode(); +} + +void DelegatingStaticContext::setInheritMode(const InheritMode mode) +{ + m_context->setInheritMode(mode); +} + +StaticContext::PreserveMode DelegatingStaticContext::preserveMode() const +{ + return m_context->preserveMode(); +} + +void DelegatingStaticContext::setPreserveMode(const PreserveMode mode) +{ + m_context->setPreserveMode(mode); +} + +ItemType::Ptr DelegatingStaticContext::contextItemType() const +{ + return m_context->contextItemType(); +} + +ItemType::Ptr DelegatingStaticContext::currentItemType() const +{ + return m_context->currentItemType(); +} + +ExternalVariableLoader::Ptr DelegatingStaticContext::externalVariableLoader() const +{ + return m_context->externalVariableLoader(); +} + +StaticContext::Ptr DelegatingStaticContext::copy() const +{ + return StaticContext::Ptr(new DelegatingStaticContext(m_context->copy())); +} + +ResourceLoader::Ptr DelegatingStaticContext::resourceLoader() const +{ + return m_context->resourceLoader(); +} + +NamePool::Ptr DelegatingStaticContext::namePool() const +{ + return m_context->namePool(); +} + +void DelegatingStaticContext::addLocation(const SourceLocationReflection *const reflection, + const QSourceLocation &location) +{ + m_context->addLocation(reflection, location); +} + +StaticContext::LocationHash DelegatingStaticContext::sourceLocations() const +{ + return m_context->sourceLocations(); +} + +QSourceLocation DelegatingStaticContext::locationFor(const SourceLocationReflection *const reflection) const +{ + return m_context->locationFor(reflection); +} + +const QAbstractUriResolver *DelegatingStaticContext::uriResolver() const +{ + return m_context->uriResolver(); +} + +VariableSlotID DelegatingStaticContext::currentRangeSlot() const +{ + return m_context->currentRangeSlot(); +} + +VariableSlotID DelegatingStaticContext::allocateRangeSlot() +{ + return m_context->allocateRangeSlot(); +} + +void DelegatingStaticContext::setCompatModeEnabled(const bool newVal) +{ + m_context->setCompatModeEnabled(newVal); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/environment/qdelegatingstaticcontext_p.h b/src/xmlpatterns/environment/qdelegatingstaticcontext_p.h new file mode 100644 index 0000000..c34c994 --- /dev/null +++ b/src/xmlpatterns/environment/qdelegatingstaticcontext_p.h @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_DelegatingStaticContext_H +#define Patternist_DelegatingStaticContext_H + +#include + +#include "qstaticcontext_p.h" +#include "qfunctionfactory_p.h" +#include "qschematypefactory_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Delegates all members to a second instance. Used for + * sub-classing. + * + * @author Frans Englich + */ + class Q_AUTOTEST_EXPORT DelegatingStaticContext : public StaticContext + { + public: + virtual NamespaceResolver::Ptr namespaceBindings() const; + virtual void setNamespaceBindings(const NamespaceResolver::Ptr &); + + virtual FunctionFactory::Ptr functionSignatures() const; + virtual SchemaTypeFactory::Ptr schemaDefinitions() const; + virtual DynamicContext::Ptr dynamicContext() const; + + virtual QUrl baseURI() const; + virtual void setBaseURI(const QUrl &uri); + + virtual bool compatModeEnabled() const; + virtual void setCompatModeEnabled(const bool newVal); + + virtual QUrl defaultCollation() const; + + virtual QAbstractMessageHandler * messageHandler() const; + + virtual void setDefaultCollation(const QUrl &uri); + + virtual BoundarySpacePolicy boundarySpacePolicy() const; + virtual void setBoundarySpacePolicy(const BoundarySpacePolicy policy); + + virtual ConstructionMode constructionMode() const; + virtual void setConstructionMode(const ConstructionMode mode); + + virtual OrderingMode orderingMode() const; + virtual void setOrderingMode(const OrderingMode mode); + virtual OrderingEmptySequence orderingEmptySequence() const; + virtual void setOrderingEmptySequence(const OrderingEmptySequence ordering); + + virtual QString defaultFunctionNamespace() const; + virtual void setDefaultFunctionNamespace(const QString &ns); + + virtual QString defaultElementNamespace() const; + virtual void setDefaultElementNamespace(const QString &ns); + + virtual InheritMode inheritMode() const; + virtual void setInheritMode(const InheritMode mode); + + virtual PreserveMode preserveMode() const; + virtual void setPreserveMode(const PreserveMode mode); + + virtual ItemType::Ptr contextItemType() const; + virtual ItemType::Ptr currentItemType() const; + + virtual StaticContext::Ptr copy() const; + + virtual ExternalVariableLoader::Ptr externalVariableLoader() const; + virtual ResourceLoader::Ptr resourceLoader() const; + virtual NamePool::Ptr namePool() const; + virtual void addLocation(const SourceLocationReflection *const reflection, + const QSourceLocation &location); + virtual LocationHash sourceLocations() const; + virtual QSourceLocation locationFor(const SourceLocationReflection *const reflection) const; + virtual const QAbstractUriResolver *uriResolver() const; + + virtual VariableSlotID currentRangeSlot() const; + virtual VariableSlotID allocateRangeSlot(); + + protected: + DelegatingStaticContext(const StaticContext::Ptr &context); + + private: + const StaticContext::Ptr m_context; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/environment/qdynamiccontext.cpp b/src/xmlpatterns/environment/qdynamiccontext.cpp new file mode 100644 index 0000000..ace8d53 --- /dev/null +++ b/src/xmlpatterns/environment/qdynamiccontext.cpp @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qfocus_p.h" +#include "qreceiverdynamiccontext_p.h" +#include "qstackcontextbase_p.h" + +#include "qdynamiccontext_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +DynamicContext::Ptr DynamicContext::createFocus() +{ + return Ptr(new Focus(Ptr(this))); +} + +DynamicContext::Ptr DynamicContext::createStack() +{ + return Ptr(new StackContext(Ptr(this))); +} + +DynamicContext::Ptr DynamicContext::createReceiverContext(QAbstractXmlReceiver *const receiver) +{ + Q_ASSERT(receiver); + return Ptr(new ReceiverDynamicContext(Ptr(this), receiver)); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/environment/qdynamiccontext_p.h b/src/xmlpatterns/environment/qdynamiccontext_p.h new file mode 100644 index 0000000..131ce54 --- /dev/null +++ b/src/xmlpatterns/environment/qdynamiccontext_p.h @@ -0,0 +1,231 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_DynamicContext_H +#define Patternist_DynamicContext_H + +#include "qautoptr_p.h" +#include "qcachecells_p.h" +#include "qexternalvariableloader_p.h" +#include "qitem_p.h" +#include "qnamepool_p.h" +#include "qnodebuilder_p.h" +#include "qprimitives_p.h" +#include "qreportcontext_p.h" +#include "qresourceloader_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QDateTime; +template class QVector; + +namespace QPatternist +{ + class DayTimeDuration; + class Expression; + class TemplateMode; + + /** + * @short Carries information and facilities used at runtime, and hence + * provides a state for that stage in a thread-safe manner. + * + * @see XQuery + * 1.0: An XML Query Language, 2.1.2 Dynamic Context + * @see XQuery + * 1.0: An XML Query Language, 2.2.3.2 Dynamic Evaluation Phase + * @author Frans Englich + */ + class DynamicContext : public ReportContext + { + public: + /** + * @short Carries template parameters at runtime. + * + * The key is the name of the parameter, and the value the Expression + * which supplies the value. + */ + typedef QHash > TemplateParameterHash; + typedef QExplicitlySharedDataPointer Ptr; + + virtual ~DynamicContext() + { + } + + /** + * This function intentionally returns by reference. + * + * @see globalItemCacheCell() + */ + virtual ItemCacheCell &itemCacheCell(const VariableSlotID slot) = 0; + + /** + * This function intentionally returns by reference. + * + * @see globalItemSequenceCacheCells + */ + virtual ItemSequenceCacheCell::Vector &itemSequenceCacheCells(const VariableSlotID slot) = 0; + + virtual xsInteger contextPosition() const = 0; + virtual Item contextItem() const = 0; + virtual xsInteger contextSize() = 0; + + virtual void setRangeVariable(const VariableSlotID slot, + const Item &newValue) = 0; + virtual Item rangeVariable(const VariableSlotID slot) const = 0; + virtual void setExpressionVariable(const VariableSlotID slot, + const QExplicitlySharedDataPointer &newValue) = 0; + virtual QExplicitlySharedDataPointer + expressionVariable(const VariableSlotID slot) const = 0; + + virtual Item::Iterator::Ptr positionIterator(const VariableSlotID slot) const = 0; + virtual void setPositionIterator(const VariableSlotID slot, + const Item::Iterator::Ptr &newValue) = 0; + + virtual void setFocusIterator(const Item::Iterator::Ptr &it) = 0; + virtual Item::Iterator::Ptr focusIterator() const = 0; + + virtual QExplicitlySharedDataPointer implicitTimezone() const = 0; + virtual QDateTime currentDateTime() const = 0; + + virtual QAbstractXmlReceiver *outputReceiver() const = 0; + virtual NodeBuilder::Ptr nodeBuilder(const QUrl &baseURI) const = 0; + virtual ResourceLoader::Ptr resourceLoader() const = 0; + virtual ExternalVariableLoader::Ptr externalVariableLoader() const = 0; + virtual NamePool::Ptr namePool() const = 0; + + /** + * @short Returns the item that @c fn:current() returns. + * + * Hence, this is not the focus, and very different from the focus. + * + * @see CurrentItemStore + * @see CurrentFN + */ + virtual Item currentItem() const = 0; + + DynamicContext::Ptr createFocus(); + DynamicContext::Ptr createStack(); + DynamicContext::Ptr createReceiverContext(QAbstractXmlReceiver *const receiver); + + /** + * Whenever a tree gets built, this function is called. DynamicContext + * has the responsibility of keeping a copy of @p nm, such that it + * doesn't go out of scope, since no one else will reference @p nm. + * + * I think this is currently only used for temporary node trees. In + * other cases they are stored in the ExternalResourceLoader. + * + * The caller guarantees that @p nm is not @c null. + */ + virtual void addNodeModel(const QAbstractXmlNodeModel::Ptr &nm) = 0; + + /** + * Same as itemCacheCell(), but is only used for global varibles. This + * is needed because sometimes stack frames needs to be created for + * other kinds of variables(such as in the case of user function + * calls), while the global variable(s) needs to continue to use the + * same cache, instead of one for each new stack frame, typically an + * instance of StackContextBase. + * + * This has two effects: + * + * - It's an optimization. Instead of that a global variable gets evaluated each + * time a user function is called, think recursive functions, it's done + * only once. + * - Query stability, hence affects things like node identity and + * therefore conformance. Hence affects for instance what nodes a query + * returns, since node identity affect node deduplication. + */ + virtual ItemCacheCell &globalItemCacheCell(const VariableSlotID slot) = 0; + + /** + * @short When a template is called, this member carries the template + * parameters. + * + * Hence this is similar to the other variable stack functions such as + * rangeVariable() and expressionVariable(), the difference being that + * the order of template parameters as well as its arguments can appear + * in arbitrary order. Hence the name is used to make the order + * insignificant. + */ + virtual TemplateParameterHash &templateParameterStore() = 0; + + /** + * Same as itemSequenceCacheCells() but applies only for global + * variables. + * + * @see globalItemCacheCell() + */ + virtual ItemSequenceCacheCell::Vector &globalItemSequenceCacheCells(const VariableSlotID slot) = 0; + + /** + * @short Returns the previous DynamicContext. If this context is the + * top-level one, @c null is returned. + */ + virtual DynamicContext::Ptr previousContext() const = 0; + + /** + * @short Returns the current template mode that is in effect. + * + * If @c null is returned, it means that the default mode should be + * used as the current mode. + */ + virtual QExplicitlySharedDataPointer currentTemplateMode() const = 0; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/environment/qfocus.cpp b/src/xmlpatterns/environment/qfocus.cpp new file mode 100644 index 0000000..72031bf --- /dev/null +++ b/src/xmlpatterns/environment/qfocus.cpp @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdaytimeduration_p.h" + +#include "qfocus_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Focus::Focus(const DynamicContext::Ptr &prevContext) : DelegatingDynamicContext(prevContext), + m_contextSizeCached(-1) +{ + Q_ASSERT(prevContext); + Q_ASSERT(prevContext != this); +} + +xsInteger Focus::contextPosition() const +{ + Q_ASSERT(m_focusIterator); + return m_focusIterator->position(); +} + +Item Focus::contextItem() const +{ + Q_ASSERT(m_focusIterator); + return m_focusIterator->current(); +} + +xsInteger Focus::contextSize() +{ + Q_ASSERT(m_focusIterator); + if(m_contextSizeCached == -1) + m_contextSizeCached = m_focusIterator->copy()->count(); + + Q_ASSERT_X(m_contextSizeCached == m_focusIterator->copy()->count(), Q_FUNC_INFO, + "If our cache is not the same as the real count, something is wrong."); + + return m_contextSizeCached; +} + +void Focus::setFocusIterator(const Item::Iterator::Ptr &it) +{ + Q_ASSERT(it); + m_focusIterator = it; +} + +Item::Iterator::Ptr Focus::focusIterator() const +{ + return m_focusIterator; +} + +Item Focus::currentItem() const +{ + /* In the case that there is no top level expression that creates a focus, + * fn:current() should return the focus. This logic achieves this. + * Effectively we traverse up our "context stack" through recursion, and + * start returning when we've found the top most focus. */ + + const Item current(m_prevContext->currentItem()); + + if(current.isNull()) + return m_focusIterator->current(); + else + return current; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/environment/qfocus_p.h b/src/xmlpatterns/environment/qfocus_p.h new file mode 100644 index 0000000..94effcf --- /dev/null +++ b/src/xmlpatterns/environment/qfocus_p.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_Focus_H +#define Patternist_Focus_H + +#include "qdelegatingdynamiccontext_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A DynamicContext that maintains the focus, a sequence + * of items. + * + * Focus implements both the outer and inner focus. The focus is one of + * the things that characterizes the XPath language. The focus is what's + * iterated over in a predicate, whose current item can be received + * via the context item expression, .(the dot), + * and whose size is retrievable via the function fn:last(). + * + * @author Frans Englich + */ + class Focus : public DelegatingDynamicContext + { + public: + Focus(const DynamicContext::Ptr &prevContext); + + virtual xsInteger contextPosition() const; + virtual Item contextItem() const; + virtual xsInteger contextSize(); + + virtual void setFocusIterator(const Item::Iterator::Ptr &it); + virtual Item::Iterator::Ptr focusIterator() const; + + /** + * If there is no top level expression that sets the current item, + * the focus should be used. This implementation ensures that. + */ + virtual Item currentItem() const; + + private: + Item::Iterator::Ptr m_focusIterator; + xsInteger m_contextSizeCached; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/environment/qgenericdynamiccontext.cpp b/src/xmlpatterns/environment/qgenericdynamiccontext.cpp new file mode 100644 index 0000000..e721052 --- /dev/null +++ b/src/xmlpatterns/environment/qgenericdynamiccontext.cpp @@ -0,0 +1,205 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonvalues_p.h" +#include "qfocus_p.h" +#include "qtemplatemode_p.h" + +#include "qgenericdynamiccontext_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +GenericDynamicContext::GenericDynamicContext(const NamePool::Ptr &np, + QAbstractMessageHandler *const errHandler, + const LocationHash &locations) : m_messageHandler(errHandler) + , m_currentDateTime(QDateTime::currentDateTime().toTimeSpec(Qt::UTC)) + , m_outputReceiver(0) + , m_namePool(np) + , m_locations(locations) + , m_uriResolver(0) +{ + Q_ASSERT(m_messageHandler); + Q_ASSERT(m_namePool); +} + +QExplicitlySharedDataPointer GenericDynamicContext::implicitTimezone() const +{ + /* Or what do you prefer, sir? */ + return CommonValues::DayTimeDurationZero; +} + +QAbstractMessageHandler * GenericDynamicContext::messageHandler() const +{ + return m_messageHandler; +} + +QDateTime GenericDynamicContext::currentDateTime() const +{ + return m_currentDateTime; +} + +xsInteger GenericDynamicContext::contextPosition() const +{ + Q_ASSERT_X(false, Q_FUNC_INFO, "That this function is called makes no sense. A Focus should be used."); + return 0; +} + +Item GenericDynamicContext::contextItem() const +{ + return Item(); +} + +xsInteger GenericDynamicContext::contextSize() +{ + Q_ASSERT_X(false, Q_FUNC_INFO, "That this function is called makes no sense. A Focus should be used."); + return 0; +} + +void GenericDynamicContext::setFocusIterator(const Item::Iterator::Ptr &) +{ + Q_ASSERT_X(false, Q_FUNC_INFO, "That this function is called makes no sense. A Focus should be used."); +} + +Item::Iterator::Ptr GenericDynamicContext::focusIterator() const +{ + return Item::Iterator::Ptr(); +} + +QAbstractXmlReceiver *GenericDynamicContext::outputReceiver() const +{ + return m_outputReceiver; +} + +void GenericDynamicContext::setOutputReceiver(QAbstractXmlReceiver *const receiver) +{ + m_outputReceiver = receiver; +} + +void GenericDynamicContext::setNodeBuilder(NodeBuilder::Ptr &builder) +{ + m_nodeBuilder = builder; +} + +NodeBuilder::Ptr GenericDynamicContext::nodeBuilder(const QUrl &baseURI) const +{ + return m_nodeBuilder->create(baseURI); +} + +ResourceLoader::Ptr GenericDynamicContext::resourceLoader() const +{ + return m_resourceLoader; +} + +void GenericDynamicContext::setResourceLoader(const ResourceLoader::Ptr &loader) +{ + m_resourceLoader = loader; +} + +ExternalVariableLoader::Ptr GenericDynamicContext::externalVariableLoader() const +{ + return m_externalVariableLoader; +} + +void GenericDynamicContext::setExternalVariableLoader(const ExternalVariableLoader::Ptr &loader) +{ + m_externalVariableLoader = loader; +} + +NamePool::Ptr GenericDynamicContext::namePool() const +{ + return m_namePool; +} + +QSourceLocation GenericDynamicContext::locationFor(const SourceLocationReflection *const reflection) const +{ + + return m_locations.value(reflection->actualReflection()); +} + +void GenericDynamicContext::addNodeModel(const QAbstractXmlNodeModel::Ptr &nm) +{ + m_nodeModels.append(nm); +} + +const QAbstractUriResolver *GenericDynamicContext::uriResolver() const +{ + return m_uriResolver; +} + +ItemCacheCell &GenericDynamicContext::globalItemCacheCell(const VariableSlotID slot) +{ + if(slot >= m_globalItemCacheCells.size()) + m_globalItemCacheCells.resize(qMax(slot + 1, m_globalItemCacheCells.size())); + + return m_globalItemCacheCells[slot]; +} + +ItemSequenceCacheCell::Vector &GenericDynamicContext::globalItemSequenceCacheCells(const VariableSlotID slot) +{ + if(slot >= m_globalItemSequenceCacheCells.size()) + m_globalItemSequenceCacheCells.resize(qMax(slot + 1, m_globalItemSequenceCacheCells.size())); + + return m_globalItemSequenceCacheCells; +} + +void GenericDynamicContext::setUriResolver(const QAbstractUriResolver *const resolver) +{ + m_uriResolver = resolver; +} + +Item GenericDynamicContext::currentItem() const +{ + return Item(); +} + +DynamicContext::Ptr GenericDynamicContext::previousContext() const +{ + return DynamicContext::Ptr(); +} + +QExplicitlySharedDataPointer GenericDynamicContext::currentTemplateMode() const +{ + return QExplicitlySharedDataPointer(); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/environment/qgenericdynamiccontext_p.h b/src/xmlpatterns/environment/qgenericdynamiccontext_p.h new file mode 100644 index 0000000..1b95dfd --- /dev/null +++ b/src/xmlpatterns/environment/qgenericdynamiccontext_p.h @@ -0,0 +1,155 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_GenericDynamicContext_H +#define Patternist_GenericDynamicContext_H + +#include +#include + +#include "qdaytimeduration_p.h" +#include "qstackcontextbase_p.h" +#include "qexpression_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A DynamicContext supplying basic information that always is used. + * + * This DynamicContext is the first DynamicContext used during + * a run and is always used. In addition, more contexts, such as + * a Focus can be created. + * + * @author Frans Englich + */ + class GenericDynamicContext : public StackContextBase + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + GenericDynamicContext(const NamePool::Ptr &np, + QAbstractMessageHandler *const messageHandler, + const LocationHash &locations); + + virtual xsInteger contextPosition() const; + /** + * @returns always @c null, the focus is always undefined when an GenericDynamicContext + * is used. + */ + virtual Item contextItem() const; + virtual xsInteger contextSize(); + + virtual void setFocusIterator(const Item::Iterator::Ptr &it); + virtual Item::Iterator::Ptr focusIterator() const; + + virtual QAbstractMessageHandler * messageHandler() const; + virtual QExplicitlySharedDataPointer implicitTimezone() const; + virtual QDateTime currentDateTime() const; + + virtual QAbstractXmlReceiver *outputReceiver() const; + void setOutputReceiver(QAbstractXmlReceiver *const receiver); + + virtual NodeBuilder::Ptr nodeBuilder(const QUrl &baseURI) const; + void setNodeBuilder(NodeBuilder::Ptr &builder); + + virtual ResourceLoader::Ptr resourceLoader() const; + void setResourceLoader(const ResourceLoader::Ptr &loader); + + virtual ExternalVariableLoader::Ptr externalVariableLoader() const; + void setExternalVariableLoader(const ExternalVariableLoader::Ptr &loader); + virtual NamePool::Ptr namePool() const; + virtual QSourceLocation locationFor(const SourceLocationReflection *const reflection) const; + virtual void addNodeModel(const QAbstractXmlNodeModel::Ptr &nm); + virtual const QAbstractUriResolver *uriResolver() const; + virtual ItemCacheCell &globalItemCacheCell(const VariableSlotID slot); + virtual ItemSequenceCacheCell::Vector &globalItemSequenceCacheCells(const VariableSlotID slot); + + void setUriResolver(const QAbstractUriResolver *const resolver); + + /** + * We return a null item, we have no focus. + */ + virtual Item currentItem() const; + + /** + * @short Returns always @c null, since we're always + * a top-level context. + */ + virtual DynamicContext::Ptr previousContext() const; + + virtual QExplicitlySharedDataPointer currentTemplateMode() const; + + private: + QAbstractMessageHandler * m_messageHandler; + const QDateTime m_currentDateTime; + const DayTimeDuration::Ptr m_zoneOffset; + QAbstractXmlReceiver * m_outputReceiver; + mutable NodeBuilder::Ptr m_nodeBuilder; + ExternalVariableLoader::Ptr m_externalVariableLoader; + ResourceLoader::Ptr m_resourceLoader; + NamePool::Ptr m_namePool; + const LocationHash m_locations; + QAbstractXmlNodeModel::List m_nodeModels; + const QAbstractUriResolver * m_uriResolver; + ItemCacheCell::Vector m_globalItemCacheCells; + ItemSequenceCacheCell::Vector m_globalItemSequenceCacheCells; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/environment/qgenericstaticcontext.cpp b/src/xmlpatterns/environment/qgenericstaticcontext.cpp new file mode 100644 index 0000000..146f468 --- /dev/null +++ b/src/xmlpatterns/environment/qgenericstaticcontext.cpp @@ -0,0 +1,338 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* Patternist */ +#include "qbasictypesfactory_p.h" +#include "qcommonnamespaces_p.h" +#include "qgenericdynamiccontext_p.h" +#include "qfunctionfactorycollection_p.h" +#include "qgenericnamespaceresolver_p.h" + +#include "qgenericstaticcontext_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +GenericStaticContext::GenericStaticContext(const NamePool::Ptr &np, + QAbstractMessageHandler *const handler, + const QUrl &aBaseURI, + const FunctionFactory::Ptr &factory, + const QXmlQuery::QueryLanguage lang) : m_boundarySpacePolicy(BSPStrip) + , m_constructionMode(CMPreserve) + , m_functionFactory(factory) + , m_defaultFunctionNamespace(CommonNamespaces::XFN) + , m_orderingEmptySequence(Greatest) + , m_orderingMode(Ordered) + , m_defaultCollation(QUrl::fromEncoded(CommonNamespaces::UNICODE_COLLATION)) + , m_baseURI(aBaseURI) + , m_messageHandler(handler) + , m_preserveMode(Preserve) + , m_inheritMode(Inherit) + , m_namespaceResolver(lang == QXmlQuery::XQuery10 + ? GenericNamespaceResolver::defaultXQueryBindings() + : GenericNamespaceResolver::defaultXSLTBindings()) + , m_namePool(np) + , m_uriResolver(0) + , m_queryLanguage(lang) + , m_rangeSlot(-1) + , m_compatModeEnabled(false) +{ + /* We'll easily have at least this many AST nodes, that we need + * to track locations for. */ + m_locations.reserve(30); + + Q_ASSERT(np); + Q_ASSERT(!m_baseURI.isRelative()); +} + +NamespaceResolver::Ptr GenericStaticContext::namespaceBindings() const +{ + return m_namespaceResolver; +} + +FunctionFactory::Ptr GenericStaticContext::functionSignatures() const +{ + return m_functionFactory; +} + +DynamicContext::Ptr GenericStaticContext::dynamicContext() const +{ + GenericDynamicContext::Ptr context(new GenericDynamicContext(m_namePool, m_messageHandler, sourceLocations())); + // TODO we have many bugs here.. + context->setResourceLoader(m_resourceLoader); + return context; +} + +SchemaTypeFactory::Ptr GenericStaticContext::schemaDefinitions() const +{ + return BasicTypesFactory::self(m_namePool); +} + +QUrl GenericStaticContext::baseURI() const +{ + Q_ASSERT_X(!m_baseURI.isRelative(), Q_FUNC_INFO, + "The static base-uri must be absolute. This error is most likely caused by misuing the API."); + return m_baseURI; +} + +void GenericStaticContext::setBaseURI(const QUrl &uri) +{ + Q_ASSERT(!uri.isRelative()); + m_baseURI = uri; +} + +bool GenericStaticContext::compatModeEnabled() const +{ + return m_compatModeEnabled; +} + +void GenericStaticContext::setCompatModeEnabled(const bool newVal) +{ + m_compatModeEnabled = newVal; +} + +QUrl GenericStaticContext::defaultCollation() const +{ + return m_defaultCollation; +} + +QAbstractMessageHandler * GenericStaticContext::messageHandler() const +{ + return m_messageHandler; +} + +void GenericStaticContext::setDefaultCollation(const QUrl &uri) +{ + m_defaultCollation = uri; +} + +void GenericStaticContext::setNamespaceBindings(const NamespaceResolver::Ptr &resolver) +{ + Q_ASSERT(resolver); + m_namespaceResolver = resolver; +} + +StaticContext::BoundarySpacePolicy GenericStaticContext::boundarySpacePolicy() const +{ + return m_boundarySpacePolicy; +} + +void GenericStaticContext::setBoundarySpacePolicy(const BoundarySpacePolicy policy) +{ + Q_ASSERT(policy == BSPPreserve || policy == BSPStrip); + m_boundarySpacePolicy = policy; +} + +StaticContext::ConstructionMode GenericStaticContext::constructionMode() const +{ + return m_constructionMode; +} + +void GenericStaticContext::setConstructionMode(const ConstructionMode mode) +{ + Q_ASSERT(mode == CMPreserve || mode == CMStrip); + m_constructionMode = mode; +} + +StaticContext::OrderingMode GenericStaticContext::orderingMode() const +{ + return m_orderingMode; +} + +void GenericStaticContext::setOrderingMode(const OrderingMode mode) +{ + Q_ASSERT(mode == Ordered || mode == Unordered); + m_orderingMode = mode; +} + +StaticContext::OrderingEmptySequence GenericStaticContext::orderingEmptySequence() const +{ + return m_orderingEmptySequence; +} + +void GenericStaticContext::setOrderingEmptySequence(const OrderingEmptySequence ordering) +{ + Q_ASSERT(ordering == Greatest || ordering == Least); + m_orderingEmptySequence = ordering; +} + +QString GenericStaticContext::defaultFunctionNamespace() const +{ + return m_defaultFunctionNamespace; +} + +void GenericStaticContext::setDefaultFunctionNamespace(const QString &ns) +{ + m_defaultFunctionNamespace = ns; +} + + +QString GenericStaticContext::defaultElementNamespace() const +{ + return m_defaultElementNamespace; +} + +void GenericStaticContext::setDefaultElementNamespace(const QString &ns) +{ + m_defaultElementNamespace = ns; +} + +StaticContext::InheritMode GenericStaticContext::inheritMode() const +{ + return m_inheritMode; +} + +void GenericStaticContext::setInheritMode(const InheritMode mode) +{ + Q_ASSERT(mode == Inherit || mode == NoInherit); + m_inheritMode = mode; +} + +StaticContext::PreserveMode GenericStaticContext::preserveMode() const +{ + return m_preserveMode; +} + +void GenericStaticContext::setPreserveMode(const PreserveMode mode) +{ + Q_ASSERT(mode == Preserve || mode == NoPreserve); + m_preserveMode = mode; +} + +ItemType::Ptr GenericStaticContext::contextItemType() const +{ + return m_contextItemType; +} + +ItemType::Ptr GenericStaticContext::currentItemType() const +{ + return contextItemType(); +} + +void GenericStaticContext::setContextItemType(const ItemType::Ptr &type) +{ + m_contextItemType = type; +} + +StaticContext::Ptr GenericStaticContext::copy() const +{ + GenericStaticContext *const retval = new GenericStaticContext(m_namePool, m_messageHandler, m_baseURI, m_functionFactory, m_queryLanguage); + const NamespaceResolver::Ptr newSolver(new GenericNamespaceResolver(m_namespaceResolver->bindings())); + + retval->setNamespaceBindings(newSolver); + retval->setDefaultCollation(m_defaultCollation); + retval->setBoundarySpacePolicy(m_boundarySpacePolicy); + retval->setConstructionMode(m_constructionMode); + retval->setOrderingMode(m_orderingMode); + retval->setOrderingEmptySequence(m_orderingEmptySequence); + retval->setDefaultFunctionNamespace(m_defaultFunctionNamespace); + retval->setInheritMode(m_inheritMode); + retval->setPreserveMode(m_preserveMode); + retval->setExternalVariableLoader(m_externalVariableLoader); + retval->setResourceLoader(m_resourceLoader); + retval->setContextItemType(m_contextItemType); + retval->m_locations = m_locations; + + return StaticContext::Ptr(retval); +} + +ResourceLoader::Ptr GenericStaticContext::resourceLoader() const +{ + return m_resourceLoader; +} + +void GenericStaticContext::setResourceLoader(const ResourceLoader::Ptr &loader) +{ + m_resourceLoader = loader; +} + +ExternalVariableLoader::Ptr GenericStaticContext::externalVariableLoader() const +{ + return m_externalVariableLoader; +} + +void GenericStaticContext::setExternalVariableLoader(const ExternalVariableLoader::Ptr &loader) +{ + m_externalVariableLoader = loader; +} + +NamePool::Ptr GenericStaticContext::namePool() const +{ + return m_namePool; +} + +void GenericStaticContext::addLocation(const SourceLocationReflection *const reflection, + const QSourceLocation &location) +{ + Q_ASSERT(!location.isNull()); + Q_ASSERT_X(reflection, Q_FUNC_INFO, + "The reflection cannot be zero."); + m_locations.insert(reflection, location); +} + +StaticContext::LocationHash GenericStaticContext::sourceLocations() const +{ + return m_locations; +} + +QSourceLocation GenericStaticContext::locationFor(const SourceLocationReflection *const reflection) const +{ + return m_locations.value(reflection->actualReflection()); +} + +QAbstractUriResolver *GenericStaticContext::uriResolver() const +{ + return m_uriResolver; +} + +VariableSlotID GenericStaticContext::currentRangeSlot() const +{ + return m_rangeSlot; +} + +VariableSlotID GenericStaticContext::allocateRangeSlot() +{ + ++m_rangeSlot; + return m_rangeSlot; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/environment/qgenericstaticcontext_p.h b/src/xmlpatterns/environment/qgenericstaticcontext_p.h new file mode 100644 index 0000000..1ee9949 --- /dev/null +++ b/src/xmlpatterns/environment/qgenericstaticcontext_p.h @@ -0,0 +1,199 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_GenericStaticContext_H +#define Patternist_GenericStaticContext_H + +#include +#include + +#include "qstaticcontext_p.h" +#include "qfunctionfactory_p.h" +#include "qschematypefactory_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Provides setters and getters for the properties defined in StaticContext. + * + * @author Frans Englich + */ + class GenericStaticContext : public StaticContext + { + public: + typedef QExplicitlySharedDataPointer Ptr; + /** + * Constructs a GenericStaticContext. The components are initialized as per + * the recommended default values in XQuery 1.0. Default order for empty sequences, + * orderingEmptySequence(), is initialized to Greatest. + * + * @see XQuery + * 1.0: An XML Query Language, C.1 Static Context Components + * @param errorHandler the error handler. May be null. + * @param np the NamePool. May not be null. + * @param aBaseURI the base URI in the static context. Must be absolute + * and valid. + */ + GenericStaticContext(const NamePool::Ptr &np, + QAbstractMessageHandler *const errorHandler, + const QUrl &aBaseURI, + const FunctionFactory::Ptr &factory, + const QXmlQuery::QueryLanguage lang); + + virtual NamespaceResolver::Ptr namespaceBindings() const; + virtual void setNamespaceBindings(const NamespaceResolver::Ptr &); + + virtual FunctionFactory::Ptr functionSignatures() const; + virtual SchemaTypeFactory::Ptr schemaDefinitions() const; + + /** + * Returns a DynamicContext used for evaluation at compile time. + * + * @bug The DynamicContext isn't stable. It should be cached privately. + */ + virtual DynamicContext::Ptr dynamicContext() const; + + virtual QUrl baseURI() const; + virtual void setBaseURI(const QUrl &uri); + + virtual bool compatModeEnabled() const; + virtual void setCompatModeEnabled(const bool newVal); + + /** + * @returns always the Unicode codepoint collation URI + */ + virtual QUrl defaultCollation() const; + + virtual QAbstractMessageHandler * messageHandler() const; + + virtual void setDefaultCollation(const QUrl &uri); + + virtual BoundarySpacePolicy boundarySpacePolicy() const; + virtual void setBoundarySpacePolicy(const BoundarySpacePolicy policy); + + virtual ConstructionMode constructionMode() const; + virtual void setConstructionMode(const ConstructionMode mode); + + virtual OrderingMode orderingMode() const; + virtual void setOrderingMode(const OrderingMode mode); + virtual OrderingEmptySequence orderingEmptySequence() const; + virtual void setOrderingEmptySequence(const OrderingEmptySequence ordering); + + virtual QString defaultFunctionNamespace() const; + virtual void setDefaultFunctionNamespace(const QString &ns); + + virtual QString defaultElementNamespace() const; + virtual void setDefaultElementNamespace(const QString &ns); + + virtual InheritMode inheritMode() const; + virtual void setInheritMode(const InheritMode mode); + + virtual PreserveMode preserveMode() const; + virtual void setPreserveMode(const PreserveMode mode); + + virtual ItemType::Ptr contextItemType() const; + void setContextItemType(const ItemType::Ptr &type); + virtual ItemType::Ptr currentItemType() const; + + virtual StaticContext::Ptr copy() const; + + virtual ResourceLoader::Ptr resourceLoader() const; + void setResourceLoader(const ResourceLoader::Ptr &loader); + + virtual ExternalVariableLoader::Ptr externalVariableLoader() const; + void setExternalVariableLoader(const ExternalVariableLoader::Ptr &loader); + virtual NamePool::Ptr namePool() const; + + virtual void addLocation(const SourceLocationReflection *const reflection, + const QSourceLocation &location); + virtual QSourceLocation locationFor(const SourceLocationReflection *const reflection) const; + + virtual LocationHash sourceLocations() const; + virtual QAbstractUriResolver *uriResolver() const; + + virtual VariableSlotID currentRangeSlot() const; + virtual VariableSlotID allocateRangeSlot(); + + private: + BoundarySpacePolicy m_boundarySpacePolicy; + ConstructionMode m_constructionMode; + FunctionFactory::Ptr m_functionFactory; + QString m_defaultElementNamespace; + QString m_defaultFunctionNamespace; + OrderingEmptySequence m_orderingEmptySequence; + OrderingMode m_orderingMode; + QUrl m_defaultCollation; + QUrl m_baseURI; + QAbstractMessageHandler * m_messageHandler; + PreserveMode m_preserveMode; + InheritMode m_inheritMode; + NamespaceResolver::Ptr m_namespaceResolver; + ExternalVariableLoader::Ptr m_externalVariableLoader; + ResourceLoader::Ptr m_resourceLoader; + const NamePool::Ptr m_namePool; + ItemType::Ptr m_contextItemType; + LocationHash m_locations; + QAbstractUriResolver * m_uriResolver; + QXmlQuery::QueryLanguage m_queryLanguage; + VariableSlotID m_rangeSlot; + bool m_compatModeEnabled; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/environment/qreceiverdynamiccontext.cpp b/src/xmlpatterns/environment/qreceiverdynamiccontext.cpp new file mode 100644 index 0000000..8425fea --- /dev/null +++ b/src/xmlpatterns/environment/qreceiverdynamiccontext.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qreceiverdynamiccontext_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +ReceiverDynamicContext:: +ReceiverDynamicContext(const DynamicContext::Ptr &prevContext, + QAbstractXmlReceiver *const receiver) : DelegatingDynamicContext(prevContext) + , m_receiver(receiver) +{ + Q_ASSERT(receiver); +} + +QAbstractXmlReceiver *ReceiverDynamicContext::outputReceiver() const +{ + return m_receiver; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/environment/qreceiverdynamiccontext_p.h b/src/xmlpatterns/environment/qreceiverdynamiccontext_p.h new file mode 100644 index 0000000..ab3359b --- /dev/null +++ b/src/xmlpatterns/environment/qreceiverdynamiccontext_p.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ReceiverDynamicContext_H +#define Patternist_ReceiverDynamicContext_H + +#include "qdelegatingdynamiccontext_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A DynamicContext that has a specialized QAbstractXmlReceiver. + * + * @author Frans Englich + */ + class ReceiverDynamicContext : public DelegatingDynamicContext + { + public: + /** + * Construct a ReceiverDynamicContext and passes @p prevContext to its super class. This + * constructor is typically used when the super class is DelegatingDynamicContext. + */ + ReceiverDynamicContext(const DynamicContext::Ptr &prevContext, + QAbstractXmlReceiver *const receiver); + + virtual QAbstractXmlReceiver *outputReceiver() const; + + private: + QAbstractXmlReceiver *const m_receiver; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/environment/qreportcontext.cpp b/src/xmlpatterns/environment/qreportcontext.cpp new file mode 100644 index 0000000..c82acba --- /dev/null +++ b/src/xmlpatterns/environment/qreportcontext.cpp @@ -0,0 +1,479 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qabstractmessagehandler.h" + +#include "qcommonnamespaces_p.h" +#include "qexpression_p.h" + +#include "qreportcontext_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +ReportContext::~ReportContext() +{ +} + +QString ReportContext::finalizeDescription(const QString &desc) +{ + return QLatin1String("

") + + desc + + QLatin1String("

"); +} + +void ReportContext::warning(const QString &description, + const QSourceLocation &sourceLocation) +{ + messageHandler()->message(QtWarningMsg, finalizeDescription(description), QUrl(), sourceLocation); +} + +void ReportContext::createError(const QString &description, + const QtMsgType type, + const QUrl &id, + const QSourceLocation &sourceLocation) const +{ + messageHandler()->message(type, finalizeDescription(description), id, sourceLocation); + throw Exception(true); +} + +void ReportContext::error(const QString &msg, + const ErrorCode code, + const QSourceLocation &sourceLocation) +{ + createError(msg, QtFatalMsg, + QUrl(CommonNamespaces::XPERR + QLatin1Char('#') + codeToString(code)), + sourceLocation); +} + +QSourceLocation ReportContext::lookupSourceLocation(const SourceLocationReflection *const r) const +{ + Q_ASSERT(r); + const SourceLocationReflection *const actual = r->actualReflection(); + Q_ASSERT(actual); + + const QSourceLocation &sl = actual->sourceLocation(); + + if(sl.isNull()) + { + Q_ASSERT_X(!locationFor(actual).isNull(), Q_FUNC_INFO, + qPrintable(QString::fromLatin1("No location is available for: %1").arg(actual->description()))); + return locationFor(actual); + } + else + return sl; +} + +void ReportContext::error(const QString &message, + const ReportContext::ErrorCode errorCode, + const SourceLocationReflection *const reflection) +{ + Q_ASSERT(reflection); + error(message, errorCode, lookupSourceLocation(reflection)); +} + +void ReportContext::error(const QString &msg, + const QXmlName qname, + const SourceLocationReflection *const reflection) +{ + Q_ASSERT(!qname.isNull()); + createError(msg, QtFatalMsg, + QUrl(namePool()->stringForNamespace(qname.namespaceURI()) + QLatin1Char('#') + namePool()->stringForLocalName(qname.localName())), + lookupSourceLocation(reflection)); +} + +QString ReportContext::codeFromURI(const QString &typeURI, + QString &uri) +{ + /* Wouldn't surprise me if this can be done more efficiently. */ + QUrl source(typeURI); + + const QString code(source.fragment()); + source.setFragment(QString()); + uri = source.toString(); + return code; +} + +QString ReportContext::codeToString(const ReportContext::ErrorCode code) +{ + const char *result = 0; + + switch(code) + { + /* Alphabetically. */ + case FOAR0001: result = "FOAR0001"; break; + case FOAR0002: result = "FOAR0002"; break; + case FOCA0001: result = "FOCA0001"; break; + case FOCA0002: result = "FOCA0002"; break; + case FOCA0003: result = "FOCA0003"; break; + case FOCA0005: result = "FOCA0005"; break; + case FOCA0006: result = "FOCA0006"; break; + case FOCH0001: result = "FOCH0001"; break; + case FOCH0002: result = "FOCH0002"; break; + case FOCH0003: result = "FOCH0003"; break; + case FOCH0004: result = "FOCH0004"; break; + case FODC0001: result = "FODC0001"; break; + case FODC0002: result = "FODC0002"; break; + case FODC0003: result = "FODC0003"; break; + case FODC0004: result = "FODC0004"; break; + case FODC0005: result = "FODC0005"; break; + case FODT0001: result = "FODT0001"; break; + case FODT0002: result = "FODT0002"; break; + case FODT0003: result = "FODT0003"; break; + case FOER0000: result = "FOER0000"; break; + case FONS0004: result = "FONS0004"; break; + case FONS0005: result = "FONS0005"; break; + case FORG0001: result = "FORG0001"; break; + case FORG0002: result = "FORG0002"; break; + case FORG0003: result = "FORG0003"; break; + case FORG0004: result = "FORG0004"; break; + case FORG0005: result = "FORG0005"; break; + case FORG0006: result = "FORG0006"; break; + case FORG0008: result = "FORG0008"; break; + case FORG0009: result = "FORG0009"; break; + case FORX0001: result = "FORX0001"; break; + case FORX0002: result = "FORX0002"; break; + case FORX0003: result = "FORX0003"; break; + case FORX0004: result = "FORX0004"; break; + case FOTY0012: result = "FOTY0012"; break; + case SENR0001: result = "SENR0001"; break; + case SEPM0004: result = "SEPM0004"; break; + case SEPM0009: result = "SEPM0009"; break; + case SEPM0010: result = "SEPM0010"; break; + case SEPM0016: result = "SEPM0016"; break; + case SERE0003: result = "SERE0003"; break; + case SERE0005: result = "SERE0005"; break; + case SERE0006: result = "SERE0006"; break; + case SERE0008: result = "SERE0008"; break; + case SERE0012: result = "SERE0012"; break; + case SERE0014: result = "SERE0014"; break; + case SERE0015: result = "SERE0015"; break; + case SESU0007: result = "SESU0007"; break; + case SESU0011: result = "SESU0011"; break; + case SESU0013: result = "SESU0013"; break; + case XPDY0002: result = "XPDY0002"; break; + case XPDY0021: result = "XPDY0021"; break; + case XPDY0050: result = "XPDY0050"; break; + case XPST0001: result = "XPST0001"; break; + case XPST0003: result = "XPST0003"; break; + case XPST0005: result = "XPST0005"; break; + case XPST0008: result = "XPST0008"; break; + case XPST0010: result = "XPST0010"; break; + case XPST0017: result = "XPST0017"; break; + case XPST0051: result = "XPST0051"; break; + case XPST0080: result = "XPST0080"; break; + case XPST0081: result = "XPST0081"; break; + case XPST0083: result = "XPST0083"; break; + case XPTY0004: result = "XPTY0004"; break; + case XPTY0006: result = "XPTY0006"; break; + case XPTY0007: result = "XPTY0007"; break; + case XPTY0018: result = "XPTY0018"; break; + case XPTY0019: result = "XPTY0019"; break; + case XPTY0020: result = "XPTY0020"; break; + case XQDY0025: result = "XQDY0025"; break; + case XQDY0026: result = "XQDY0026"; break; + case XQDY0027: result = "XQDY0027"; break; + case XQDY0029: result = "XQDY0029"; break; + case XQDY0041: result = "XQDY0041"; break; + case XQDY0044: result = "XQDY0044"; break; + case XQDY0052: result = "XQDY0052"; break; + case XQDY0061: result = "XQDY0061"; break; + case XQDY0062: result = "XQDY0062"; break; + case XQDY0064: result = "XQDY0064"; break; + case XQDY0072: result = "XQDY0072"; break; + case XQDY0074: result = "XQDY0074"; break; + case XQDY0084: result = "XQDY0084"; break; + case XQDY0091: result = "XQDY0091"; break; + case XQDY0092: result = "XQDY0092"; break; + case XQST0009: result = "XQST0009"; break; + case XQST0012: result = "XQST0012"; break; + case XQST0013: result = "XQST0013"; break; + case XQST0014: result = "XQST0014"; break; + case XQST0015: result = "XQST0015"; break; + case XQST0016: result = "XQST0016"; break; + case XQST0022: result = "XQST0022"; break; + case XQST0031: result = "XQST0031"; break; + case XQST0032: result = "XQST0032"; break; + case XQST0033: result = "XQST0033"; break; + case XQST0034: result = "XQST0034"; break; + case XQST0035: result = "XQST0035"; break; + case XQST0036: result = "XQST0036"; break; + case XQST0037: result = "XQST0037"; break; + case XQST0038: result = "XQST0038"; break; + case XQST0039: result = "XQST0039"; break; + case XQST0040: result = "XQST0040"; break; + case XQST0042: result = "XQST0042"; break; + case XQST0043: result = "XQST0043"; break; + case XQST0045: result = "XQST0045"; break; + case XQST0046: result = "XQST0046"; break; + case XQST0047: result = "XQST0047"; break; + case XQST0048: result = "XQST0048"; break; + case XQST0049: result = "XQST0049"; break; + case XQST0053: result = "XQST0053"; break; + case XQST0054: result = "XQST0054"; break; + case XQST0055: result = "XQST0055"; break; + case XQST0056: result = "XQST0056"; break; + case XQST0057: result = "XQST0057"; break; + case XQST0058: result = "XQST0058"; break; + case XQST0059: result = "XQST0059"; break; + case XQST0060: result = "XQST0060"; break; + case XQST0063: result = "XQST0063"; break; + case XQST0065: result = "XQST0065"; break; + case XQST0066: result = "XQST0066"; break; + case XQST0067: result = "XQST0067"; break; + case XQST0068: result = "XQST0068"; break; + case XQST0069: result = "XQST0069"; break; + case XQST0070: result = "XQST0070"; break; + case XQST0071: result = "XQST0071"; break; + case XQST0073: result = "XQST0073"; break; + case XQST0075: result = "XQST0075"; break; + case XQST0076: result = "XQST0076"; break; + case XQST0077: result = "XQST0077"; break; + case XQST0078: result = "XQST0078"; break; + case XQST0079: result = "XQST0079"; break; + case XQST0082: result = "XQST0082"; break; + case XQST0085: result = "XQST0085"; break; + case XQST0087: result = "XQST0087"; break; + case XQST0088: result = "XQST0088"; break; + case XQST0089: result = "XQST0089"; break; + case XQST0090: result = "XQST0090"; break; + case XQST0093: result = "XQST0093"; break; + case XQTY0023: result = "XQTY0023"; break; + case XQTY0024: result = "XQTY0024"; break; + case XQTY0028: result = "XQTY0028"; break; + case XQTY0030: result = "XQTY0030"; break; + case XQTY0086: result = "XQTY0086"; break; + case XTDE0030: result = "XTDE0030"; break; + case XTDE0040: result = "XTDE0040"; break; + case XTDE0045: result = "XTDE0045"; break; + case XTDE0047: result = "XTDE0047"; break; + case XTDE0050: result = "XTDE0050"; break; + case XTDE0060: result = "XTDE0060"; break; + case XTDE0160: result = "XTDE0160"; break; + case XTDE0290: result = "XTDE0290"; break; + case XTDE0410: result = "XTDE0410"; break; + case XTDE0420: result = "XTDE0420"; break; + case XTDE0430: result = "XTDE0430"; break; + case XTDE0440: result = "XTDE0440"; break; + case XTDE0485: result = "XTDE0485"; break; + case XTDE0560: result = "XTDE0560"; break; + case XTDE0610: result = "XTDE0610"; break; + case XTDE0640: result = "XTDE0640"; break; + case XTDE0700: result = "XTDE0700"; break; + case XTDE0820: result = "XTDE0820"; break; + case XTDE0830: result = "XTDE0830"; break; + case XTDE0835: result = "XTDE0835"; break; + case XTDE0850: result = "XTDE0850"; break; + case XTDE0855: result = "XTDE0855"; break; + case XTDE0860: result = "XTDE0860"; break; + case XTDE0865: result = "XTDE0865"; break; + case XTDE0890: result = "XTDE0890"; break; + case XTDE0905: result = "XTDE0905"; break; + case XTDE0920: result = "XTDE0920"; break; + case XTDE0925: result = "XTDE0925"; break; + case XTDE0930: result = "XTDE0930"; break; + case XTDE0980: result = "XTDE0980"; break; + case XTDE1030: result = "XTDE1030"; break; + case XTDE1035: result = "XTDE1035"; break; + case XTDE1110: result = "XTDE1110"; break; + case XTDE1140: result = "XTDE1140"; break; + case XTDE1145: result = "XTDE1145"; break; + case XTDE1150: result = "XTDE1150"; break; + case XTDE1170: result = "XTDE1170"; break; + case XTDE1190: result = "XTDE1190"; break; + case XTDE1200: result = "XTDE1200"; break; + case XTDE1260: result = "XTDE1260"; break; + case XTDE1270: result = "XTDE1270"; break; + case XTDE1280: result = "XTDE1280"; break; + case XTDE1310: result = "XTDE1310"; break; + case XTDE1340: result = "XTDE1340"; break; + case XTDE1350: result = "XTDE1350"; break; + case XTDE1360: result = "XTDE1360"; break; + case XTDE1370: result = "XTDE1370"; break; + case XTDE1380: result = "XTDE1380"; break; + case XTDE1390: result = "XTDE1390"; break; + case XTDE1400: result = "XTDE1400"; break; + case XTDE1420: result = "XTDE1420"; break; + case XTDE1425: result = "XTDE1425"; break; + case XTDE1428: result = "XTDE1428"; break; + case XTDE1440: result = "XTDE1440"; break; + case XTDE1450: result = "XTDE1450"; break; + case XTDE1460: result = "XTDE1460"; break; + case XTDE1480: result = "XTDE1480"; break; + case XTDE1490: result = "XTDE1490"; break; + case XTDE1665: result = "XTDE1665"; break; + case XTMM9000: result = "XTMM9000"; break; + case XTRE0270: result = "XTRE0270"; break; + case XTRE0540: result = "XTRE0540"; break; + case XTRE0795: result = "XTRE0795"; break; + case XTRE1160: result = "XTRE1160"; break; + case XTRE1495: result = "XTRE1495"; break; + case XTRE1500: result = "XTRE1500"; break; + case XTRE1620: result = "XTRE1620"; break; + case XTRE1630: result = "XTRE1630"; break; + case XTSE0010: result = "XTSE0010"; break; + case XTSE0020: result = "XTSE0020"; break; + case XTSE0080: result = "XTSE0080"; break; + case XTSE0090: result = "XTSE0090"; break; + case XTSE0110: result = "XTSE0110"; break; + case XTSE0120: result = "XTSE0120"; break; + case XTSE0125: result = "XTSE0125"; break; + case XTSE0130: result = "XTSE0130"; break; + case XTSE0150: result = "XTSE0150"; break; + case XTSE0165: result = "XTSE0165"; break; + case XTSE0170: result = "XTSE0170"; break; + case XTSE0180: result = "XTSE0180"; break; + case XTSE0190: result = "XTSE0190"; break; + case XTSE0200: result = "XTSE0200"; break; + case XTSE0210: result = "XTSE0210"; break; + case XTSE0215: result = "XTSE0215"; break; + case XTSE0220: result = "XTSE0220"; break; + case XTSE0260: result = "XTSE0260"; break; + case XTSE0265: result = "XTSE0265"; break; + case XTSE0280: result = "XTSE0280"; break; + case XTSE0340: result = "XTSE0340"; break; + case XTSE0350: result = "XTSE0350"; break; + case XTSE0370: result = "XTSE0370"; break; + case XTSE0500: result = "XTSE0500"; break; + case XTSE0530: result = "XTSE0530"; break; + case XTSE0550: result = "XTSE0550"; break; + case XTSE0580: result = "XTSE0580"; break; + case XTSE0620: result = "XTSE0620"; break; + case XTSE0630: result = "XTSE0630"; break; + case XTSE0650: result = "XTSE0650"; break; + case XTSE0660: result = "XTSE0660"; break; + case XTSE0670: result = "XTSE0670"; break; + case XTSE0680: result = "XTSE0680"; break; + case XTSE0690: result = "XTSE0690"; break; + case XTSE0710: result = "XTSE0710"; break; + case XTSE0720: result = "XTSE0720"; break; + case XTSE0740: result = "XTSE0740"; break; + case XTSE0760: result = "XTSE0760"; break; + case XTSE0770: result = "XTSE0770"; break; + case XTSE0805: result = "XTSE0805"; break; + case XTSE0808: result = "XTSE0808"; break; + case XTSE0809: result = "XTSE0809"; break; + case XTSE0810: result = "XTSE0810"; break; + case XTSE0812: result = "XTSE0812"; break; + case XTSE0840: result = "XTSE0840"; break; + case XTSE0870: result = "XTSE0870"; break; + case XTSE0880: result = "XTSE0880"; break; + case XTSE0910: result = "XTSE0910"; break; + case XTSE0940: result = "XTSE0940"; break; + case XTSE0975: result = "XTSE0975"; break; + case XTSE1015: result = "XTSE1015"; break; + case XTSE1017: result = "XTSE1017"; break; + case XTSE1040: result = "XTSE1040"; break; + case XTSE1060: result = "XTSE1060"; break; + case XTSE1070: result = "XTSE1070"; break; + case XTSE1080: result = "XTSE1080"; break; + case XTSE1090: result = "XTSE1090"; break; + case XTSE1130: result = "XTSE1130"; break; + case XTSE1205: result = "XTSE1205"; break; + case XTSE1210: result = "XTSE1210"; break; + case XTSE1220: result = "XTSE1220"; break; + case XTSE1290: result = "XTSE1290"; break; + case XTSE1295: result = "XTSE1295"; break; + case XTSE1300: result = "XTSE1300"; break; + case XTSE1430: result = "XTSE1430"; break; + case XTSE1505: result = "XTSE1505"; break; + case XTSE1520: result = "XTSE1520"; break; + case XTSE1530: result = "XTSE1530"; break; + case XTSE1560: result = "XTSE1560"; break; + case XTSE1570: result = "XTSE1570"; break; + case XTSE1580: result = "XTSE1580"; break; + case XTSE1590: result = "XTSE1590"; break; + case XTSE1600: result = "XTSE1600"; break; + case XTSE1650: result = "XTSE1650"; break; + case XTSE1660: result = "XTSE1660"; break; + case XTTE0505: result = "XTTE0505"; break; + case XTTE0510: result = "XTTE0510"; break; + case XTTE0520: result = "XTTE0520"; break; + case XTTE0570: result = "XTTE0570"; break; + case XTTE0590: result = "XTTE0590"; break; + case XTTE0600: result = "XTTE0600"; break; + case XTTE0780: result = "XTTE0780"; break; + case XTTE0790: result = "XTTE0790"; break; + case XTTE0950: result = "XTTE0950"; break; + case XTTE0990: result = "XTTE0990"; break; + case XTTE1000: result = "XTTE1000"; break; + case XTTE1020: result = "XTTE1020"; break; + case XTTE1100: result = "XTTE1100"; break; + case XTTE1120: result = "XTTE1120"; break; + case XTTE1510: result = "XTTE1510"; break; + case XTTE1512: result = "XTTE1512"; break; + case XTTE1515: result = "XTTE1515"; break; + case XTTE1540: result = "XTTE1540"; break; + case XTTE1545: result = "XTTE1545"; break; + case XTTE1550: result = "XTTE1550"; break; + case XTTE1555: result = "XTTE1555"; break; + case XSDError: result = "XSDError"; break; + } + + Q_ASSERT_X(result, Q_FUNC_INFO, "Unknown enum value."); + return QLatin1String(result); +} + +QUrl ReportContext::resolveURI(const QUrl &relative, + const QUrl &baseURI) const +{ + Q_ASSERT_X(!baseURI.isRelative(), Q_FUNC_INFO, + "The base URI passed from the engine wasn't absolute."); + + const QAbstractUriResolver *const resolver(uriResolver()); + + if(resolver) + { + const QUrl final(resolver->resolve(relative, baseURI)); + Q_ASSERT_X(final.isValid() || final.isEmpty(), Q_FUNC_INFO, + "The QAbstractUriResolver must return a valid URI."); + Q_ASSERT_X(!final.isRelative(), Q_FUNC_INFO, + "The QAbstractUriResolver must return an absolute URI."); + return final; + } + else + return baseURI.resolved(relative); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/environment/qreportcontext_p.h b/src/xmlpatterns/environment/qreportcontext_p.h new file mode 100644 index 0000000..067c1d3 --- /dev/null +++ b/src/xmlpatterns/environment/qreportcontext_p.h @@ -0,0 +1,2464 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ReportContext_H +#define Patternist_ReportContext_H + +#include +#include +#include + +#include "qnamepool_p.h" +#include "qxmlname.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QAbstractMessageHandler; +class QSourceLocation; +class QString; + +namespace QPatternist +{ + class SourceLocationReflection; + + /** + * @short A callback for reporting errors. + * + * ReportContext receives messages of various severity and type via its + * functions warning() and error(). In turn, ReportContext create Message instances + * and submit them to the QAbstractMessageHandler instance returned by messageHandler(). + * + * The Message attributes are set as follows: + * + * - Message::description() - A translated, human-readable description + * - Message::type() - Message::Error if a static, dynamic or type error was encountered + * that halted compilation or evaluation, or Message::Warning in case of a warning + * - Message::identifier() - This is a URI consisting of the error namespace with the + * error code as fragment. For example, a Message representing a syntax error + * would return the type "http://www.w3.org/2005/xqt-errors#XPST0003". The convenience + * function codeFromURI() can be used to extract the error code. The error namespace + * is typically the namespace for XPath and XQuery errors(as in the previous example), but + * can also be user defined. + * + * @see XML Path Language + * (XPath) 2.0, 2.3.2 Identifying and Reporting Errors + * @see XQuery 1.0 and + * XPath 2.0 Functions and Operators, 3 The Error Function + * @author Frans Englich + * @warning This file is auto-generated from extractErrorCodes.xsl. Any + * modifications done to this file are lost. + */ + class Q_AUTOTEST_EXPORT ReportContext : public QSharedData + { + public: + typedef QHash LocationHash; + + /** + * A smart pointer wrapping ReportContext instances. + */ + typedef QExplicitlySharedDataPointer Ptr; + + /** + * @short Default constructors. + * + * For some reason GCC fails to synthesize it, so we provide an empty + * one here. + */ + inline ReportContext() {} + + virtual ~ReportContext(); + + /** + * Error codes that corresponds to the error codes defined in the + * relevant specifications. They are used throughout the API for + * identifying error conditions. + * + * While strings could have been used for identifying errors, enums + * reduces bugs by providing type safety. + * + * @see XML + * Path Language (XPath) 2.0, 2.3 Error Handling + * @see XQuery 1.0 + * and XPath 2.0 Functions and Operators, C Error Summary + * @see XSL Transformations + * (XSLT) Version 2.0, E Summary of Error Conditions (Non-Normative) + * @note The enumerator values' Doxygen documentation is copied from the + * W3C documents + * XQuery 1.0 and XPath + * 2.0 Functions and Operators, + * XML Path Language (XPath) 2.0, and + * XSL Transformations (XSLT) + * Version 2.0, respectively. The doxygen documentation is therefore covered + * by the following legal notice: + * "Copyright @ 2005 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C + * liability, + * trademark and + * document + * use rules apply." + * @warning This enumerator is auto-generated from the relevant specifications + * by the XSL-T stylesheet extractErrorCodes.xsl. Hence, any modifications + * done to this file, in contrary to the stylesheet, are therefore lost. + */ + enum ErrorCode + { + /** + * XML Schema error code. + */ + XSDError, + + /** + * It is a static error if analysis of an expression relies on some + * component of the static context that has not been assigned a + * value. + */ + XPST0001, + + /** + * It is a dynamic error if evaluation of an expression relies on + * some part of the dynamic context that has not been assigned a + * value. + */ + XPDY0002, + + /** + * It is a static error if an expression is not a valid instance + * of the grammar defined in A.1 EBNF. + */ + XPST0003, + + /** + * It is a type error if, during the static analysis phase, an expression + * is found to have a static type that is not appropriate for the + * context in which the expression occurs, or during the dynamic + * evaluation phase, the dynamic type of a value does not match + * a required type as specified by the matching rules in 2.5.4 SequenceType + * Matching. + */ + XPTY0004, + + /** + * During the analysis phase, it is a static error if the static + * type assigned to an expression other than the expression () or + * data(()) is empty-sequence(). + */ + XPST0005, + + /** + * (Not currently used.) + */ + XPTY0006, + + /** + * (Not currently used.) + */ + XPTY0007, + + /** + * It is a static error if an expression refers to an element name, + * attribute name, schema type name, namespace prefix, or variable + * name that is not defined in the static context, except for an + * ElementName in an ElementTest or an AttributeName in an AttributeTest. + */ + XPST0008, + + /** + * An implementation that does not support the Schema Import Feature + * must raise a static error if a Prolog contains a schema import. + */ + XQST0009, + + /** + * An implementation must raise a static error if it encounters + * a reference to an axis that it does not support. + */ + XPST0010, + + /** + * It is a static error if the set of definitions contained in all + * schemas imported by a Prolog do not satisfy the conditions for + * schema validity specified in Sections 3 and 5 of [XML Schema] + * Part 1--i.e., each definition must be valid, complete, and unique. + */ + XQST0012, + + /** + * It is a static error if an implementation recognizes a pragma + * but determines that its content is invalid. + */ + XQST0013, + + /** + * (Not currently used.) + */ + XQST0014, + + /** + * (Not currently used.) + */ + XQST0015, + + /** + * An implementation that does not support the Module Feature raises + * a static error if it encounters a module declaration or a module + * import. + */ + XQST0016, + + /** + * It is a static error if the expanded QName and number of arguments + * in a function call do not match the name and arity of a function + * signature in the static context. + */ + XPST0017, + + /** + * It is a type error if the result of the last step in a path expression + * contains both nodes and atomic values. + */ + XPTY0018, + + /** + * It is a type error if the result of a step (other than the last + * step) in a path expression contains an atomic value. + */ + XPTY0019, + + /** + * It is a type error if, in an axis step, the context item is not + * a node. + */ + XPTY0020, + + /** + * (Not currently used.) + */ + XPDY0021, + + /** + * It is a static error if the value of a namespace declaration + * attribute is not a URILiteral. + */ + XQST0022, + + /** + * (Not currently used.) + */ + XQTY0023, + + /** + * It is a type error if the content sequence in an element constructor + * contains an attribute node following a node that is not an attribute + * node. + */ + XQTY0024, + + /** + * It is a dynamic error if any attribute of a constructed element + * does not have a name that is distinct from the names of all other + * attributes of the constructed element. + */ + XQDY0025, + + /** + * It is a dynamic error if the result of the content expression + * of a computed processing instruction constructor contains the + * string "?>". + */ + XQDY0026, + + /** + * In a validate expression, it is a dynamic error if the root element + * information item in the PSVI resulting from validation does not + * have the expected validity property: valid if validation mode + * is strict, or either valid or notKnown if validation mode is + * lax. + */ + XQDY0027, + + /** + * (Not currently used.) + */ + XQTY0028, + + /** + * (Not currently used.) + */ + XQDY0029, + + /** + * It is a type error if the argument of a validate expression does + * not evaluate to exactly one document or element node. + */ + XQTY0030, + + /** + * It is a static error if the version number specified in a version + * declaration is not supported by the implementation. + */ + XQST0031, + + /** + * A static error is raised if a Prolog contains more than one base + * URI declaration. + */ + XQST0032, + + /** + * It is a static error if a module contains multiple bindings for + * the same namespace prefix. + */ + XQST0033, + + /** + * It is a static error if multiple functions declared or imported + * by a module have the number of arguments and their expanded QNames + * are equal (as defined by the eq operator). + */ + XQST0034, + + /** + * It is a static error to import two schema components that both + * define the same name in the same symbol space and in the same + * scope. + */ + XQST0035, + + /** + * It is a static error to import a module if the importing module's + * in-scope schema types do not include definitions for the schema + * type names that appear in the declarations of variables and functions + * (whether in an argument type or return type) that are present + * in the imported module and are referenced in the importing module. + */ + XQST0036, + + /** + * (Not currently used.) + */ + XQST0037, + + /** + * It is a static error if a Prolog contains more than one default + * collation declaration, or the value specified by a default collation + * declaration is not present in statically known collations. + */ + XQST0038, + + /** + * It is a static error for a function declaration to have more + * than one parameter with the same name. + */ + XQST0039, + + /** + * It is a static error if the attributes specified by a direct + * element constructor do not have distinct expanded QNames. + */ + XQST0040, + + /** + * It is a dynamic error if the value of the name expression in + * a computed processing instruction constructor cannot be cast + * to the type xs:NCName. + */ + XQDY0041, + + /** + * (Not currently used.) + */ + XQST0042, + + /** + * (Not currently used.) + */ + XQST0043, + + /** + * It is a dynamic error if the node-name property of the node constructed + * by a computed attribute constructor is in the namespace http://www.w3.org/2000/xmlns/ + * (corresponding to namespace prefix xmlns), or is in no namespace + * and has local name xmlns. + */ + XQDY0044, + + /** + * It is a static error if the function name in a function declaration + * is in one of the following namespaces: http://www.w3.org/XML/1998/namespace, + * http://www.w3.org/2001/XMLSchema, http://www.w3.org/2001/XMLSchema-instance, + * http://www.w3.org/2005/xpath-functions. + */ + XQST0045, + + /** + * An implementation MAY raise a static error if the value of a + * URILiteral is of nonzero length and is not in the lexical space + * of xs:anyURI. + */ + XQST0046, + + /** + * It is a static error if multiple module imports in the same Prolog + * specify the same target namespace. + */ + XQST0047, + + /** + * It is a static error if a function or variable declared in a + * library module is not in the target namespace of the library + * module. + */ + XQST0048, + + /** + * It is a static error if two or more variables declared or imported + * by a module have equal expanded QNames (as defined by the eq + * operator.) + */ + XQST0049, + + /** + * It is a dynamic error if the dynamic type of the operand of a + * treat expression does not match the sequence type specified by + * the treat expression. This error might also be raised by a path + * expression beginning with "/" or "//" if the context node is + * not in a tree that is rooted at a document node. This is because + * a leading "/" or "//" in a path expression is an abbreviation + * for an initial step that includes the clause treat as document-node(). + */ + XPDY0050, + + /** + * It is a static error if a QName that is used as an AtomicType + * in a SequenceType is not defined in the in-scope schema types + * as an atomic type. + */ + XPST0051, + + /** + * (Not currently used.) + */ + XQDY0052, + + /** + * (Not currently used.) + */ + XQST0053, + + /** + * It is a static error if a variable depends on itself. + */ + XQST0054, + + /** + * It is a static error if a Prolog contains more than one copy-namespaces + * declaration. + */ + XQST0055, + + /** + * (Not currently used.) + */ + XQST0056, + + /** + * It is a static error if a schema import binds a namespace prefix + * but does not specify a target namespace other than a zero-length + * string. + */ + XQST0057, + + /** + * It is a static error if multiple schema imports specify the same + * target namespace. + */ + XQST0058, + + /** + * It is a static error if an implementation is unable to process + * a schema or module import by finding a schema or module with + * the specified target namespace. + */ + XQST0059, + + /** + * It is a static error if the name of a function in a function + * declaration is not in a namespace (expanded QName has a null + * namespace URI). + */ + XQST0060, + + /** + * It is a dynamic error if the operand of a validate expression + * is a document node whose children do not consist of exactly one + * element node and zero or more comment and processing instruction + * nodes, in any order. + */ + XQDY0061, + + /** + * (Not currently used.) + */ + XQDY0062, + + /** + * (Not currently used.) + */ + XQST0063, + + /** + * It is a dynamic error if the value of the name expression in + * a computed processing instruction constructor is equal to "XML" + * (in any combination of upper and lower case). + */ + XQDY0064, + + /** + * A static error is raised if a Prolog contains more than one ordering + * mode declaration. + */ + XQST0065, + + /** + * A static error is raised if a Prolog contains more than one default + * element/type namespace declaration, or more than one default + * function namespace declaration. + */ + XQST0066, + + /** + * A static error is raised if a Prolog contains more than one construction + * declaration. + */ + XQST0067, + + /** + * A static error is raised if a Prolog contains more than one boundary-space + * declaration. + */ + XQST0068, + + /** + * A static error is raised if a Prolog contains more than one empty + * order declaration. + */ + XQST0069, + + /** + * A static error is raised if a namespace URI is bound to the predefined + * prefix xmlns, or if a namespace URI other than http://www.w3.org/XML/1998/namespace + * is bound to the prefix xml, or if the prefix xml is bound to + * a namespace URI other than http://www.w3.org/XML/1998/namespace. + */ + XQST0070, + + /** + * A static error is raised if the namespace declaration attributes + * of a direct element constructor do not have distinct names. + */ + XQST0071, + + /** + * It is a dynamic error if the result of the content expression + * of a computed comment constructor contains two adjacent hyphens + * or ends with a hyphen. + */ + XQDY0072, + + /** + * It is a static error if the graph of module imports contains + * a cycle (that is, if there exists a sequence of modules M1 ... + * Mn such that each Mi imports Mi+1 and Mn imports M1), unless + * all the modules in the cycle share a common namespace. + */ + XQST0073, + + /** + * It is a dynamic error if the value of the name expression in + * a computed element or attribute constructor cannot be converted + * to an expanded QName (for example, because it contains a namespace + * prefix not found in statically known namespaces.) + */ + XQDY0074, + + /** + * An implementation that does not support the Validation Feature + * must raise a static error if it encounters a validate expression. + */ + XQST0075, + + /** + * It is a static error if a collation subclause in an order by + * clause of a FLWOR expression does not identify a collation that + * is present in statically known collations. + */ + XQST0076, + + /** + * (Not currently used.) + */ + XQST0077, + + /** + * (Not currently used.) + */ + XQST0078, + + /** + * It is a static error if an extension expression contains neither + * a pragma that is recognized by the implementation nor an expression + * enclosed in curly braces. + */ + XQST0079, + + /** + * It is a static error if the target type of a cast or castable + * expression is xs:NOTATION or xs:anyAtomicType. + */ + XPST0080, + + /** + * It is a static error if a QName used in a query contains a namespace + * prefix that cannot be expanded into a namespace URI by using + * the statically known namespaces. + */ + XPST0081, + + /** + * (Not currently used.) + */ + XQST0082, + + /** + * (Not currently used.) + */ + XPST0083, + + /** + * It is a dynamic error if the element validated by a validate + * statement does not have a top-level element declaration in the + * in-scope element declarations, if validation mode is strict. + */ + XQDY0084, + + /** + * It is a static error if the namespace URI in a namespace declaration + * attribute is a zero-length string, and the implementation does + * not support [XML Names 1.1]. + */ + XQST0085, + + /** + * It is a type error if the typed value of a copied element or + * attribute node is namespace-sensitive when construction mode + * is preserve and copy-namespaces mode is no-preserve. + */ + XQTY0086, + + /** + * It is a static error if the encoding specified in a Version Declaration + * does not conform to the definition of EncName specified in [XML + * 1.0]. + */ + XQST0087, + + /** + * It is a static error if the literal that specifies the target + * namespace in a module import or a module declaration is of zero + * length. + */ + XQST0088, + + /** + * It is a static error if a variable bound in a for clause of a + * FLWOR expression, and its associated positional variable, do + * not have distinct names (expanded QNames). + */ + XQST0089, + + /** + * It is a static error if a character reference does not identify + * a valid character in the version of XML that is in use. + */ + XQST0090, + + /** + * An implementation MAY raise a dynamic error if an xml:id error, + * as defined in [XML ID], is encountered during construction of + * an attribute named xml:id. + */ + XQDY0091, + + /** + * An implementation MAY raise a dynamic error if a constructed + * attribute named xml:space has a value other than preserve or + * default. + */ + XQDY0092, + + /** + * It is a static error to import a module M1 if there exists a + * sequence of modules M1 ... Mi ... M1 such that each module directly + * depends on the next module in the sequence (informally, if M1 + * depends on itself through some chain of module dependencies.) + */ + XQST0093, + + /** + * Unidentified error. + */ + FOER0000, + + /** + * Division by zero. + */ + FOAR0001, + + /** + * Numeric operation overflow/underflow. + */ + FOAR0002, + + /** + * Input value too large for decimal. + */ + FOCA0001, + + /** + * Invalid lexical value. + */ + FOCA0002, + + /** + * Input value too large for integer. + */ + FOCA0003, + + /** + * NaN supplied as float/double value. + */ + FOCA0005, + + /** + * String to be cast to decimal has too many digits of precision. + */ + FOCA0006, + + /** + * Code point not valid. + */ + FOCH0001, + + /** + * Unsupported collation. + */ + FOCH0002, + + /** + * Unsupported normalization form. + */ + FOCH0003, + + /** + * Collation does not support collation units. + */ + FOCH0004, + + /** + * No context document. + */ + FODC0001, + + /** + * Error retrieving resource. + */ + FODC0002, + + /** + * Function stability not defined. + */ + FODC0003, + + /** + * Invalid argument to fn:collection. + */ + FODC0004, + + /** + * Invalid argument to fn:doc or fn:doc-available. + */ + FODC0005, + + /** + * Overflow/underflow in date/time operation. + */ + FODT0001, + + /** + * Overflow/underflow in duration operation. + */ + FODT0002, + + /** + * Invalid timezone value. + */ + FODT0003, + + /** + * No namespace found for prefix. + */ + FONS0004, + + /** + * Base-uri not defined in the static context. + */ + FONS0005, + + /** + * Invalid value for cast/constructor. + */ + FORG0001, + + /** + * Invalid argument to fn:resolve-uri(). + */ + FORG0002, + + /** + * fn:zero-or-one called with a sequence containing more than one + * item. + */ + FORG0003, + + /** + * fn:one-or-more called with a sequence containing no items. + */ + FORG0004, + + /** + * fn:exactly-one called with a sequence containing zero or more + * than one item. + */ + FORG0005, + + /** + * Invalid argument type. + */ + FORG0006, + + /** + * Both arguments to fn:dateTime have a specified timezone. + */ + FORG0008, + + /** + * Error in resolving a relative URI against a base URI in fn:resolve-uri. + */ + FORG0009, + + /** + * Invalid regular expression. flags + */ + FORX0001, + + /** + * Invalid regular expression. + */ + FORX0002, + + /** + * Regular expression matches zero-length string. + */ + FORX0003, + + /** + * Invalid replacement string. + */ + FORX0004, + + /** + * Argument node does not have a typed value. + */ + FOTY0012, + + /** + * It is an error if an item in S6 in sequence normalization is + * an attribute node or a namespace node. + */ + SENR0001, + + /** + * It is an error if the serializer is unable to satisfy the rules + * for either a well-formed XML document entity or a well-formed + * XML external general parsed entity, or both, except for content + * modified by the character expansion phase of serialization. + */ + SERE0003, + + /** + * It is an error to specify the doctype-system parameter, or to + * specify the standalone parameter with a value other than omit, + * if the instance of the data model contains text nodes or multiple + * element nodes as children of the root node. + */ + SEPM0004, + + /** + * It is an error if the serialized result would contain an NCName + * Names that contains a character that is not permitted by the + * version of Namespaces in XML specified by the version parameter. + */ + SERE0005, + + /** + * It is an error if the serialized result would contain a character + * that is not permitted by the version of XML specified by the + * version parameter. + */ + SERE0006, + + /** + * It is an error if an output encoding other than UTF-8 or UTF-16 + * is requested and the serializer does not support that encoding. + */ + SESU0007, + + /** + * It is an error if a character that cannot be represented in the + * encoding that the serializer is using for output appears in a + * context where character references are not allowed (for example + * if the character occurs in the name of an element). + */ + SERE0008, + + /** + * It is an error if the omit-xml-declaration parameter has the + * value yes, and the standalone attribute has a value other than + * omit; or the version parameter has a value other than 1.0 and + * the doctype-system parameter is specified. + */ + SEPM0009, + + /** + * It is an error if the output method is xml, the value of the + * undeclare-prefixes parameter is yes, and the value of the version + * parameter is 1.0. + */ + SEPM0010, + + /** + * It is an error if the value of the normalization-form parameter + * specifies a normalization form that is not supported by the serializer. + */ + SESU0011, + + /** + * It is an error if the value of the normalization-form parameter + * is fully-normalized and any relevant construct of the result + * begins with a combining character. + */ + SERE0012, + + /** + * It is an error if the serializer does not support the version + * of XML or HTML specified by the version parameter. + */ + SESU0013, + + /** + * It is an error to use the HTML output method when characters + * which are legal in XML but not in HTML, specifically the control + * characters \#x7F-#x9F, appear in the instance of the data model. + */ + SERE0014, + + /** + * It is an error to use the HTML output method when > appears within + * a processing instruction in the data model instance being serialized. + */ + SERE0015, + + /** + * It is a an error if a parameter value is invalid for the defined + * domain. + */ + SEPM0016, + + /** + * A static error is signaled if an XSLT-defined element is used + * in a context where it is not permitted, if a required attribute + * is omitted, or if the content of the element does not correspond + * to the content that is allowed for the element. + */ + XTSE0010, + + /** + * It is a static error if an attribute (other than an attribute + * written using curly brackets in a position where an attribute + * value template is permitted) contains a value that is not one + * of the permitted values for that attribute. + */ + XTSE0020, + + /** + * It is a static error to use a reserved namespace in the name + * of a named template, a mode, an attribute set, a key, a decimal-format, + * a variable or parameter, a stylesheet function, a named output + * definition, or a character map. + */ + XTSE0080, + + /** + * It is a static error for an element from the XSLT namespace to + * have an attribute whose namespace is either null (that is, an + * attribute with an unprefixed name) or the XSLT namespace, other + * than attributes defined for the element in this document. + */ + XTSE0090, + + /** + * The value of the version attribute must be a number: specifically, + * it must be a a valid instance of the type xs:decimal as defined + * in [XML Schema Part 2]. + */ + XTSE0110, + + /** + * An xsl:stylesheet element must not have any text node children. + */ + XTSE0120, + + /** + * It is a static error if the value of an [xsl:]default-collation + * attribute, after resolving against the base URI, contains no + * URI that the implementation recognizes as a collation URI. + */ + XTSE0125, + + /** + * It is a static error if the xsl:stylesheet element has a child + * element whose name has a null namespace URI. + */ + XTSE0130, + + /** + * A literal result element that is used as the outermost element + * of a simplified stylesheet module must have an xsl:version attribute. + */ + XTSE0150, + + /** + * It is a static error if the processor is not able to retrieve + * the resource identified by the URI reference [ in the href attribute + * of xsl:include or xsl:import] , or if the resource that is retrieved + * does not contain a stylesheet module conforming to this specification. + */ + XTSE0165, + + /** + * An xsl:include element must be a top-level element. + */ + XTSE0170, + + /** + * It is a static error if a stylesheet module directly or indirectly + * includes itself. + */ + XTSE0180, + + /** + * An xsl:import element must be a top-level element. + */ + XTSE0190, + + /** + * The xsl:import element children must precede all other element + * children of an xsl:stylesheet element, including any xsl:include + * element children and any user-defined data elements. + */ + XTSE0200, + + /** + * It is a static error if a stylesheet module directly or indirectly + * imports itself. + */ + XTSE0210, + + /** + * It is a static error if an xsl:import-schema element that contains + * an xs:schema element has a schema-location attribute, or if it + * has a namespace attribute that conflicts with the target namespace + * of the contained schema. + */ + XTSE0215, + + /** + * It is a static error if the synthetic schema document does not + * satisfy the constraints described in [XML Schema Part 1] (section + * 5.1, Errors in Schema Construction and Structure). This includes, + * without loss of generality, conflicts such as multiple definitions + * of the same name. + */ + XTSE0220, + + /** + * Within an XSLT element that is required to be empty, any content + * other than comments or processing instructions, including any + * whitespace text node preserved using the xml:space="preserve" + * attribute, is a static error. + */ + XTSE0260, + + /** + * It is a static error if there is a stylesheet module in the stylesheet + * that specifies input-type-annotations="strip" and another stylesheet + * module that specifies input-type-annotations="preserve". + */ + XTSE0265, + + /** + * In the case of a prefixed QName used as the value of an attribute + * in the stylesheet, or appearing within an XPath expression in + * the stylesheet, it is a static error if the defining element + * has no namespace node whose name matches the prefix of the QName. + */ + XTSE0280, + + /** + * Where an attribute is defined to contain a pattern, it is a static + * error if the pattern does not match the production Pattern. + */ + XTSE0340, + + /** + * It is a static error if an unescaped left curly bracket appears + * in a fixed part of an attribute value template without a matching + * right curly bracket. + */ + XTSE0350, + + /** + * It is a static error if an unescaped right curly bracket occurs + * in a fixed part of an attribute value template. + */ + XTSE0370, + + /** + * An xsl:template element must have either a match attribute or + * a name attribute, or both. An xsl:template element that has no + * match attribute must have no mode attribute and no priority attribute. + */ + XTSE0500, + + /** + * The value of this attribute [the priority attribute of the xsl:template + * element] must conform to the rules for the xs:decimal type defined + * in [XML Schema Part 2]. Negative values are permitted.. + */ + XTSE0530, + + /** + * It is a static error if the list [of modes in the mode attribute + * of xsl:template] is empty, if the same token is included more + * than once in the list, if the list contains an invalid token, + * or if the token \#all appears together with any other value. + */ + XTSE0550, + + /** + * It is a static error if two parameters of a template or of a + * stylesheet function have the same name. + */ + XTSE0580, + + /** + * It is a static error if a variable-binding element has a select + * attribute and has non-empty content. + */ + XTSE0620, + + /** + * It is a static error if a stylesheet contains more than one binding + * of a global variable with the same name and same import precedence, + * unless it also contains another binding with the same name and + * higher import precedence. + */ + XTSE0630, + + /** + * It is a static error if a stylesheet contains an xsl:call-template + * instruction whose name attribute does not match the name attribute + * of any xsl:template in the stylesheet. + */ + XTSE0650, + + /** + * It is a static error if a stylesheet contains more than one template + * with the same name and the same import precedence, unless it + * also contains a template with the same name and higher import + * precedence. + */ + XTSE0660, + + /** + * It is a static error if a single xsl:call-template, xsl:apply-templates, + * xsl:apply-imports, or xsl:next-match element contains two or + * more xsl:with-param elements with matching name attributes. + */ + XTSE0670, + + /** + * In the case of xsl:call-template, it is a static error to pass + * a non-tunnel parameter named x to a template that does not have + * a template parameter named x, unless backwards compatible behavior + * is enabled for the xsl:call-template instruction. + */ + XTSE0680, + + /** + * It is a static error if a template that is invoked using xsl:call-template + * declares a template parameter specifying required="yes" and not + * specifying tunnel="yes", if no value for this parameter is supplied + * by the calling instruction. + */ + XTSE0690, + + /** + * It is a static error if the value of the use-attribute-sets attribute + * of an xsl:copy, xsl:element, or xsl:attribute-set element, or + * the xsl:use-attribute-sets attribute of a literal result element, + * is not a whitespace-separated sequence of QNames, or if it contains + * a QName that does not match the name attribute of any xsl:attribute-set + * declaration in the stylesheet. + */ + XTSE0710, + + /** + * It is a static error if an xsl:attribute-set element directly + * or indirectly references itself via the names contained in the + * use-attribute-sets attribute. + */ + XTSE0720, + + /** + * A stylesheet function must have a prefixed name, to remove any + * risk of a clash with a function in the default function namespace. + * It is a static error if the name has no prefix. + */ + XTSE0740, + + /** + * Because arguments to a stylesheet function call must all be specified, + * the xsl:param elements within an xsl:function element must not + * specify a default value: this means they must be empty, and must + * not have a select attribute. + */ + XTSE0760, + + /** + * It is a static error for a stylesheet to contain two or more + * functions with the same expanded-QName, the same arity, and the + * same import precedence, unless there is another function with + * the same expanded-QName and arity, and a higher import precedence. + */ + XTSE0770, + + /** + * It is a static error if an attribute on a literal result element + * is in the XSLT namespace, unless it is one of the attributes + * explicitly defined in this specification. + */ + XTSE0805, + + /** + * It is a static error if a namespace prefix is used within the + * [xsl:]exclude-result-prefixes attribute and there is no namespace + * binding in scope for that prefix. + */ + XTSE0808, + + /** + * It is a static error if the value \#default is used within the + * [xsl:]exclude-result-prefixes attribute and the parent element + * of the [xsl:]exclude-result-prefixes attribute has no default + * namespace. + */ + XTSE0809, + + /** + * It is a static error if there is more than one such declaration + * [more than one xsl:namespace-alias declaration] with the same + * literal namespace URI and the same import precedence and different + * values for the target namespace URI, unless there is also an + * xsl:namespace-alias declaration with the same literal namespace + * URI and a higher import precedence. + */ + XTSE0810, + + /** + * It is a static error if a value other than \#default is specified + * for either the stylesheet-prefix or the result-prefix attributes + * of the xsl:namespace-alias element when there is no in-scope + * binding for that namespace prefix. + */ + XTSE0812, + + /** + * It is a static error if the select attribute of the xsl:attribute + * element is present unless the element has empty content. + */ + XTSE0840, + + /** + * It is a static error if the select attribute of the xsl:value-of + * element is present when the content of the element is non-empty, + * or if the select attribute is absent when the content is empty. + */ + XTSE0870, + + /** + * It is a static error if the select attribute of the xsl:processing-instruction + * element is present unless the element has empty content. + */ + XTSE0880, + + /** + * It is a static error if the select attribute of the xsl:namespace + * element is present when the element has content other than one + * or more xsl:fallback instructions, or if the select attribute + * is absent when the element has empty content. + */ + XTSE0910, + + /** + * It is a static error if the select attribute of the xsl:comment + * element is present unless the element has empty content. + */ + XTSE0940, + + /** + * It is a type error to use the xsl:copy or xsl:copy-of instruction + * to copy a node that has namespace-sensitive content if the copy-namespaces + * attribute has the value no and its explicit or implicit validation + * attribute has the value preserve. It is also a type error if + * either of these instructions (with validation="preserve") is + * used to copy an attribute having namespace-sensitive content, + * unless the parent element is also copied. A node has namespace-sensitive + * content if its typed value contains an item of type xs:QName + * or xs:NOTATION or a type derived therefrom. The reason this is + * an error is because the validity of the content depends on the + * namespace context being preserved. + */ + XTTE0950, + + /** + * It is a static error if the value attribute of xsl:number is + * present unless the select, level, count, and from attributes + * are all absent. + */ + XTSE0975, + + /** + * It is a static error if an xsl:sort element with a select attribute + * has non-empty content. + */ + XTSE1015, + + /** + * It is a static error if an xsl:sort element other than the first + * in a sequence of sibling xsl:sort elements has a stable attribute. + */ + XTSE1017, + + /** + * It is a static error if an xsl:perform-sort instruction with + * a select attribute has any content other than xsl:sort and xsl:fallback + * instructions. + */ + XTSE1040, + + /** + * It is a static error if the current-group function is used within + * a pattern. + */ + XTSE1060, + + /** + * It is a static error if the current-grouping-key function is + * used within a pattern. + */ + XTSE1070, + + /** + * These four attributes [the group-by, group-adjacent, group-starting-with, + * and group-ending-with attributes of xsl:for-each-group ] are + * mutually exclusive: it is a static error if none of these four + * attributes is present, or if more than one of them is present. + */ + XTSE1080, + + /** + * It is an error to specify the collation attribute if neither + * the group-by attribute nor group-adjacent attribute is specified. + */ + XTSE1090, + + /** + * It is a static error if the xsl:analyze-string instruction contains + * neither an xsl:matching-substring nor an xsl:non-matching-substring + * element. + */ + XTSE1130, + + /** + * It is a static error if an xsl:key declaration has a use attribute + * and has non-empty content, or if it has empty content and no + * use attribute. + */ + XTSE1205, + + /** + * It is a static error if the xsl:key declaration has a collation + * attribute whose value (after resolving against the base URI) + * is not a URI recognized by the implementation as referring to + * a collation. + */ + XTSE1210, + + /** + * It is a static error if there are several xsl:key declarations + * in the stylesheet with the same key name and different effective + * collations. Two collations are the same if their URIs are equal + * under the rules for comparing xs:anyURI values, or if the implementation + * can determine that they are different URIs referring to the same + * collation. + */ + XTSE1220, + + /** + * It is a static error if a named or unnamed decimal format contains + * two conflicting values for the same attribute in different xsl:decimal-format + * declarations having the same import precedence, unless there + * is another definition of the same attribute with higher import + * precedence. + */ + XTSE1290, + + /** + * It is a static error if the character specified in the zero-digit + * attribute is not a digit or is a digit that does not have the + * numeric value zero. + */ + XTSE1295, + + /** + * It is a static error if, for any named or unnamed decimal format, + * the variables representing characters used in a picture string + * do not each have distinct values. These variables are decimal-separator-sign, + * grouping-sign, percent-sign, per-mille-sign, digit-zero-sign, + * digit-sign, and pattern-separator-sign. + */ + XTSE1300, + + /** + * It is a static error if there is no namespace bound to the prefix + * on the element bearing the [xsl:]extension-element-prefixes attribute + * or, when \#default is specified, if there is no default namespace. + */ + XTSE1430, + + /** + * It is a static error if both the [xsl:]type and [xsl:]validation + * attributes are present on the xsl:element, xsl:attribute, xsl:copy, + * xsl:copy-of, xsl:document, or xsl:result-document instructions, + * or on a literal result element. + */ + XTSE1505, + + /** + * It is a static error if the value of the type attribute of an + * xsl:element, xsl:attribute, xsl:copy, xsl:copy-of, xsl:document, + * or xsl:result-document instruction, or the xsl:type attribute + * of a literal result element, is not a valid QName, or if it uses + * a prefix that is not defined in an in-scope namespace declaration, + * or if the QName is not the name of a type definition included + * in the in-scope schema components for the stylesheet. + */ + XTSE1520, + + /** + * It is a static error if the value of the type attribute of an + * xsl:attribute instruction refers to a complex type definition + */ + XTSE1530, + + /** + * It is a static error if two xsl:output declarations within an + * output definition specify explicit values for the same attribute + * (other than cdata-section-elements and use-character-maps), with + * the values of the attributes being not equal, unless there is + * another xsl:output declaration within the same output definition + * that has higher import precedence and that specifies an explicit + * value for the same attribute. + */ + XTSE1560, + + /** + * The value [of the method attribute on xsl:output ] must (if present) + * be a valid QName. If the QName does not have a prefix, then it + * identifies a method specified in [XSLT and XQuery Serialization] + * and must be one of xml, html, xhtml, or text. + */ + XTSE1570, + + /** + * It is a static error if the stylesheet contains two or more character + * maps with the same name and the same import precedence, unless + * it also contains another character map with the same name and + * higher import precedence. + */ + XTSE1580, + + /** + * It is a static error if a name in the use-character-maps attribute + * of the xsl:output or xsl:character-map elements does not match + * the name attribute of any xsl:character-map in the stylesheet. + */ + XTSE1590, + + /** + * It is a static error if a character map references itself, directly + * or indirectly, via a name in the use-character-maps attribute. + */ + XTSE1600, + + /** + * A basic XSLT processor must signal a static error if the stylesheet + * includes an xsl:import-schema declaration. + */ + XTSE1650, + + /** + * A basic XSLT processor must signal a static error if the stylesheet + * includes an [xsl:]type attribute, or an [xsl:]validation or default-validation + * attribute with a value other than strip. + */ + XTSE1660, + + /** + * It is a type error if the result of evaluating the sequence constructor + * cannot be converted to the required type. + */ + XTTE0505, + + /** + * It is a type error if an xsl:apply-templates instruction with + * no select attribute is evaluated when the context item is not + * a node. + */ + XTTE0510, + + /** + * It is a type error if the sequence returned by the select expression + * [of xsl:apply-templates] contains an item that is not a node. + */ + XTTE0520, + + /** + * It is a type error if the supplied value of a variable cannot + * be converted to the required type. + */ + XTTE0570, + + /** + * It is a type error if the conversion of the supplied value of + * a parameter to its required type fails. + */ + XTTE0590, + + /** + * If a default value is given explicitly, that is, if there is + * either a select attribute or a non-empty sequence constructor, + * then it is a type error if the default value cannot be converted + * to the required type, using the function conversion rules. + */ + XTTE0600, + + /** + * If the as attribute [of xsl:function ] is specified, then the + * result evaluated by the sequence constructor (see 5.7 Sequence + * Constructors) is converted to the required type, using the function + * conversion rules. It is a type error if this conversion fails. + */ + XTTE0780, + + /** + * If the value of a parameter to a stylesheet function cannot be + * converted to the required type, a type error is signaled. + */ + XTTE0790, + + /** + * It is a type error if the xsl:number instruction is evaluated, + * with no value or select attribute, when the context item is not + * a node. + */ + XTTE0990, + + /** + * It is a type error if the result of evaluating the select attribute + * of the xsl:number instruction is anything other than a single + * node. + */ + XTTE1000, + + /** + * If any sort key value, after atomization and any type conversion + * required by the data-type attribute, is a sequence containing + * more than one item, then the effect depends on whether the xsl:sort + * element is evaluated with backwards compatible behavior. With + * backwards compatible behavior, the effective sort key value is + * the first item in the sequence. In other cases, this is a type + * error. + */ + XTTE1020, + + /** + * It is a type error if the grouping key evaluated using the group-adjacent + * attribute is an empty sequence, or a sequence containing more + * than one item. + */ + XTTE1100, + + /** + * When the group-starting-with or group-ending-with attribute [of + * the xsl:for-each-group instruction] is used, it is a type error + * if the result of evaluating the select expression contains an + * item that is not a node. + */ + XTTE1120, + + /** + * If the validation attribute of an xsl:element, xsl:attribute, + * xsl:copy, xsl:copy-of, or xsl:result-document instruction, or + * the xsl:validation attribute of a literal result element, has + * the effective value strict, and schema validity assessment concludes + * that the validity of the element or attribute is invalid or unknown, + * a type error occurs. As with other type errors, the error may + * be signaled statically if it can be detected statically. + */ + XTTE1510, + + /** + * If the validation attribute of an xsl:element, xsl:attribute, + * xsl:copy, xsl:copy-of, or xsl:result-document instruction, or + * the xsl:validation attribute of a literal result element, has + * the effective value strict, and there is no matching top-level + * declaration in the schema, then a type error occurs. As with + * other type errors, the error may be signaled statically if it + * can be detected statically. + */ + XTTE1512, + + /** + * If the validation attribute of an xsl:element, xsl:attribute, + * xsl:copy, xsl:copy-of, or xsl:result-document instruction, or + * the xsl:validation attribute of a literal result element, has + * the effective value lax, and schema validity assessment concludes + * that the element or attribute is invalid, a type error occurs. + * As with other type errors, the error may be signaled statically + * if it can be detected statically. + */ + XTTE1515, + + /** + * It is a type error if an [xsl:]type attribute is defined for + * a constructed element or attribute, and the outcome of schema + * validity assessment against that type is that the validity property + * of that element or attribute information item is other than valid. + */ + XTTE1540, + + /** + * A type error occurs if a type or validation attribute is defined + * (explicitly or implicitly) for an instruction that constructs + * a new attribute node, if the effect of this is to cause the attribute + * value to be validated against a type that is derived from, or + * constructed by list or union from, the primitive types xs:QName + * or xs:NOTATION. + */ + XTTE1545, + + /** + * A type error occurs [when a document node is validated] unless + * the children of the document node comprise exactly one element + * node, no text nodes, and zero or more comment and processing + * instruction nodes, in any order. + */ + XTTE1550, + + /** + * It is a type error if, when validating a document node, document-level + * constraints are not satisfied. These constraints include identity + * constraints (xs:unique, xs:key, and xs:keyref) and ID/IDREF constraints. + */ + XTTE1555, + + /** + * It is a non-recoverable dynamic error if the effective value + * of an attribute written using curly brackets, in a position where + * an attribute value template is permitted, is a value that is + * not one of the permitted values for that attribute. If the processor + * is able to detect the error statically (for example, when any + * XPath expressions within the curly brackets can be evaluated + * statically), then the processor may optionally signal this as + * a static error. + */ + XTDE0030, + + /** + * It is a non-recoverable dynamic error if the invocation of the + * stylesheet specifies a template name that does not match the + * expanded-QName of a named template defined in the stylesheet. + */ + XTDE0040, + + /** + * It is a non-recoverable dynamic error if the invocation of the + * stylesheet specifies an initial mode (other than the default + * mode) that does not match the expanded-QName in the mode attribute + * of any template defined in the stylesheet. + */ + XTDE0045, + + /** + * It is a non-recoverable dynamic error if the invocation of the + * stylesheet specifies both an initial mode and an initial template. + */ + XTDE0047, + + /** + * It is a non-recoverable dynamic error if the stylesheet that + * is invoked declares a visible stylesheet parameter with required="yes" + * and no value for this parameter is supplied during the invocation + * of the stylesheet. A stylesheet parameter is visible if it is + * not masked by another global variable or parameter with the same + * name and higher import precedence. + */ + XTDE0050, + + /** + * It is a non-recoverable dynamic error if the initial template + * defines a template parameter that specifies required="yes". + */ + XTDE0060, + + /** + * If an implementation does not support backwards-compatible behavior, + * then it is a non-recoverable dynamic error if any element is + * evaluated that enables backwards-compatible behavior. + */ + XTDE0160, + + /** + * It is a recoverable dynamic error if this [the process of finding + * an xsl:strip-space or xsl:preserve-space declaration to match + * an element in the source document] leaves more than one match, + * unless all the matched declarations are equivalent (that is, + * they are all xsl:strip-space or they are all xsl:preserve-space). + * Action: The optional recovery action is to select, from the matches + * that are left, the one that occurs last in declaration order. + */ + XTRE0270, + + /** + * Where the result of evaluating an XPath expression (or an attribute + * value template) is required to be a lexical QName, then unless + * otherwise specified it is a non-recoverable dynamic error if + * the defining element has no namespace node whose name matches + * the prefix of the lexical QName. This error may be signaled as + * a static error if the value of the expression can be determined + * statically. + */ + XTDE0290, + + /** + * It is a non-recoverable dynamic error if the result sequence + * used to construct the content of an element node contains a namespace + * node or attribute node that is preceded in the sequence by a + * node that is neither a namespace node nor an attribute node. + */ + XTDE0410, + + /** + * It is a non-recoverable dynamic error if the result sequence + * used to construct the content of a document node contains a namespace + * node or attribute node. + */ + XTDE0420, + + /** + * It is a non-recoverable dynamic error if the result sequence + * contains two or more namespace nodes having the same name but + * different string values (that is, namespace nodes that map the + * same prefix to different namespace URIs). + */ + XTDE0430, + + /** + * It is a non-recoverable dynamic error if the result sequence + * contains a namespace node with no name and the element node being + * constructed has a null namespace URI (that is, it is an error + * to define a default namespace when the element is in no namespace). + */ + XTDE0440, + + /** + * It is a non-recoverable dynamic error if namespace fixup is performed + * on an element that contains among the typed values of the element + * and its attributes two values of type xs:QName or xs:NOTATION + * containing conflicting namespace prefixes, that is, two values + * that use the same prefix to refer to different namespace URIs. + */ + XTDE0485, + + /** + * It is a recoverable dynamic error if the conflict resolution + * algorithm for template rules leaves more than one matching template + * rule. Action: The optional recovery action is to select, from + * the matching template rules that are left, the one that occurs + * last in declaration order. + */ + XTRE0540, + + /** + * It is a non-recoverable dynamic error if xsl:apply-imports or + * xsl:next-match is evaluated when the current template rule is + * null. + */ + XTDE0560, + + /** + * If an optional parameter has no select attribute and has an empty + * sequence constructor, and if there is an as attribute, then the + * default value of the parameter is an empty sequence. If the empty + * sequence is not a valid instance of the required type defined + * in the as attribute, then the parameter is treated as a required + * parameter, which means that it is a non-recoverable dynamic error + * if the caller supplies no value for the parameter. + */ + XTDE0610, + + /** + * In general, a circularity in a stylesheet is a non-recoverable + * dynamic error. + */ + XTDE0640, + + /** + * In other cases, [with xsl:apply-templates, xsl:apply-imports, + * and xsl:next-match, or xsl:call-template with tunnel parameters] + * it is a non-recoverable dynamic error if the template that is + * invoked declares a template parameter with required="yes" and + * no value for this parameter is supplied by the calling instruction. + */ + XTDE0700, + + /** + * It is a recoverable dynamic error if the name of a constructed + * attribute is xml:space and the value is not either default or + * preserve. Action: The optional recovery action is to construct + * the attribute with the value as requested. + */ + XTRE0795, + + /** + * It is a non-recoverable dynamic error if the effective value + * of the name attribute [of the xsl:element instruction] is not + * a lexical QName. + */ + XTDE0820, + + /** + * In the case of an xsl:element instruction with no namespace attribute, + * it is a non-recoverable dynamic error if the effective value + * of the name attribute is a QName whose prefix is not declared + * in an in-scope namespace declaration for the xsl:element instruction. + */ + XTDE0830, + + /** + * It is a non-recoverable dynamic error if the effective value + * of the namespace attribute [of the xsl:element instruction] is + * not in the lexical space of the xs:anyURI data type. + */ + XTDE0835, + + /** + * It is a non-recoverable dynamic error if the effective value + * of the name attribute [of an xsl:attribute instruction] is not + * a lexical QName. + */ + XTDE0850, + + /** + * In the case of an xsl:attribute instruction with no namespace + * attribute, it is a non-recoverable dynamic error if the effective + * value of the name attribute is the string xmlns. + */ + XTDE0855, + + /** + * In the case of an xsl:attribute instruction with no namespace + * attribute, it is a non-recoverable dynamic error if the effective + * value of the name attribute is a lexical QName whose prefix is + * not declared in an in-scope namespace declaration for the xsl:attribute + * instruction. + */ + XTDE0860, + + /** + * It is a non-recoverable dynamic error if the effective value + * of the namespace attribute [of the xsl:attribute instruction] + * is not in the lexical space of the xs:anyURI data type. + */ + XTDE0865, + + /** + * It is a non-recoverable dynamic error if the effective value + * of the name attribute [of the xsl:processing-instruction instruction] + * is not both an NCName Names and a PITarget XML. + */ + XTDE0890, + + /** + * It is a non-recoverable dynamic error if the string value of + * the new namespace node [created using xsl:namespace] is not valid + * in the lexical space of the data type xs:anyURI. [see ERR XTDE0835] + */ + XTDE0905, + + /** + * It is a non-recoverable dynamic error if the effective value + * of the name attribute [of the xsl:namespace instruction] is neither + * a zero-length string nor an NCName Names, or if it is xmlns. + */ + XTDE0920, + + /** + * It is a non-recoverable dynamic error if the xsl:namespace instruction + * generates a namespace node whose name is xml and whose string + * value is not http://www.w3.org/XML/1998/namespace, or a namespace + * node whose string value is http://www.w3.org/XML/1998/namespace + * and whose name is not xml. + */ + XTDE0925, + + /** + * It is a non-recoverable dynamic error if evaluating the select + * attribute or the contained sequence constructor of an xsl:namespace + * instruction results in a zero-length string. + */ + XTDE0930, + + /** + * It is a non-recoverable dynamic error if any undiscarded item + * in the atomized sequence supplied as the value of the value attribute + * of xsl:number cannot be converted to an integer, or if the resulting + * integer is less than 0 (zero). + */ + XTDE0980, + + /** + * It is a non-recoverable dynamic error if, for any sort key component, + * the set of sort key values evaluated for all the items in the + * initial sequence, after any type conversion requested, contains + * a pair of ordinary values for which the result of the XPath lt + * operator is an error. + */ + XTDE1030, + + /** + * It is a non-recoverable dynamic error if the collation attribute + * of xsl:sort (after resolving against the base URI) is not a URI + * that is recognized by the implementation as referring to a collation. + */ + XTDE1035, + + /** + * It is a non-recoverable dynamic error if the collation URI specified + * to xsl:for-each-group (after resolving against the base URI) + * is a collation that is not recognized by the implementation. + * (For notes, [see ERR XTDE1035].) + */ + XTDE1110, + + /** + * It is a non-recoverable dynamic error if the effective value + * of the regex attribute [of the xsl:analyze-string instruction] + * does not conform to the required syntax for regular expressions, + * as specified in [Functions and Operators]. If the regular expression + * is known statically (for example, if the attribute does not contain + * any expressions enclosed in curly brackets) then the processor + * may signal the error as a static error. + */ + XTDE1140, + + /** + * It is a non-recoverable dynamic error if the effective value + * of the flags attribute [of the xsl:analyze-string instruction] + * has a value other than the values defined in [Functions and Operators]. + * If the value of the attribute is known statically (for example, + * if the attribute does not contain any expressions enclosed in + * curly brackets) then the processor may signal the error as a + * static error. + */ + XTDE1145, + + /** + * It is a non-recoverable dynamic error if the effective value + * of the regex attribute [of the xsl:analyze-string instruction] + * is a regular expression that matches a zero-length string: or + * more specifically, if the regular expression $r and flags $f + * are such that matches("", $r, $f) returns true. If the regular + * expression is known statically (for example, if the attribute + * does not contain any expressions enclosed in curly brackets) + * then the processor may signal the error as a static error. + */ + XTDE1150, + + /** + * When a URI reference [supplied to the document function] contains + * a fragment identifier, it is a recoverable dynamic error if the + * media type is not one that is recognized by the processor, or + * if the fragment identifier does not conform to the rules for + * fragment identifiers for that media type, or if the fragment + * identifier selects something other than a sequence of nodes (for + * example, if it selects a range of characters within a text node). + * Action: The optional recovery action is to ignore the fragment + * identifier and return the document node. + */ + XTRE1160, + + /** + * It is a non-recoverable dynamic error if a URI [supplied in the + * first argument to the unparsed-text function] contains a fragment + * identifier, or if it cannot be used to retrieve a resource containing + * text. + */ + XTDE1170, + + /** + * It is a non-recoverable dynamic error if a resource [retrieved + * using the unparsed-text function] contains octets that cannot + * be decoded into Unicode characters using the specified encoding, + * or if the resulting characters are not permitted XML characters. + * This includes the case where the processor does not support the + * requested encoding. + */ + XTDE1190, + + /** + * It is a non-recoverable dynamic error if the second argument + * of the unparsed-text function is omitted and the processor cannot + * infer the encoding using external information and the encoding + * is not UTF-8. + */ + XTDE1200, + + /** + * It is a non-recoverable dynamic error if the value [of the first + * argument to the key function] is not a valid QName, or if there + * is no namespace declaration in scope for the prefix of the QName, + * or if the name obtained by expanding the QName is not the same + * as the expanded name of any xsl:key declaration in the stylesheet. + * If the processor is able to detect the error statically (for + * example, when the argument is supplied as a string literal), + * then the processor may optionally signal this as a static error. + */ + XTDE1260, + + /** + * It is a non-recoverable dynamic error to call the key function + * with two arguments if there is no context node, or if the root + * of the tree containing the context node is not a document node; + * or to call the function with three arguments if the root of the + * tree containing the node supplied in the third argument is not + * a document node. + */ + XTDE1270, + + /** + * It is a non-recoverable dynamic error if the name specified as + * the $decimal-format-name argument [ to the format-number function] + * is not a valid QName, or if its prefix has not been declared + * in an in-scope namespace declaration, or if the stylesheet does + * not contain a declaration of a decimal-format with a matching + * expanded-QName. If the processor is able to detect the error + * statically (for example, when the argument is supplied as a string + * literal), then the processor may optionally signal this as a + * static error. + */ + XTDE1280, + + /** + * The picture string [supplied to the format-number function] must + * conform to the following rules. [ See full specification.] It + * is a non-recoverable dynamic error if the picture string does + * not satisfy these rules. + */ + XTDE1310, + + /** + * It is a non-recoverable dynamic error if the syntax of the picture + * [used for date/time formatting] is incorrect. + */ + XTDE1340, + + /** + * It is a non-recoverable dynamic error if a component specifier + * within the picture [used for date/time formatting] refers to + * components that are not available in the given type of $value, + * for example if the picture supplied to the format-time refers + * to the year, month, or day component. + */ + XTDE1350, + + /** + * If the current function is evaluated within an expression that + * is evaluated when the context item is undefined, a non-recoverable + * dynamic error occurs. + */ + XTDE1360, + + /** + * It is a non-recoverable dynamic error if the unparsed-entity-uri + * function is called when there is no context node, or when the + * root of the tree containing the context node is not a document + * node. + */ + XTDE1370, + + /** + * It is a non-recoverable dynamic error if the unparsed-entity-public-id + * function is called when there is no context node, or when the + * root of the tree containing the context node is not a document + * node. + */ + XTDE1380, + + /** + * It is a non-recoverable dynamic error if the value [supplied + * as the $property-name argument to the system-property function] + * is not a valid QName, or if there is no namespace declaration + * in scope for the prefix of the QName. If the processor is able + * to detect the error statically (for example, when the argument + * is supplied as a string literal), then the processor may optionally + * signal this as a static error. + */ + XTDE1390, + + /** + * When a transformation is terminated by use of xsl:message terminate="yes", + * the effect is the same as when a non-recoverable dynamic error + * occurs during the transformation. + */ + XTMM9000, + + /** + * It is a non-recoverable dynamic error if the argument [passed + * to the function-available function] does not evaluate to a string + * that is a valid QName, or if there is no namespace declaration + * in scope for the prefix of the QName. If the processor is able + * to detect the error statically (for example, when the argument + * is supplied as a string literal), then the processor may optionally + * signal this as a static error. + */ + XTDE1400, + + /** + * It is a non-recoverable dynamic error if the arguments supplied + * to a call on an extension function do not satisfy the rules defined + * for that particular extension function, or if the extension function + * reports an error, or if the result of the extension function + * cannot be converted to an XPath value. + */ + XTDE1420, + + /** + * When backwards compatible behavior is enabled, it is a non-recoverable + * dynamic error to evaluate an extension function call if no implementation + * of the extension function is available. + */ + XTDE1425, + + /** + * It is a non-recoverable dynamic error if the argument [passed + * to the type-available function] does not evaluate to a string + * that is a valid QName, or if there is no namespace declaration + * in scope for the prefix of the QName. If the processor is able + * to detect the error statically (for example, when the argument + * is supplied as a string literal), then the processor may optionally + * signal this as a static error. + */ + XTDE1428, + + /** + * It is a non-recoverable dynamic error if the argument [passed + * to the element-available function] does not evaluate to a string + * that is a valid QName, or if there is no namespace declaration + * in scope for the prefix of the QName. If the processor is able + * to detect the error statically (for example, when the argument + * is supplied as a string literal), then the processor may optionally + * signal this as a static error. + */ + XTDE1440, + + /** + * When a processor performs fallback for an extension instruction + * that is not recognized, if the instruction element has one or + * more xsl:fallback children, then the content of each of the xsl:fallback + * children must be evaluated; it is a non-recoverable dynamic error + * if it has no xsl:fallback children. + */ + XTDE1450, + + /** + * It is a non-recoverable dynamic error if the effective value + * of the format attribute [of an xsl:result-document element] is + * not a valid lexical QName, or if it does not match the expanded-QName + * of an output definition in the stylesheet. If the processor is + * able to detect the error statically (for example, when the format + * attribute contains no curly brackets), then the processor may + * optionally signal this as a static error. + */ + XTDE1460, + + /** + * It is a non-recoverable dynamic error to evaluate the xsl:result-document + * instruction in temporary output state. + */ + XTDE1480, + + /** + * It is a non-recoverable dynamic error for a transformation to + * generate two or more final result trees with the same URI. + */ + XTDE1490, + + /** + * It is a recoverable dynamic error for a transformation to generate + * two or more final result trees with URIs that identify the same + * physical resource. The optional recovery action is implementation-dependent, + * since it may be impossible for the processor to detect the error. + */ + XTRE1495, + + /** + * It is a recoverable dynamic error for a stylesheet to write to + * an external resource and read from the same resource during a + * single transformation, whether or not the same URI is used to + * access the resource in both cases. Action: The optional recovery + * action is implementation-dependent: implementations are not required + * to detect the error condition. Note that if the error is not + * detected, it is undefined whether the document that is read from + * the resource reflects its state before or after the result tree + * is written. + */ + XTRE1500, + + /** + * It is a recoverable dynamic error if an xsl:value-of or xsl:text + * instruction specifies that output escaping is to be disabled + * and the implementation does not support this. Action: The optional + * recovery action is to ignore the disable-output-escaping attribute. + */ + XTRE1620, + + /** + * It is a recoverable dynamic error if an xsl:value-of or xsl:text + * instruction specifies that output escaping is to be disabled + * when writing to a final result tree that is not being serialized. + * Action: The optional recovery action is to ignore the disable-output-escaping + * attribute. + */ + XTRE1630, + + /** + * A basic XSLT processor must raise a non-recoverable dynamic error + * if the input to the processor includes a node with a type annotation + * other than xs:untyped or xs:untypedAtomic, or an atomic value + * of a type other than those which a basic XSLT processor supports. + */ + XTDE1665 + + }; + + /** + * Issues a warning, should not be used excessively. This can + * be used to communicate that a certain implementation defined + * feature is unsupported or that a certain expression most likely + * doesn't do what the users wants, to name a few examples. + * + * @see XML Path Language (XPath) 2.0, + * 2.3 Error Handling + * @param message the message to be read by the user. + * @param sourceLocation the location of where the warning originates from. + */ + void warning(const QString &message, const QSourceLocation &sourceLocation = QSourceLocation()); + + /** + * Issues an error. May be used at the static analysis phase or + * the dynamic evaluation phase. + * + * For SourceLocationReflection instances, the overload taking an SouourceLocationReflection should be used. + * + * @see XML Path Language (XPath) 2.0, + * 2.3 Error Handling + * @param message the message to be read by the user. + * @param errorCode identifies the error condition, as described + * @param sourceLocation the location of where the error originates from + * in "XML Path Language (XPath) 2.0" section "G Error Conditions" + */ + void error(const QString &message, + const ReportContext::ErrorCode errorCode, + const QSourceLocation &sourceLocation); + + /** + * Overload. + * + * Same as the above, but passes the SourceLocationReflection as reference for error reporting. + */ + void error(const QString &message, + const ReportContext::ErrorCode errorCode, + const SourceLocationReflection *const reflection); + + /** + * Issues an error which is not identified in the XPath specifications. This function + * is among other things used for implementing the fn:error() function. + */ + void error(const QString &message, + const QXmlName qName, + const SourceLocationReflection *const r); + + /** + * @return the QAbstractMessageHandler which functions such as warning() and + * error() should submit messages to. This function + * may never return @c null; a valid QAbstractMessageHandler pointer must always be returned. + */ + virtual QAbstractMessageHandler *messageHandler() const = 0; + + virtual NamePool::Ptr namePool() const = 0; + + /** + * Returns a string representation of the error code @p code. + * + * @see ReportContext::ErrorCode + * @param errorCode identifies the error condition, as described + * in XML Path + * Language (XPath) 2.0, G Error Conditions + */ + static QString codeToString(const ReportContext::ErrorCode errorCode); + + /** + * @returns the error code part of @p typeURI and sets @p uri to the error namespace. Note + * that the error namespace not necessarily is the namespace for XPath and + * XQuery errors, http://www.w3.org/2005/xqt-errors, but can be user defined. + */ + static QString codeFromURI(const QString &typeURI, + QString &uri); + + /** + * @short Returns the source location applying for @p reflection. + */ + virtual QSourceLocation locationFor(const SourceLocationReflection *const reflection) const = 0; + + /** + * Resolves @p relative against @p baseURI, possibly using a URI resolver. + */ + QUrl resolveURI(const QUrl &relative, + const QUrl &baseURI) const; + + /** + * @short The URI resolver in use. + * + * If no URI resolver is in use, a @c null pointer is returned. + * + * @note You should probably use resolveURI(), which handles the case of + * when uriResolver() is @c null. + */ + virtual const QAbstractUriResolver *uriResolver() const = 0; + + private: + void createError(const QString &description, + const QtMsgType type, + const QUrl &id, + const QSourceLocation &sourceLocation) const; + static inline QString finalizeDescription(const QString &desc); + QSourceLocation lookupSourceLocation(const SourceLocationReflection *const ref) const; + + Q_DISABLE_COPY(ReportContext) + }; + + /** + * @short This is the class type that is being thrown when a query error occur. + * + * @relates ReportContext + */ + typedef bool Exception; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/environment/qstackcontextbase.cpp b/src/xmlpatterns/environment/qstackcontextbase.cpp new file mode 100644 index 0000000..cd22a55 --- /dev/null +++ b/src/xmlpatterns/environment/qstackcontextbase.cpp @@ -0,0 +1,153 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/** + * @file + * @short This file is included by qstackcontextbase_p.h. + * If you need includes in this file, put them in qstackcontextbase_p.h, outside of the namespace. + */ + +template +StackContextBase::StackContextBase() : m_rangeVariables(10), + m_expressionVariables(10), + m_positionIterators(5), + m_itemCacheCells(5), + m_itemSequenceCacheCells(5) +{ + /* The m_* containers are initialized with default sizes. Estimated guesses on usage patterns. */ +} + +template +StackContextBase::StackContextBase(const DynamicContext::Ptr &prevContext) + : TSuperClass(prevContext), + m_rangeVariables(10), + m_expressionVariables(10), + m_positionIterators(5), + m_itemCacheCells(5), + m_itemSequenceCacheCells(5) +{ + Q_ASSERT(prevContext); +} + +template +ItemCacheCell &StackContextBase::itemCacheCell(const VariableSlotID slot) +{ + if(slot >= m_itemCacheCells.size()) + m_itemCacheCells.resize(qMax(slot + 1, m_itemCacheCells.size())); + + return m_itemCacheCells[slot]; +} + +template +ItemSequenceCacheCell::Vector &StackContextBase::itemSequenceCacheCells(const VariableSlotID slot) +{ + if(slot >= m_itemSequenceCacheCells.size()) + m_itemSequenceCacheCells.resize(qMax(slot + 1, m_itemSequenceCacheCells.size())); + + return m_itemSequenceCacheCells; +} + +template +Item StackContextBase::rangeVariable(const VariableSlotID slot) const +{ + Q_ASSERT(slot < m_rangeVariables.size()); + Q_ASSERT(m_rangeVariables.at(slot)); + return m_rangeVariables.at(slot); +} + +template +Expression::Ptr StackContextBase::expressionVariable(const VariableSlotID slot) const +{ + Q_ASSERT(slot < m_expressionVariables.size()); + Q_ASSERT(m_expressionVariables.at(slot)); + return m_expressionVariables.at(slot); +} + +template +Item::Iterator::Ptr StackContextBase::positionIterator(const VariableSlotID slot) const +{ + Q_ASSERT(slot < m_positionIterators.size()); + return m_positionIterators.at(slot); +} + +template +template +inline +void StackContextBase::setSlotVariable(const VariableSlotID slot, + const UnitType &newValue, + VectorType &container) const +{ + if(slot < container.size()) + container.replace(slot, newValue); + else + { + container.resize(slot + 1); + container.replace(slot, newValue); + } +} + +template +void StackContextBase::setRangeVariable(const VariableSlotID slot, + const Item &newValue) +{ + setSlotVariable(slot, newValue, m_rangeVariables); +} + +template +void StackContextBase::setExpressionVariable(const VariableSlotID slot, + const Expression::Ptr &newValue) +{ + setSlotVariable(slot, newValue, m_expressionVariables); +} + +template +void StackContextBase::setPositionIterator(const VariableSlotID slot, + const Item::Iterator::Ptr &newValue) +{ + setSlotVariable(slot, newValue, m_positionIterators); +} + +template +DynamicContext::TemplateParameterHash &StackContextBase::templateParameterStore() +{ + return m_templateParameterStore; +} + diff --git a/src/xmlpatterns/environment/qstackcontextbase_p.h b/src/xmlpatterns/environment/qstackcontextbase_p.h new file mode 100644 index 0000000..9a2d3cf --- /dev/null +++ b/src/xmlpatterns/environment/qstackcontextbase_p.h @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_StackContextBase_H +#define Patternist_StackContextBase_H + +#include + +#include "qdaytimeduration_p.h" +#include "qdelegatingdynamiccontext_p.h" +#include "qexpression_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Base class for all DynamicContext classes that needs to supply + * variables. It has a new frame for local caches, position iterators, + * expressions, range variables, template parameters but notably continues + * to delegate global caches. + * + * @author Frans Englich + */ + template + class StackContextBase : public TSuperClass + { + public: + StackContextBase(); + /** + * Construct a StackContextBase and passes @p prevContext to its super class. This + * constructor is typically used when the super class is DelegatingDynamicContext. + */ + StackContextBase(const DynamicContext::Ptr &prevContext); + + virtual void setRangeVariable(const VariableSlotID slotNumber, + const Item &newValue); + virtual Item rangeVariable(const VariableSlotID slotNumber) const; + + virtual void setExpressionVariable(const VariableSlotID slotNumber, + const Expression::Ptr &newValue); + virtual Expression::Ptr expressionVariable(const VariableSlotID slotNumber) const; + + virtual Item::Iterator::Ptr positionIterator(const VariableSlotID slot) const; + virtual void setPositionIterator(const VariableSlotID slot, + const Item::Iterator::Ptr &newValue); + virtual ItemCacheCell &itemCacheCell(const VariableSlotID slot); + virtual ItemSequenceCacheCell::Vector &itemSequenceCacheCells(const VariableSlotID slot); + + virtual DynamicContext::TemplateParameterHash &templateParameterStore(); + + protected: + /** + * This function is protected, although it only is used in this class. I don't + * know why it has to be, but it won't compile when private. + */ + template + inline + void setSlotVariable(const VariableSlotID slot, + const UnitType &newValue, + VectorType &container) const; + + private: + Item::Vector m_rangeVariables; + Expression::Vector m_expressionVariables; + Item::Iterator::Vector m_positionIterators; + ItemCacheCell::Vector m_itemCacheCells; + ItemSequenceCacheCell::Vector m_itemSequenceCacheCells; + DynamicContext::TemplateParameterHash m_templateParameterStore; + }; + + #include "qstackcontextbase.cpp" + + /** + * @short A DynamicContext that creates a new scope for variables. + * + * This DynamicContext is used for recursive user function calls, for example. + */ + typedef StackContextBase StackContext; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/environment/qstaticbaseuricontext.cpp b/src/xmlpatterns/environment/qstaticbaseuricontext.cpp new file mode 100644 index 0000000..6907078 --- /dev/null +++ b/src/xmlpatterns/environment/qstaticbaseuricontext.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qstaticbaseuricontext_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +StaticBaseURIContext::StaticBaseURIContext(const QUrl &bURI, + const StaticContext::Ptr &prevContext) : DelegatingStaticContext(prevContext) + , m_baseURI(bURI) +{ + Q_ASSERT(m_baseURI.isValid()); + Q_ASSERT(!m_baseURI.isRelative()); + Q_ASSERT(prevContext); +} + +QUrl StaticBaseURIContext::baseURI() const +{ + return m_baseURI; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/environment/qstaticbaseuricontext_p.h b/src/xmlpatterns/environment/qstaticbaseuricontext_p.h new file mode 100644 index 0000000..555b560 --- /dev/null +++ b/src/xmlpatterns/environment/qstaticbaseuricontext_p.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_StaticBaseURIContext_H +#define Patternist_StaticBaseURIContext_H + +#include "qdelegatingstaticcontext_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A StaticContext that changes the static base URI. + * of items. + * + * @since 4.5 + * @author Frans Englich + */ + class StaticBaseURIContext : public DelegatingStaticContext + { + public: + /** + * The @p bURI is the new static base URI, and it must be valid + * and absolute. + */ + StaticBaseURIContext(const QUrl &bURI, + const StaticContext::Ptr &prevContext); + + virtual QUrl baseURI() const; + + private: + const QUrl m_baseURI; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/environment/qstaticcompatibilitycontext.cpp b/src/xmlpatterns/environment/qstaticcompatibilitycontext.cpp new file mode 100644 index 0000000..be86573 --- /dev/null +++ b/src/xmlpatterns/environment/qstaticcompatibilitycontext.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qstaticcompatibilitycontext_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +StaticCompatibilityContext::StaticCompatibilityContext(const StaticContext::Ptr &context) : DelegatingStaticContext(context) +{ +} + +bool StaticCompatibilityContext::compatModeEnabled() const +{ + return true; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/environment/qstaticcompatibilitycontext_p.h b/src/xmlpatterns/environment/qstaticcompatibilitycontext_p.h new file mode 100644 index 0000000..dbec0e9 --- /dev/null +++ b/src/xmlpatterns/environment/qstaticcompatibilitycontext_p.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_StaticCompatibilityContext_H +#define Patternist_StaticCompatibilityContext_H + +#include "qdelegatingstaticcontext_p.h" + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Has the XPath Compatibility Mode activated. Used for XSL-T 2.0's + * compatibility mode. + * + * @since 4.5 + * @author Frans Englich + */ + class Q_AUTOTEST_EXPORT StaticCompatibilityContext : public DelegatingStaticContext + { + public: + StaticCompatibilityContext(const StaticContext::Ptr &context); + + /** + * Returns always @c true. + */ + virtual bool compatModeEnabled() const; + }; +} + +QT_END_NAMESPACE +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/environment/qstaticcontext.cpp b/src/xmlpatterns/environment/qstaticcontext.cpp new file mode 100644 index 0000000..0c2f097 --- /dev/null +++ b/src/xmlpatterns/environment/qstaticcontext.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonnamespaces_p.h" +#include "qexpression_p.h" + +#include "qstaticcontext_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +StaticContext::~StaticContext() +{ +} + +void StaticContext::wrapExpressionWith(const SourceLocationReflection *const existingNode, + const QExplicitlySharedDataPointer &newNode) +{ + addLocation(newNode.data(), locationFor(existingNode)); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/environment/qstaticcontext_p.h b/src/xmlpatterns/environment/qstaticcontext_p.h new file mode 100644 index 0000000..ed45987 --- /dev/null +++ b/src/xmlpatterns/environment/qstaticcontext_p.h @@ -0,0 +1,299 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_StaticContext_H +#define Patternist_StaticContext_H + +#include "qexternalvariableloader_p.h" +#include "qitemtype_p.h" +#include "qnamepool_p.h" +#include "qnamespaceresolver_p.h" +#include "qreportcontext_p.h" +#include "qresourceloader_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QUrl; +template class QHash; + +namespace QPatternist +{ + class DynamicContext; + class Expression; + class FunctionFactory; + class SchemaTypeFactory; + + /** + * @short Carries information and facilities used at compilation time. + * + * A representation of the Static Context in XPath 2.0. The Static Context + * contains information which doesn't change and is the "outer scope" of the + * expression. It provides for example a base URI the expression can relate to and + * what functions and variables that are available for the expression. + * + * @see XML Path + * Language (XPath) 2.0, 2.1.1 Static Context + * @author Frans Englich + */ + class StaticContext : public ReportContext + { + public: + /** + * A smart pointer wrapping StaticContext instances. + */ + typedef QExplicitlySharedDataPointer Ptr; + + /** + * @see XQuery 1.0: + * An XML Query Language, 4.3 Boundary-space Declaration + * @see XQuery 1.0: + * An XML Query Language, Definition: Boundary-space policy + */ + enum BoundarySpacePolicy + { + BSPPreserve, + BSPStrip + }; + + /** + * @see XQuery 1.0: + * An XML Query Language, 4.6 Construction Declaration + * @see XQuery 1.0: + * An XML Query Language, Definition: Construction mode + */ + enum ConstructionMode + { + CMPreserve, + CMStrip + }; + + /** + * @see XQuery 1.0: + * An XML Query Language, 4.7 Ordering Mode Declaration + * @see XQuery 1.0: + * An XML Query Language, Definition: Ordering mode + */ + enum OrderingMode + { + Ordered, + Unordered + }; + + /** + * @see XQuery 1.0: + * An XML Query Language, 4.8 Empty Order Declaration + * @see XQuery 1.0: + * An XML Query Language, Definition: Default order for empty sequences + */ + enum OrderingEmptySequence + { + Greatest, + Least + }; + + enum InheritMode + { + Inherit, + NoInherit + }; + + enum PreserveMode + { + Preserve, + NoPreserve + }; + + inline StaticContext() + { + } + + virtual ~StaticContext(); + + virtual NamespaceResolver::Ptr namespaceBindings() const = 0; + virtual void setNamespaceBindings(const NamespaceResolver::Ptr &) = 0; + virtual QExplicitlySharedDataPointer functionSignatures() const = 0; + virtual QExplicitlySharedDataPointer schemaDefinitions() const = 0; + + /** + * The base URI of the context. Typically, this is the base URI + * if of the element that contained the expression. + * + * The base URI is in this implementation is never undefined, but is + * always valid. + */ + virtual QUrl baseURI() const = 0; + + virtual void setBaseURI(const QUrl &uri) = 0; + + /** + * @returns always the standard function namespace defined in + * XQuery 1.0 and + * XPath 2.0 Functions and Operators + */ + virtual QString defaultFunctionNamespace() const = 0; + virtual void setDefaultFunctionNamespace(const QString &ns) = 0; + + virtual QString defaultElementNamespace() const = 0; + virtual void setDefaultElementNamespace(const QString &ns) = 0; + + /** + * @returns the URI identifying the default collation. The function + * is responsible for ensuring a collation is always returned. If + * a collation is not provided by the user or the host language in the + * context, the Unicode codepoint URI should be returned. + */ + virtual QUrl defaultCollation() const = 0; + + virtual void setDefaultCollation(const QUrl &uri) = 0; + + /** + * Determine whether Backwards Compatible Mode is used. + * + * @see XML Path + * Language (XPath) 2.0, I Backwards Compatibility with XPath 1.0 (Non-Normative) + * @see XML Path + * Language (XPath) 2.0, Definition: XPath 1.0 compatibility mode + */ + virtual bool compatModeEnabled() const = 0; + + virtual void setCompatModeEnabled(const bool newVal) = 0; + + /** + * This is the DynamicContext that is used for pre-evaluation at + * compilation time, const-folding at the static stage. + */ + virtual QExplicitlySharedDataPointer dynamicContext() const = 0; + + virtual BoundarySpacePolicy boundarySpacePolicy() const = 0; + virtual void setBoundarySpacePolicy(const BoundarySpacePolicy policy) = 0; + + virtual ConstructionMode constructionMode() const = 0; + virtual void setConstructionMode(const ConstructionMode mode) = 0; + + virtual OrderingMode orderingMode() const = 0; + virtual void setOrderingMode(const OrderingMode mode) = 0; + virtual OrderingEmptySequence orderingEmptySequence() const = 0; + virtual void setOrderingEmptySequence(const OrderingEmptySequence ordering) = 0; + + virtual InheritMode inheritMode() const = 0; + virtual void setInheritMode(const InheritMode mode) = 0; + + virtual PreserveMode preserveMode() const = 0; + virtual void setPreserveMode(const PreserveMode mode) = 0; + + /** + * @short The static type of the context item. + * + * Different StaticContext instances are used for different nodes in the + * AST to properly reflect the type of the focus. If the focus is undefined, + * this function must return @c null. + * + * @see XQuery + * 1.0: An XML Query Language, Definition: Context item static type + */ + virtual ItemType::Ptr contextItemType() const = 0; + + /** + * @short The static type of the current item, as returned by @c + * fn:current(). + */ + virtual ItemType::Ptr currentItemType() const = 0; + + /** + * Copies this StaticContext and returns the copy. + * + * The copy and original must not be independent. Since the StaticContext is modified + * during the compilation process, the copy must be independent from the original + * to the degree that is required for the subclass in question. + */ + virtual StaticContext::Ptr copy() const = 0; + + virtual ExternalVariableLoader::Ptr externalVariableLoader() const = 0; + virtual ResourceLoader::Ptr resourceLoader() const = 0; + virtual NamePool::Ptr namePool() const = 0; + + /** + * @short Adds @p location for @p reflection. + */ + virtual void addLocation(const SourceLocationReflection *const reflection, + const QSourceLocation &location) = 0; + + /** + * @short Returns a hash of the contained locations. + * + * The key is the address for the expression, and the value is its location. Note + * that the key cannot be dereferenced, there's no guarantee the + * Expression is in scope. The key is merely an identifier. + */ + virtual LocationHash sourceLocations() const = 0; + + virtual VariableSlotID currentRangeSlot() const = 0; + virtual VariableSlotID allocateRangeSlot() = 0; + + /** + * @short Ensures source locations are handled in such a manner that @p + * existingNode wraps @p newNode. + * + * Ensures that the source locations for @p existingNode, applies to + * @p newNode. + */ + void wrapExpressionWith(const SourceLocationReflection *const existingNode, + const QExplicitlySharedDataPointer &newNode); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/environment/qstaticcurrentcontext.cpp b/src/xmlpatterns/environment/qstaticcurrentcontext.cpp new file mode 100644 index 0000000..421eb78 --- /dev/null +++ b/src/xmlpatterns/environment/qstaticcurrentcontext.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qstaticcurrentcontext_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +StaticCurrentContext::StaticCurrentContext(const ItemType::Ptr &t, + const StaticContext::Ptr &context) : DelegatingStaticContext(context) + , m_currentItemType(t) +{ + Q_ASSERT(m_currentItemType); +} + +ItemType::Ptr StaticCurrentContext::currentItemType() const +{ + return m_currentItemType; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/environment/qstaticcurrentcontext_p.h b/src/xmlpatterns/environment/qstaticcurrentcontext_p.h new file mode 100644 index 0000000..49e7523 --- /dev/null +++ b/src/xmlpatterns/environment/qstaticcurrentcontext_p.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_StaticCurrentContext_H +#define Patternist_StaticCurrentContext_H + +#include "qdelegatingstaticcontext_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A StaticContext that carries a specified static type for the + * current item, as returned by @c fn:current(), but otherwise delegates to + * another StaticContext. + * + * @since 4.5 + * @author Frans Englich + */ + class Q_AUTOTEST_EXPORT StaticCurrentContext : public DelegatingStaticContext + { + public: + StaticCurrentContext(const ItemType::Ptr ¤tItemType, + const StaticContext::Ptr &context); + /** + * @returns the type passed in the constructor. + */ + virtual ItemType::Ptr currentItemType() const; + + private: + const ItemType::Ptr m_currentItemType; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/environment/qstaticfocuscontext.cpp b/src/xmlpatterns/environment/qstaticfocuscontext.cpp new file mode 100644 index 0000000..3c21f69 --- /dev/null +++ b/src/xmlpatterns/environment/qstaticfocuscontext.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qstaticfocuscontext_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +StaticFocusContext::StaticFocusContext(const ItemType::Ptr &t, + const StaticContext::Ptr &context) : DelegatingStaticContext(context) + , m_contextItemType(t) +{ +} + +ItemType::Ptr StaticFocusContext::contextItemType() const +{ + return m_contextItemType; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/environment/qstaticfocuscontext_p.h b/src/xmlpatterns/environment/qstaticfocuscontext_p.h new file mode 100644 index 0000000..53308d0 --- /dev/null +++ b/src/xmlpatterns/environment/qstaticfocuscontext_p.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_StaticFocusContext_H +#define Patternist_StaticFocusContext_H + +#include "qdelegatingstaticcontext_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A StaticContext that carries a specified static type + * for the context item, but otherwise delegates to another StaticContext. + * + * @author Frans Englich + */ + class Q_AUTOTEST_EXPORT StaticFocusContext : public DelegatingStaticContext + { + public: + /** + * @p contextItemType may be @c null. + */ + StaticFocusContext(const ItemType::Ptr &contextItemType, + const StaticContext::Ptr &context); + /** + * @returns the type passed in the constructor. + */ + virtual ItemType::Ptr contextItemType() const; + + private: + const ItemType::Ptr m_contextItemType; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/environment/qstaticnamespacecontext.cpp b/src/xmlpatterns/environment/qstaticnamespacecontext.cpp new file mode 100644 index 0000000..521d504 --- /dev/null +++ b/src/xmlpatterns/environment/qstaticnamespacecontext.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qstaticnamespacecontext_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +StaticNamespaceContext::StaticNamespaceContext(const NamespaceResolver::Ptr &resolver, + const StaticContext::Ptr &context) : DelegatingStaticContext(context) + , m_namespaceBindings(resolver) +{ + Q_ASSERT(m_namespaceBindings); +} + +NamespaceResolver::Ptr StaticNamespaceContext::namespaceBindings() const +{ + return m_namespaceBindings; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/environment/qstaticnamespacecontext_p.h b/src/xmlpatterns/environment/qstaticnamespacecontext_p.h new file mode 100644 index 0000000..3aa1487 --- /dev/null +++ b/src/xmlpatterns/environment/qstaticnamespacecontext_p.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_StaticNamespaceContext_H +#define Patternist_StaticNamespaceContext_H + +#include "qdelegatingstaticcontext_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A StaticContext that carries a specified namespace resolver + * for the context item, but otherwise delegates to another StaticContext. + * + * @author Frans Englich + */ + class Q_AUTOTEST_EXPORT StaticNamespaceContext : public DelegatingStaticContext + { + public: + StaticNamespaceContext(const NamespaceResolver::Ptr &resolver, + const StaticContext::Ptr &context); + + /** + * @returns the resolver passed in the constructor. + */ + virtual NamespaceResolver::Ptr namespaceBindings() const; + + private: + const NamespaceResolver::Ptr m_namespaceBindings; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/expr.pri b/src/xmlpatterns/expr/expr.pri new file mode 100644 index 0000000..81c3994 --- /dev/null +++ b/src/xmlpatterns/expr/expr.pri @@ -0,0 +1,173 @@ +HEADERS += $$PWD/qandexpression_p.h \ + $$PWD/qapplytemplate_p.h \ + $$PWD/qargumentreference_p.h \ + $$PWD/qarithmeticexpression_p.h \ + $$PWD/qattributeconstructor_p.h \ + $$PWD/qattributenamevalidator_p.h \ + $$PWD/qaxisstep_p.h \ + $$PWD/qcachecells_p.h \ + $$PWD/qcallsite_p.h \ + $$PWD/qcalltargetdescription_p.h \ + $$PWD/qcalltemplate_p.h \ + $$PWD/qcastableas_p.h \ + $$PWD/qcastas_p.h \ + $$PWD/qcastingplatform_p.h \ + $$PWD/qcollationchecker_p.h \ + $$PWD/qcombinenodes_p.h \ + $$PWD/qcommentconstructor_p.h \ + $$PWD/qcomparisonplatform_p.h \ + $$PWD/qcomputednamespaceconstructor_p.h \ + $$PWD/qcontextitem_p.h \ + $$PWD/qcopyof_p.h \ + $$PWD/qcurrentitemstore_p.h \ + $$PWD/qdocumentconstructor_p.h \ + $$PWD/qdocumentcontentvalidator_p.h \ + $$PWD/qdynamiccontextstore_p.h \ + $$PWD/qelementconstructor_p.h \ + $$PWD/qemptycontainer_p.h \ + $$PWD/qemptysequence_p.h \ + $$PWD/qevaluationcache_p.h \ + $$PWD/qexpressiondispatch_p.h \ + $$PWD/qexpressionfactory_p.h \ + $$PWD/qexpression_p.h \ + $$PWD/qexpressionsequence_p.h \ + $$PWD/qexpressionvariablereference_p.h \ + $$PWD/qexternalvariableloader_p.h \ + $$PWD/qexternalvariablereference_p.h \ + $$PWD/qfirstitempredicate_p.h \ + $$PWD/qforclause_p.h \ + $$PWD/qgeneralcomparison_p.h \ + $$PWD/qgenericpredicate_p.h \ + $$PWD/qifthenclause_p.h \ + $$PWD/qinstanceof_p.h \ + $$PWD/qletclause_p.h \ + $$PWD/qliteral_p.h \ + $$PWD/qliteralsequence_p.h \ + $$PWD/qnamespaceconstructor_p.h \ + $$PWD/qncnameconstructor_p.h \ + $$PWD/qnodecomparison_p.h \ + $$PWD/qnodesort_p.h \ + $$PWD/qoperandsiterator_p.h \ + $$PWD/qoptimizationpasses_p.h \ + $$PWD/qoptimizerblocks_p.h \ + $$PWD/qoptimizerframework_p.h \ + $$PWD/qorderby_p.h \ + $$PWD/qorexpression_p.h \ + $$PWD/qpaircontainer_p.h \ + $$PWD/qparentnodeaxis_p.h \ + $$PWD/qpath_p.h \ + $$PWD/qpositionalvariablereference_p.h \ + $$PWD/qprocessinginstructionconstructor_p.h \ + $$PWD/qqnameconstructor_p.h \ + $$PWD/qquantifiedexpression_p.h \ + $$PWD/qrangeexpression_p.h \ + $$PWD/qrangevariablereference_p.h \ + $$PWD/qreturnorderby_p.h \ + $$PWD/qsimplecontentconstructor_p.h \ + $$PWD/qsinglecontainer_p.h \ + $$PWD/qsourcelocationreflection_p.h \ + $$PWD/qstaticbaseuristore_p.h \ + $$PWD/qstaticcompatibilitystore_p.h \ + $$PWD/qtemplatemode_p.h \ + $$PWD/qtemplateparameterreference_p.h \ + $$PWD/qtemplatepattern_p.h \ + $$PWD/qtemplatepattern_p.h \ + $$PWD/qtemplate_p.h \ + $$PWD/qtextnodeconstructor_p.h \ + $$PWD/qtreatas_p.h \ + $$PWD/qtriplecontainer_p.h \ + $$PWD/qtruthpredicate_p.h \ + $$PWD/qunaryexpression_p.h \ + $$PWD/qunlimitedcontainer_p.h \ + $$PWD/qunresolvedvariablereference_p.h \ + $$PWD/quserfunctioncallsite_p.h \ + $$PWD/quserfunction_p.h \ + $$PWD/qvalidate_p.h \ + $$PWD/qvaluecomparison_p.h \ + $$PWD/qvariabledeclaration_p.h \ + $$PWD/qvariablereference_p.h \ + $$PWD/qwithparam_p.h \ + $$PWD/qxsltsimplecontentconstructor_p.h + +SOURCES += $$PWD/qandexpression.cpp \ + $$PWD/qapplytemplate.cpp \ + $$PWD/qargumentreference.cpp \ + $$PWD/qarithmeticexpression.cpp \ + $$PWD/qattributeconstructor.cpp \ + $$PWD/qattributenamevalidator.cpp \ + $$PWD/qaxisstep.cpp \ + $$PWD/qcallsite.cpp \ + $$PWD/qcalltargetdescription.cpp \ + $$PWD/qcalltemplate.cpp \ + $$PWD/qcastableas.cpp \ + $$PWD/qcastas.cpp \ + $$PWD/qcollationchecker.cpp \ + $$PWD/qcombinenodes.cpp \ + $$PWD/qcommentconstructor.cpp \ + $$PWD/qcomputednamespaceconstructor.cpp \ + $$PWD/qcontextitem.cpp \ + $$PWD/qcopyof.cpp \ + $$PWD/qcurrentitemstore.cpp \ + $$PWD/qdocumentconstructor.cpp \ + $$PWD/qdocumentcontentvalidator.cpp \ + $$PWD/qdynamiccontextstore.cpp \ + $$PWD/qelementconstructor.cpp \ + $$PWD/qemptycontainer.cpp \ + $$PWD/qemptysequence.cpp \ + $$PWD/qexpression.cpp \ + $$PWD/qexpressionfactory.cpp \ + $$PWD/qexpressionsequence.cpp \ + $$PWD/qexpressionvariablereference.cpp \ + $$PWD/qexternalvariableloader.cpp \ + $$PWD/qexternalvariablereference.cpp \ + $$PWD/qfirstitempredicate.cpp \ + $$PWD/qforclause.cpp \ + $$PWD/qgeneralcomparison.cpp \ + $$PWD/qgenericpredicate.cpp \ + $$PWD/qifthenclause.cpp \ + $$PWD/qinstanceof.cpp \ + $$PWD/qletclause.cpp \ + $$PWD/qliteral.cpp \ + $$PWD/qliteralsequence.cpp \ + $$PWD/qnamespaceconstructor.cpp \ + $$PWD/qncnameconstructor.cpp \ + $$PWD/qnodecomparison.cpp \ + $$PWD/qnodesort.cpp \ + $$PWD/qoptimizationpasses.cpp \ + $$PWD/qoptimizerblocks.cpp \ + $$PWD/qoptimizerframework.cpp \ + $$PWD/qorderby.cpp \ + $$PWD/qorexpression.cpp \ + $$PWD/qpaircontainer.cpp \ + $$PWD/qparentnodeaxis.cpp \ + $$PWD/qpath.cpp \ + $$PWD/qpositionalvariablereference.cpp \ + $$PWD/qprocessinginstructionconstructor.cpp \ + $$PWD/qqnameconstructor.cpp \ + $$PWD/qquantifiedexpression.cpp \ + $$PWD/qrangeexpression.cpp \ + $$PWD/qrangevariablereference.cpp \ + $$PWD/qreturnorderby.cpp \ + $$PWD/qsimplecontentconstructor.cpp \ + $$PWD/qsinglecontainer.cpp \ + $$PWD/qsourcelocationreflection.cpp \ + $$PWD/qstaticbaseuristore.cpp \ + $$PWD/qstaticcompatibilitystore.cpp \ + $$PWD/qtemplate.cpp \ + $$PWD/qtemplateinvoker.cpp \ + $$PWD/qtemplatemode.cpp \ + $$PWD/qtemplateparameterreference.cpp \ + $$PWD/qtextnodeconstructor.cpp \ + $$PWD/qtreatas.cpp \ + $$PWD/qtriplecontainer.cpp \ + $$PWD/qtruthpredicate.cpp \ + $$PWD/qunaryexpression.cpp \ + $$PWD/qunlimitedcontainer.cpp \ + $$PWD/qunresolvedvariablereference.cpp \ + $$PWD/quserfunctioncallsite.cpp \ + $$PWD/quserfunction.cpp \ + $$PWD/qvalidate.cpp \ + $$PWD/qvaluecomparison.cpp \ + $$PWD/qvariabledeclaration.cpp \ + $$PWD/qvariablereference.cpp \ + $$PWD/qxsltsimplecontentconstructor.cpp diff --git a/src/xmlpatterns/expr/qandexpression.cpp b/src/xmlpatterns/expr/qandexpression.cpp new file mode 100644 index 0000000..ae1d6f2 --- /dev/null +++ b/src/xmlpatterns/expr/qandexpression.cpp @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qboolean_p.h" +#include "qcommonsequencetypes_p.h" +#include "qcommonvalues_p.h" +#include "qliteral_p.h" + +#include "qandexpression_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +AndExpression::AndExpression(const Expression::Ptr &operand1, + const Expression::Ptr &operand2) : PairContainer(operand1, operand2) +{ +} + +bool AndExpression::evaluateEBV(const DynamicContext::Ptr &context) const +{ + return m_operand1->evaluateEBV(context) && m_operand2->evaluateEBV(context); +} + +Expression::Ptr AndExpression::compress(const StaticContext::Ptr &context) +{ + const Expression::Ptr newMe(PairContainer::compress(context)); + + if(newMe != this) + return newMe; + + /* Both operands mustn't be evaluated in order to be able to compress. */ + if(m_operand1->isEvaluated() && !m_operand1->evaluateEBV(context->dynamicContext())) + return wrapLiteral(CommonValues::BooleanFalse, context, this); + else if(m_operand2->isEvaluated() && !m_operand2->evaluateEBV(context->dynamicContext())) + return wrapLiteral(CommonValues::BooleanFalse, context, this); + else + return Expression::Ptr(this); +} + +SequenceType::List AndExpression::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::EBV); + result.append(CommonSequenceTypes::EBV); + return result; +} + +SequenceType::Ptr AndExpression::staticType() const +{ + return CommonSequenceTypes::ExactlyOneBoolean; +} + +ExpressionVisitorResult::Ptr AndExpression::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qandexpression_p.h b/src/xmlpatterns/expr/qandexpression_p.h new file mode 100644 index 0000000..b4fd87c --- /dev/null +++ b/src/xmlpatterns/expr/qandexpression_p.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_AndExpression_H +#define Patternist_AndExpression_H + +#include "qpaircontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Implements XPath 2.0's logical expression @c and. + * + * The @c and expression is the same in XQuery 1.0 as in XPath 2.0. + * + * @see XML Path Language + * (XPath) 2.0, 3.6 Logical Expressions + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class AndExpression : public PairContainer + { + public: + AndExpression(const Expression::Ptr &operand1, + const Expression::Ptr &operand2); + + virtual bool evaluateEBV(const DynamicContext::Ptr &context) const; + + virtual SequenceType::List expectedOperandTypes() const; + + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + /** + * @returns always CommonSequenceTypes::ExactlyOneBoolean + */ + virtual SequenceType::Ptr staticType() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qapplytemplate.cpp b/src/xmlpatterns/expr/qapplytemplate.cpp new file mode 100644 index 0000000..2a9f501 --- /dev/null +++ b/src/xmlpatterns/expr/qapplytemplate.cpp @@ -0,0 +1,210 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qaxisstep_p.h" +#include "qcommonsequencetypes_p.h" +#include "qcommonvalues_p.h" +#include "qitemmappingiterator_p.h" +#include "qsequencemappingiterator_p.h" +#include "qpatternistlocale_p.h" + +#include "qapplytemplate_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +ApplyTemplate::ApplyTemplate(const TemplateMode::Ptr &mode, + const WithParam::Hash &withParams, + const TemplateMode::Ptr &defaultMode) : TemplateInvoker(withParams) + , m_mode(mode) + , m_defaultMode(defaultMode) +{ + Q_ASSERT_X(m_mode || m_defaultMode, Q_FUNC_INFO, + "Either a mode, or the default mode must be supplied."); +} + +Item ApplyTemplate::mapToItem(const QXmlNodeModelIndex &node, + const DynamicContext::Ptr &) const +{ + return Item(node); +} + +Item::Iterator::Ptr ApplyTemplate::mapToSequence(const Item &item, + const DynamicContext::Ptr &context) const +{ + Q_UNUSED(item); + return evaluateSequence(context); +} + +TemplateMode::Ptr ApplyTemplate::effectiveMode(const DynamicContext::Ptr &context) const +{ + if(m_mode) + return m_mode; + else + { + const TemplateMode::Ptr currentMode(context->currentTemplateMode()); + + if(currentMode) + return currentMode; + else + return m_defaultMode; + } +} + +Template::Ptr ApplyTemplate::findTemplate(const DynamicContext::Ptr &context, + const TemplateMode::Ptr &templateMode) const +{ + const int count = templateMode->templatePatterns.count(); + Template::Ptr result; + /* It's redundant to initialize these values, but it suppresses false + * positives with GCC. */ + PatternPriority priority = 0; + TemplatePattern::ID id = -1; + + /* Possible optimization: detecting ambiguous rule matches could be forked off to a + * low prioirity thread. */ + for(int i = 0; i < count; ++i) + { + const TemplatePattern::Ptr &candidate = templateMode->templatePatterns.at(i); + if(candidate->matchPattern()->evaluateEBV(context)) + { + if(result) + { + if( candidate->id() != id + && candidate->priority() == priority + && candidate->templateTarget()->importPrecedence == + result->importPrecedence) + { + context->error(QtXmlPatterns::tr("Ambiguous rule match."), + ReportContext::XTRE0540, this); + } + else + break; + } + else + { + result = candidate->templateTarget(); + priority = candidate->priority(); + id = candidate->id(); + } + } + } + + return result; +} + +Item::Iterator::Ptr ApplyTemplate::evaluateSequence(const DynamicContext::Ptr &context) const +{ + const TemplateMode::Ptr templateMode(effectiveMode(context)); + const Template::Ptr &templateMatch = findTemplate(context, templateMode); + + if(templateMatch) + return templateMatch->body->evaluateSequence(templateMatch->createContext(this, context, false)); + else + { + /* None of our templates matched. Proceed with a built-in. */ + const Item current(context->contextItem()); + // TODO it can be an atomic value? + const QXmlNodeModelIndex::NodeKind kind(current.asNode().kind()); + + if(kind == QXmlNodeModelIndex::Element || kind == QXmlNodeModelIndex::Document) + { + pDebug() << "No template match, using builtin template for element() | document-node()"; + + const Item::Iterator::Ptr focusIterator(makeItemMappingIterator(ConstPtr(this), + current.asNode().iterate(QXmlNodeModelIndex::AxisChild), + context)); + + const DynamicContext::Ptr focus(context->createFocus()); + focus->setFocusIterator(focusIterator); + return makeSequenceMappingIterator(ConstPtr(this), focusIterator, focus); + } + return CommonValues::emptyIterator; + } +} + +Expression::Ptr ApplyTemplate::compress(const StaticContext::Ptr &context) +{ + /* If we have a mode, we will never need the default mode. */ + if(m_mode) + m_defaultMode.reset(); + + return TemplateInvoker::compress(context); +} + +SequenceType::Ptr ApplyTemplate::staticType() const +{ + return CommonSequenceTypes::ZeroOrMoreItems; +} + +ExpressionVisitorResult::Ptr ApplyTemplate::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +Expression::Properties ApplyTemplate::properties() const +{ + return RequiresFocus | DisableElimination; +} + +bool ApplyTemplate::configureRecursion(const CallTargetDescription::Ptr &sign) +{ + Q_ASSERT_X(false, Q_FUNC_INFO, "We're not expected to be called."); + Q_UNUSED(sign); + return false; +} + +Expression::Ptr ApplyTemplate::body() const +{ + Q_ASSERT_X(false, Q_FUNC_INFO, "We're not expected to be called."); + return Expression::Ptr(); +} + +CallTargetDescription::Ptr ApplyTemplate::callTargetDescription() const +{ + Q_ASSERT_X(false, Q_FUNC_INFO, "We're not expected to be called."); + return CallTargetDescription::Ptr(); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qapplytemplate_p.h b/src/xmlpatterns/expr/qapplytemplate_p.h new file mode 100644 index 0000000..1398945 --- /dev/null +++ b/src/xmlpatterns/expr/qapplytemplate_p.h @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ApplyTemplate_H +#define Patternist_ApplyTemplate_H + +#include "qtemplatemode_p.h" + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short When combined with other components, implements + * @c xsl:apply-templates. + * + * Note that ApplyTemplate isn't named ApplyTemplates. The reason for this + * is that ApplyTemplate doesn't do the iteration part. An @c + * instruction is rewritten into: + * + * @code + * child::node/() map apply-template() + * @endcode + * + * Hence, this expression requires a focus, although it can consist of + * atomic values. + * + * @since 4.5 + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class ApplyTemplate : public TemplateInvoker + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * @short @p mode may be @c null. If it is, ApplyTemplate interprets + * that as that it should use the #current mode. + * + * @see StaticContext::currentTemplateMode() + */ + ApplyTemplate(const TemplateMode::Ptr &mode, + const WithParam::Hash &withParams, + const TemplateMode::Ptr &defaultMode); + + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + + virtual SequenceType::Ptr staticType() const; + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + virtual Properties properties() const; + + /** + * The only reason this function exists, is in order to convert + * QXmlNodeModelIndex to QPatternist::Item. So, this is a huge + * performance setback. It applies for one of the builtin templates. + */ + inline Item mapToItem(const QXmlNodeModelIndex &node, + const DynamicContext::Ptr &context) const; + inline Item::Iterator::Ptr mapToSequence(const Item &item, + const DynamicContext::Ptr &context) const; + + inline TemplateMode::Ptr mode() const; + + virtual bool configureRecursion(const CallTargetDescription::Ptr &sign); + virtual Expression::Ptr body() const; + virtual CallTargetDescription::Ptr callTargetDescription() const; + + Expression::Ptr compress(const StaticContext::Ptr &context); + + private: + typedef QExplicitlySharedDataPointer ConstPtr; + + Template::Ptr findTemplate(const DynamicContext::Ptr &context, + const TemplateMode::Ptr &templateMode) const; + /** + * @note You typically want to use effectiveMode(). + */ + const TemplateMode::Ptr m_mode; + + TemplateMode::Ptr m_defaultMode; + + inline TemplateMode::Ptr effectiveMode(const DynamicContext::Ptr &context) const; + }; + + TemplateMode::Ptr ApplyTemplate::mode() const + { + return m_mode; + } +} + +QT_END_NAMESPACE +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qargumentreference.cpp b/src/xmlpatterns/expr/qargumentreference.cpp new file mode 100644 index 0000000..d4c1bc6 --- /dev/null +++ b/src/xmlpatterns/expr/qargumentreference.cpp @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include "qargumentreference_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +ArgumentReference::ArgumentReference(const SequenceType::Ptr &sourceType, + const VariableSlotID slotP) : VariableReference(slotP), + m_type(sourceType) +{ + Q_ASSERT(m_type); +} + +bool ArgumentReference::evaluateEBV(const DynamicContext::Ptr &context) const +{ + return context->expressionVariable(slot())->evaluateEBV(context); +} + +Item ArgumentReference::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + return context->expressionVariable(slot())->evaluateSingleton(context); +} + +Item::Iterator::Ptr ArgumentReference::evaluateSequence(const DynamicContext::Ptr &context) const +{ + return context->expressionVariable(slot())->evaluateSequence(context); +} + +SequenceType::Ptr ArgumentReference::staticType() const +{ + return m_type; +} + +ExpressionVisitorResult::Ptr ArgumentReference::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +Expression::ID ArgumentReference::id() const +{ + return IDArgumentReference; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qargumentreference_p.h b/src/xmlpatterns/expr/qargumentreference_p.h new file mode 100644 index 0000000..0fc51d3 --- /dev/null +++ b/src/xmlpatterns/expr/qargumentreference_p.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ArgumentReference_H +#define Patternist_ArgumentReference_H + +#include "qvariablereference_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A reference to an argument declared in a UserFunction. + * + * This is in other words a variable reference in side a function + * body, that references a function argument. + * + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class ArgumentReference : public VariableReference + { + public: + ArgumentReference(const SequenceType::Ptr &sourceType, + const VariableSlotID slot); + + virtual bool evaluateEBV(const DynamicContext::Ptr &context) const; + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + virtual SequenceType::Ptr staticType() const; + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + virtual ID id() const; + + private: + const SequenceType::Ptr m_type; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qarithmeticexpression.cpp b/src/xmlpatterns/expr/qarithmeticexpression.cpp new file mode 100644 index 0000000..e424dc0 --- /dev/null +++ b/src/xmlpatterns/expr/qarithmeticexpression.cpp @@ -0,0 +1,363 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qboolean_p.h" +#include "qbuiltintypes_p.h" +#include "qcommonsequencetypes_p.h" +#include "qemptysequence_p.h" +#include "qgenericsequencetype_p.h" +#include "qliteral_p.h" +#include "qpatternistlocale_p.h" +#include "qschemanumeric_p.h" +#include "quntypedatomicconverter_p.h" + +#include "qarithmeticexpression_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +ArithmeticExpression::ArithmeticExpression(const Expression::Ptr &op1, + const AtomicMathematician::Operator op, + const Expression::Ptr &op2) : PairContainer(op1, op2) + , m_op(op) + , m_isCompat(false) +{ +} + +Item ArithmeticExpression::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item op1(m_operand1->evaluateSingleton(context)); + if(!op1) + return Item(); + + const Item op2(m_operand2->evaluateSingleton(context)); + if(!op2) + return Item(); + + return flexiblyCalculate(op1, m_op, op2, m_mather, context, this, + ReportContext::XPTY0004, m_isCompat); +} + +/** + * Since ArithmeticExpression::flexiblyCalculate() creates Expression instances + * at runtime, we have the problem of having SourceLocationReflections for them + * in the case that we run into a runtime error, since the locations are always + * located at compile time. + * + * This class simply delegates the reflection over to an existing expression. + * + * I only managed to trigger this with "current() + 1", where current() + * evaluates to an invalid representation for @c xs:double. + * + * @since 4.5 + * @author Frans Englich + */ +class DelegatingReflectionExpression : public Literal +{ +public: + DelegatingReflectionExpression(const Item &item, + const SourceLocationReflection *const reflection) : Literal(item) + , m_reflection(reflection) + { + } + + virtual const SourceLocationReflection *actualReflection() const + { + return m_reflection; + } + +private: + const SourceLocationReflection *const m_reflection; +}; + +Item ArithmeticExpression::flexiblyCalculate(const Item &op1, + const AtomicMathematician::Operator op, + const Item &op2, + const AtomicMathematician::Ptr &mather, + const DynamicContext::Ptr &context, + const SourceLocationReflection *const reflection, + const ReportContext::ErrorCode code, + const bool isCompat) +{ + if(mather) + return mather->calculate(op1, op, op2, context); + + /* This is a very heavy code path. */ + Expression::Ptr a1(new DelegatingReflectionExpression(op1, reflection)); + Expression::Ptr a2(new DelegatingReflectionExpression(op2, reflection)); + + const AtomicMathematician::Ptr ingela(fetchMathematician(a1, a2, op, true, context, reflection, code, isCompat)); + + return ingela->calculate(a1->evaluateSingleton(context), + op, + a2->evaluateSingleton(context), + context); +} + +Expression::Ptr ArithmeticExpression::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + m_isCompat = context->compatModeEnabled(); + + const Expression::Ptr me(PairContainer::typeCheck(context, reqType)); + const ItemType::Ptr t1(m_operand1->staticType()->itemType()); + const ItemType::Ptr t2(m_operand2->staticType()->itemType()); + + if(*CommonSequenceTypes::Empty == *t1 || + *CommonSequenceTypes::Empty == *t2) + { + return EmptySequence::create(this, context); + } + + if(*BuiltinTypes::xsAnyAtomicType == *t1 || + *BuiltinTypes::xsAnyAtomicType == *t2 || + *BuiltinTypes::numeric == *t1 || + *BuiltinTypes::numeric == *t2) + { + /* The static type of (at least) one of the operands could not + * be narrowed further than xs:anyAtomicType, so we do the operator + * lookup at runtime. */ + return me; + } + + m_mather = fetchMathematician(m_operand1, m_operand2, m_op, true, context, this, + ReportContext::XPTY0004, m_isCompat); + + return me; +} + +AtomicMathematician::Ptr +ArithmeticExpression::fetchMathematician(Expression::Ptr &op1, + Expression::Ptr &op2, + const AtomicMathematician::Operator op, + const bool issueError, + const ReportContext::Ptr &context, + const SourceLocationReflection *const reflection, + const ReportContext::ErrorCode code, + const bool isCompat) +{ + ItemType::Ptr t1(op1->staticType()->itemType()); + ItemType::Ptr t2(op2->staticType()->itemType()); + + if(BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t1) + || (isCompat && (BuiltinTypes::xsString->xdtTypeMatches(t1) + || BuiltinTypes::xsDecimal->xdtTypeMatches(t1)))) + { + op1 = Expression::Ptr(new UntypedAtomicConverter(op1, BuiltinTypes::xsDouble)); + /* The types might have changed, reload. */ + t1 = op1->staticType()->itemType(); + } + + if(BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t2) + || (isCompat && (BuiltinTypes::xsString->xdtTypeMatches(t1) + || BuiltinTypes::xsDecimal->xdtTypeMatches(t1)))) + { + op2 = Expression::Ptr(new UntypedAtomicConverter(op2, BuiltinTypes::xsDouble)); + /* The types might have changed, reload. */ + t2 = op2->staticType()->itemType(); + } + + const AtomicMathematicianLocator::Ptr locator + (static_cast(t1.data())->mathematicianLocator()); + + if(!locator) + { + if(!issueError) + return AtomicMathematician::Ptr(); + + context->error(QtXmlPatterns::tr( + "Operator %1 cannot be used on type %2.") + .arg(formatKeyword(AtomicMathematician::displayName(op))) + .arg(formatType(context->namePool(), t1)), + code, reflection); + return AtomicMathematician::Ptr(); + } + + const AtomicMathematician::Ptr comp + (static_cast(t2.data())->accept(locator, op, reflection)); + + if(comp) + return comp; + + if(!issueError) + return AtomicMathematician::Ptr(); + + context->error(QtXmlPatterns::tr("Operator %1 cannot be used on " + "atomic values of type %2 and %3.") + .arg(formatKeyword(AtomicMathematician::displayName(op))) + .arg(formatType(context->namePool(), t1)) + .arg(formatType(context->namePool(), t2)), + code, reflection); + return AtomicMathematician::Ptr(); +} + +SequenceType::Ptr ArithmeticExpression::staticType() const +{ + Cardinality card; + + /* These variables are important because they ensure staticType() only + * gets called once from this function. Before, this lead to strange + * semi-infinite recursion involving many arithmetic expressions. */ + const SequenceType::Ptr st1(m_operand1->staticType()); + const SequenceType::Ptr st2(m_operand2->staticType()); + + if(st1->cardinality().allowsEmpty() || + st2->cardinality().allowsEmpty()) + { + card = Cardinality::zeroOrOne(); + } + else + card = Cardinality::exactlyOne(); + + if(m_op == AtomicMathematician::IDiv) + return makeGenericSequenceType(BuiltinTypes::xsInteger, card); + + const ItemType::Ptr t1(st1->itemType()); + const ItemType::Ptr t2(st2->itemType()); + ItemType::Ptr returnType; + + /* Please, make this beautiful? */ + if(BuiltinTypes::xsTime->xdtTypeMatches(t1) || + BuiltinTypes::xsDate->xdtTypeMatches(t1) || + BuiltinTypes::xsDateTime->xdtTypeMatches(t1)) + { + if(BuiltinTypes::xsDuration->xdtTypeMatches(t2)) + returnType = t1; + else + returnType = BuiltinTypes::xsDayTimeDuration; + } + else if(BuiltinTypes::xsYearMonthDuration->xdtTypeMatches(t1)) + { + if(m_op == AtomicMathematician::Div && + BuiltinTypes::xsYearMonthDuration->xdtTypeMatches(t2)) + { + returnType = BuiltinTypes::xsDecimal; + } + else if(BuiltinTypes::numeric->xdtTypeMatches(t2)) + returnType = BuiltinTypes::xsYearMonthDuration; + else + returnType = t2; + } + else if(BuiltinTypes::xsYearMonthDuration->xdtTypeMatches(t2)) + { + returnType = BuiltinTypes::xsYearMonthDuration; + } + else if(BuiltinTypes::xsDayTimeDuration->xdtTypeMatches(t1)) + { + if(m_op == AtomicMathematician::Div && + BuiltinTypes::xsDayTimeDuration->xdtTypeMatches(t2)) + { + returnType = BuiltinTypes::xsDecimal; + } + else if(BuiltinTypes::numeric->xdtTypeMatches(t2)) + returnType = BuiltinTypes::xsDayTimeDuration; + else + returnType = t2; + } + else if(BuiltinTypes::xsDayTimeDuration->xdtTypeMatches(t2)) + { + returnType = BuiltinTypes::xsDayTimeDuration; + } + else if(BuiltinTypes::xsDouble->xdtTypeMatches(t1) || + BuiltinTypes::xsDouble->xdtTypeMatches(t2)) + { + returnType = BuiltinTypes::xsDouble; + } + else if(BuiltinTypes::xsFloat->xdtTypeMatches(t1) || + BuiltinTypes::xsFloat->xdtTypeMatches(t2)) + { + if(m_isCompat) + returnType = BuiltinTypes::xsFloat; + else + returnType = BuiltinTypes::xsDouble; + } + else if(BuiltinTypes::xsInteger->xdtTypeMatches(t1) && + BuiltinTypes::xsInteger->xdtTypeMatches(t2)) + { + if(m_isCompat) + returnType = BuiltinTypes::xsDouble; + else + { + /* "A div B numeric numeric op:numeric-divide(A, B) + * numeric; but xs:decimal if both operands are xs:integer" */ + if(m_op == AtomicMathematician::Div) + returnType = BuiltinTypes::xsDecimal; + else + returnType = BuiltinTypes::xsInteger; + } + } + else if(m_isCompat && (BuiltinTypes::xsInteger->xdtTypeMatches(t1) && + BuiltinTypes::xsInteger->xdtTypeMatches(t2))) + { + returnType = BuiltinTypes::xsDouble; + } + else + { + /* If typeCheck() has been called, our operands conform to expectedOperandTypes(), and + * the types are hence either xs:decimals, or xs:anyAtomicType(meaning the static type could + * not be inferred), or empty-sequence(). So we use the union of the two types. The combinations + * could also be wrong.*/ + returnType = t1 | t2; + + /* However, if we're called before typeCheck(), we could potentially have nodes, so we need to make + * sure that the type is at least atomic. */ + if(!BuiltinTypes::xsAnyAtomicType->xdtTypeMatches(returnType)) + returnType = BuiltinTypes::xsAnyAtomicType; + } + + return makeGenericSequenceType(returnType, card); +} + +SequenceType::List ArithmeticExpression::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ZeroOrOneAtomicType); + result.append(CommonSequenceTypes::ZeroOrOneAtomicType); + return result; +} + +ExpressionVisitorResult::Ptr ArithmeticExpression::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qarithmeticexpression_p.h b/src/xmlpatterns/expr/qarithmeticexpression_p.h new file mode 100644 index 0000000..a1621f7 --- /dev/null +++ b/src/xmlpatterns/expr/qarithmeticexpression_p.h @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ArithmeticExpression_H +#define Patternist_ArithmeticExpression_H + +#include "qatomicmathematician_p.h" +#include "qpaircontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements arithmetics, such as multiplication and subtraction. + * + * + * Optimizations: there's some operator/value combos that are no ops. For + * instance, 0 + , which is the case of unary plus. We can't compile + * those away early due to that type checks needs to be done but one can + * check for them in compress(). + * + * @see XML Path Language + * (XPath) 2.0, 3.4 Arithmetic Expressions + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class Q_AUTOTEST_EXPORT ArithmeticExpression : public PairContainer + { + public: + ArithmeticExpression(const Expression::Ptr &operand1, + const AtomicMathematician::Operator op, + const Expression::Ptr &operand2); + + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + + virtual SequenceType::Ptr staticType() const; + virtual SequenceType::List expectedOperandTypes() const; + AtomicMathematician::Operator operatorID() const; + + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + static Item flexiblyCalculate(const Item &op1, + const AtomicMathematician::Operator op, + const Item &op2, + const AtomicMathematician::Ptr &mather, + const DynamicContext::Ptr &context, + const SourceLocationReflection *const reflection, + const ReportContext::ErrorCode code = ReportContext::XPTY0004, + const bool isCompat = false); + + static AtomicMathematician::Ptr + fetchMathematician(Expression::Ptr &t1, + Expression::Ptr &t2, + const AtomicMathematician::Operator op, + const bool issueError, + const ReportContext::Ptr &context, + const SourceLocationReflection *const reflection, + const ReportContext::ErrorCode code = ReportContext::XPTY0004, + const bool isCompat = false); + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + + protected: + + private: + const AtomicMathematician::Operator m_op; + AtomicMathematician::Ptr m_mather; + bool m_isCompat; + }; + + inline AtomicMathematician::Operator ArithmeticExpression::operatorID() const + { + return m_op; + } + +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qattributeconstructor.cpp b/src/xmlpatterns/expr/qattributeconstructor.cpp new file mode 100644 index 0000000..fa41afd --- /dev/null +++ b/src/xmlpatterns/expr/qattributeconstructor.cpp @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qcommonsequencetypes_p.h" +#include "qnodebuilder_p.h" +#include "qqnamevalue_p.h" + +#include "qattributeconstructor_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +AttributeConstructor::AttributeConstructor(const Expression::Ptr &op1, + const Expression::Ptr &op2) : PairContainer(op1, op2) +{ +} + +QString AttributeConstructor::processValue(const QXmlName name, + const Item &value) +{ + if(!value) + return QString(); + else if(name == QXmlName(StandardNamespaces::xml, StandardLocalNames::id)) + return value.stringValue().simplified(); + else + return value.stringValue(); +} + +Item AttributeConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item nameItem(m_operand1->evaluateSingleton(context)); + const Item content(m_operand2->evaluateSingleton(context)); + + const QXmlName name(nameItem.as()->qName()); + const QString value(processValue(name, content)); + const NodeBuilder::Ptr nodeBuilder(context->nodeBuilder(QUrl())); + + nodeBuilder->attribute(name, QStringRef(&value)); + + const QAbstractXmlNodeModel::Ptr nm(nodeBuilder->builtDocument()); + context->addNodeModel(nm); + return nm->root(QXmlNodeModelIndex()); +} + +void AttributeConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const +{ + QAbstractXmlReceiver *const receiver = context->outputReceiver(); + const Item nameItem(m_operand1->evaluateSingleton(context)); + + const Item content(m_operand2->evaluateSingleton(context)); + const QXmlName name(nameItem.as()->qName()); + const QString value(processValue(name, content)); + + receiver->attribute(name, QStringRef(&value)); +} + +SequenceType::Ptr AttributeConstructor::staticType() const +{ + return CommonSequenceTypes::ExactlyOneAttribute; +} + +SequenceType::List AttributeConstructor::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ExactlyOneQName); + result.append(CommonSequenceTypes::ZeroOrMoreItems); + return result; +} + +Expression::Properties AttributeConstructor::properties() const +{ + return DisableElimination | IsNodeConstructor; +} + +ExpressionVisitorResult::Ptr +AttributeConstructor::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +Expression::ID AttributeConstructor::id() const +{ + return IDAttributeConstructor; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qattributeconstructor_p.h b/src/xmlpatterns/expr/qattributeconstructor_p.h new file mode 100644 index 0000000..055ad7f --- /dev/null +++ b/src/xmlpatterns/expr/qattributeconstructor_p.h @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_AttributeConstructor_H +#define Patternist_AttributeConstructor_H + +#include "qpaircontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Constructs an element node. This covers both computed and directly constructed + * element nodes. + * + * @see XQuery + * 1.0: An XML Query Language, 3.7 Constructors + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class AttributeConstructor : public PairContainer + { + public: + AttributeConstructor(const Expression::Ptr &operand1, + const Expression::Ptr &operand2); + + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const; + + virtual SequenceType::Ptr staticType() const; + + /** + * The first operand must be exactly one @c xs:QName, and the second + * argument can be zero or more items. + */ + virtual SequenceType::List expectedOperandTypes() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + + /** + * @returns always IDAttributeConstructor. + */ + virtual ID id() const; + + virtual Properties properties() const; + + private: + static inline QString processValue(const QXmlName name, + const Item &value); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qattributenamevalidator.cpp b/src/xmlpatterns/expr/qattributenamevalidator.cpp new file mode 100644 index 0000000..1625bc1 --- /dev/null +++ b/src/xmlpatterns/expr/qattributenamevalidator.cpp @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" +#include "qcommonnamespaces_p.h" +#include "qcommonsequencetypes_p.h" +#include "qpatternistlocale_p.h" +#include "qqnamevalue_p.h" +#include "qatomicstring_p.h" + +#include "qattributenamevalidator_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +AttributeNameValidator::AttributeNameValidator(const Expression::Ptr &source) : SingleContainer(source) +{ +} + +Item AttributeNameValidator::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item name(m_operand->evaluateSingleton(context)); + const QXmlName qName(name.as()->qName()); + + if(qName.namespaceURI() == StandardNamespaces::xmlns) + { + context->error(QtXmlPatterns::tr("The namespace URI in the name for a " + "computed attribute cannot be %1.") + .arg(formatURI(CommonNamespaces::XMLNS)), + ReportContext::XQDY0044, this); + return Item(); /* Silence warning. */ + } + else if(qName.namespaceURI() == StandardNamespaces::empty && + qName.localName() == StandardLocalNames::xmlns) + { + context->error(QtXmlPatterns::tr("The name for a computed attribute " + "cannot have the namespace URI %1 " + "with the local name %2.") + .arg(formatURI(CommonNamespaces::XMLNS)) + .arg(formatKeyword("xmlns")), + ReportContext::XQDY0044, this); + return Item(); /* Silence warning. */ + } + else if(!qName.hasPrefix() && qName.hasNamespace()) + { + return Item(QNameValue::fromValue(context->namePool(), + QXmlName(qName.namespaceURI(), qName.localName(), StandardPrefixes::ns0))); + } + else + return name; +} + +SequenceType::Ptr AttributeNameValidator::staticType() const +{ + return m_operand->staticType(); +} + +SequenceType::List AttributeNameValidator::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ExactlyOneQName); + return result; +} + +ExpressionVisitorResult::Ptr AttributeNameValidator::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qattributenamevalidator_p.h b/src/xmlpatterns/expr/qattributenamevalidator_p.h new file mode 100644 index 0000000..ddf05ec --- /dev/null +++ b/src/xmlpatterns/expr/qattributenamevalidator_p.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_AttributeNameValidator_H +#define Patternist_AttributeNameValidator_H + +#include "qsinglecontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Ensures the lexical space of the string value of the Item returned + * from its child Expression is an NCName. Also possibly changes the name + * by generating a prefix if one is needed. + * + * @note It doesn't actually construct an @c xs:NCName. It only ensures the lexical + * space is an @c NCName. The atomic value can be of any string type, such as @c xs:untypedAtomic + * of @c xs:string. + * + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class AttributeNameValidator : public SingleContainer + { + public: + AttributeNameValidator(const Expression::Ptr &source); + + virtual Item evaluateSingleton(const DynamicContext::Ptr &) const; + + virtual SequenceType::List expectedOperandTypes() const; + + /** + * @returns the static type of its operand. This is returned as opposed + * CommonSequenceTypes::ExactlyOneQName, since the operand might return a subtype + * of @c xs:QName. + */ + virtual SequenceType::Ptr staticType() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qaxisstep.cpp b/src/xmlpatterns/expr/qaxisstep.cpp new file mode 100644 index 0000000..40fe694 --- /dev/null +++ b/src/xmlpatterns/expr/qaxisstep.cpp @@ -0,0 +1,247 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" +#include "qcommonsequencetypes_p.h" +#include "qitemmappingiterator_p.h" +#include "qgenericsequencetype_p.h" +#include "qparentnodeaxis_p.h" + +#include "qaxisstep_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +namespace QPatternist +{ + /** + * This operator is needed for the s_whenAxisNodeKindEmpty array. The @c int constructors + * ensure we invoke another operator| such that we don't get an infinite loop. + */ + static inline QXmlNodeModelIndex::NodeKind operator|(const QXmlNodeModelIndex::NodeKind &op1, const QXmlNodeModelIndex::NodeKind &op2) + { + return QXmlNodeModelIndex::NodeKind(int(op1) | int(op2)); + } +} + +/** + * @note The order is significant. It is of the same order as the values in QXmlNodeModelIndex::Axis is declared. + */ +const QXmlNodeModelIndex::NodeKind AxisStep::s_whenAxisNodeKindEmpty[] = +{ + QXmlNodeModelIndex::Attribute|QXmlNodeModelIndex::Text|QXmlNodeModelIndex::ProcessingInstruction|QXmlNodeModelIndex::Comment|QXmlNodeModelIndex::Namespace, // child; + QXmlNodeModelIndex::Attribute|QXmlNodeModelIndex::Text|QXmlNodeModelIndex::ProcessingInstruction|QXmlNodeModelIndex::Comment|QXmlNodeModelIndex::Namespace, // descendant; + QXmlNodeModelIndex::Document|QXmlNodeModelIndex::Attribute|QXmlNodeModelIndex::Text|QXmlNodeModelIndex::ProcessingInstruction|QXmlNodeModelIndex::Comment|QXmlNodeModelIndex::Namespace,// attribute; + QXmlNodeModelIndex::NodeKind(0), // self; + QXmlNodeModelIndex::NodeKind(0), // descendant-or-self; + QXmlNodeModelIndex::Document|QXmlNodeModelIndex::Attribute|QXmlNodeModelIndex::Text|QXmlNodeModelIndex::ProcessingInstruction|QXmlNodeModelIndex::Comment|QXmlNodeModelIndex::Namespace, // namespace; + QXmlNodeModelIndex::Document, // following; + QXmlNodeModelIndex::Document, // parent; + QXmlNodeModelIndex::Document, // ancestor + QXmlNodeModelIndex::Document|QXmlNodeModelIndex::Attribute|QXmlNodeModelIndex::Namespace, // preceding-sibling; + QXmlNodeModelIndex::Document|QXmlNodeModelIndex::Attribute|QXmlNodeModelIndex::Namespace, // following-sibling; + QXmlNodeModelIndex::Document, // preceding; + QXmlNodeModelIndex::NodeKind(0) // ancestor-or-self; +}; + +bool AxisStep::isAlwaysEmpty(const QXmlNodeModelIndex::Axis axis, const QXmlNodeModelIndex::NodeKind nodeKind) +{ + return (s_whenAxisNodeKindEmpty[(1 >> axis) - 1] & nodeKind) != 0; +} + +AxisStep::AxisStep(const QXmlNodeModelIndex::Axis a, + const ItemType::Ptr &nt) : m_axis(a), + m_nodeTest(nt) +{ + Q_ASSERT(m_nodeTest); + Q_ASSERT_X(BuiltinTypes::node->xdtTypeMatches(m_nodeTest), Q_FUNC_INFO, + "We assume we're a node type."); +} + +Item AxisStep::mapToItem(const QXmlNodeModelIndex &node, + const DynamicContext::Ptr &context) const +{ + Q_ASSERT(!node.isNull()); + Q_ASSERT(Item(node).isNode()); + Q_ASSERT(Item(node)); + Q_UNUSED(context); + + if(m_nodeTest->itemMatches(Item(node))) + return Item(node); + else + return Item(); +} + +Item::Iterator::Ptr AxisStep::evaluateSequence(const DynamicContext::Ptr &context) const +{ + /* If we don't have a focus, it's either a bug or our parent isn't a Path + * that have advanced the focus iterator. Hence, attempt to advance the focus on our own. */ + if(!context->contextItem()) + context->focusIterator()->next(); + + Q_ASSERT(context->contextItem()); + + const QXmlNodeModelIndex::Iterator::Ptr source(context->contextItem().asNode().iterate(m_axis)); + + return makeItemMappingIterator(ConstPtr(this), source, context); +} + +Item AxisStep::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + /* If we don't have a focus, it's either a bug or our parent isn't a Path + * that have advanced the focus iterator. Hence, attempt to advance the focus on our own. */ + if(!context->contextItem()) + context->focusIterator()->next(); + + Q_ASSERT(context->contextItem()); + + const QXmlNodeModelIndex::Iterator::Ptr it(context->contextItem().asNode().iterate(m_axis)); + QXmlNodeModelIndex next(it->next()); + + while(!next.isNull()) + { + const Item candidate(mapToItem(next, context)); + + if(candidate) + return candidate; + else + next = it->next(); + }; + + return Item(); +} + +Expression::Ptr AxisStep::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + if(m_axis == QXmlNodeModelIndex::AxisParent && *m_nodeTest == *BuiltinTypes::node) + { + /* We only rewrite parent::node() to ParentNodeAxis. */ + return rewrite(Expression::Ptr(new ParentNodeAxis()), context)->typeCheck(context, reqType); + } + /* TODO temporarily disabled + else if(isAlwaysEmpty(m_axis, static_cast(m_nodeTest.data())->nodeKind())) + return EmptySequence::create(this, context); + */ + else + return EmptyContainer::typeCheck(context, reqType); +} + +SequenceType::Ptr AxisStep::staticType() const +{ + Cardinality cardinality; + + if(m_axis == QXmlNodeModelIndex::AxisSelf || m_axis == QXmlNodeModelIndex::AxisParent) + cardinality = Cardinality::zeroOrOne(); + else + cardinality = Cardinality::zeroOrMore(); + + return makeGenericSequenceType(m_nodeTest, + cardinality); +} + +SequenceType::List AxisStep::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ZeroOrMoreNodes); + return result; +} + +Expression::Properties AxisStep::properties() const +{ + return RequiresContextItem | DisableElimination; +} + +ItemType::Ptr AxisStep::expectedContextItemType() const +{ + return BuiltinTypes::node; +} + +ExpressionVisitorResult::Ptr AxisStep::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +QXmlNodeModelIndex::Axis AxisStep::axis() const +{ + return m_axis; +} + +QString AxisStep::axisName(const QXmlNodeModelIndex::Axis axis) +{ + const char *result = 0; + + switch(axis) + { + /* These must not be translated. */ + case QXmlNodeModelIndex::AxisAncestorOrSelf: result = "ancestor-or-self"; break; + case QXmlNodeModelIndex::AxisAncestor: result = "ancestor"; break; + case QXmlNodeModelIndex::AxisAttributeOrTop: result = "attribute-or-top"; break; + case QXmlNodeModelIndex::AxisAttribute: result = "attribute"; break; + case QXmlNodeModelIndex::AxisChildOrTop: result = "child-or-top"; break; + case QXmlNodeModelIndex::AxisChild: result = "child"; break; + case QXmlNodeModelIndex::AxisDescendantOrSelf: result = "descendant-or-self"; break; + case QXmlNodeModelIndex::AxisDescendant: result = "descendant"; break; + case QXmlNodeModelIndex::AxisFollowing: result = "following"; break; + case QXmlNodeModelIndex::AxisFollowingSibling: result = "following-sibling"; break; + case QXmlNodeModelIndex::AxisNamespace: result = "namespace"; break; + case QXmlNodeModelIndex::AxisParent: result = "parent"; break; + case QXmlNodeModelIndex::AxisPreceding: result = "preceding"; break; + case QXmlNodeModelIndex::AxisPrecedingSibling: result = "preceding-sibling"; break; + case QXmlNodeModelIndex::AxisSelf: result = "self"; break; + } + + Q_ASSERT_X(result, Q_FUNC_INFO, "An unknown axis type was apparently encountered."); + return QString::fromLatin1(result); +} + +PatternPriority AxisStep::patternPriority() const +{ + return static_cast(m_nodeTest.data())->patternPriority(); +} + +Expression::ID AxisStep::id() const +{ + return IDAxisStep; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qaxisstep_p.h b/src/xmlpatterns/expr/qaxisstep_p.h new file mode 100644 index 0000000..8f2ae27 --- /dev/null +++ b/src/xmlpatterns/expr/qaxisstep_p.h @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_AxisStep_H +#define Patternist_AxisStep_H + +#include "qemptycontainer_p.h" +#include "qitem_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A step in a path expression that with an axis and a node test evaluates + * to a sequence of nodes from the context item. + * + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class Q_AUTOTEST_EXPORT AxisStep : public EmptyContainer + { + public: + AxisStep(const QXmlNodeModelIndex::Axis axis, + const ItemType::Ptr &nodeTest); + + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &) const; + virtual Item evaluateSingleton(const DynamicContext::Ptr &) const; + + /** + * Returns @p node if it matches the node test this step is using, otherwise @c null. + */ + inline Item mapToItem(const QXmlNodeModelIndex &node, + const DynamicContext::Ptr &context) const; + + virtual SequenceType::List expectedOperandTypes() const; + virtual SequenceType::Ptr staticType() const; + + /** + * Rewrites to ParentNodeAxis, if possible. + */ + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + /** + * @returns always BuiltinTypes::node; + */ + virtual ItemType::Ptr expectedContextItemType() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + + virtual Properties properties() const; + + /** + * @returns the axis this step is using. + */ + QXmlNodeModelIndex::Axis axis() const; + + /** + * @returns the node test this step is using. + */ + inline ItemType::Ptr nodeTest() const + { + return m_nodeTest; + } + + void setNodeTest(const ItemType::Ptr &nev) + { + m_nodeTest = nev; + } + + /** + * @short Prints the EBNF name corresponding to @p axis. + * + * For instance, for QXmlNodeModelIndex::Child, "child" is returned. + * + * Apart from being used in this class, it is used in the SDK. + */ + static QString axisName(const QXmlNodeModelIndex::Axis axis); + + virtual ID id() const; + virtual PatternPriority patternPriority() const; + + inline void setAxis(const QXmlNodeModelIndex::Axis newAxis); + + private: + typedef QExplicitlySharedDataPointer ConstPtr; + + static const QXmlNodeModelIndex::NodeKind s_whenAxisNodeKindEmpty[]; + + /** + * @returns @c true when the axis @p axis and a node test testing node of + * type @p nodeKind always produces an empty sequence. One such example + * is attribute::comment(). + */ + static bool isAlwaysEmpty(const QXmlNodeModelIndex::Axis axis, + const QXmlNodeModelIndex::NodeKind nodeKind); + + /** + * The reason this variable is mutable, is that in the case of XSL-T patterns, + * we do quite some reordering. + */ + QXmlNodeModelIndex::Axis m_axis; + ItemType::Ptr m_nodeTest; + }; + + void AxisStep::setAxis(const QXmlNodeModelIndex::Axis newAxis) + { + m_axis = newAxis; + } + +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qcachecells_p.h b/src/xmlpatterns/expr/qcachecells_p.h new file mode 100644 index 0000000..ec9ea8e --- /dev/null +++ b/src/xmlpatterns/expr/qcachecells_p.h @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_CacheCells_H +#define Patternist_CacheCells_H + +#include +#include + +#include "qitem_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Represents a cache entry for a single Item, + * as opposed to for a sequence of items. + * + * A characteristic of the ItemCacheCell is that it has two states: + * either its full or it's not, since it only deals with a single + * item. + * + * Remember that cachedItem doesn't tell the state of the ItemCacheCell. + * For instance, it can have a null pointer, the empty sequence, and that + * can be the value of its cache. + * + * @author Frans Englich + */ + class ItemCacheCell + { + public: + typedef QList List; + typedef QVector Vector; + enum CacheState + { + Full, + Empty + }; + + inline ItemCacheCell() : cacheState(Empty) + { + } + + Item cachedItem; + CacheState cacheState; + }; + + /** + * @short Represents a cache entry for a sequence of items. + * + * As opposed to ItemCacheCell, ItemSequenceCacheCell can be partially + * populated: e.g, four items is in the cache while three remains in the + * source. For that reason ItemSequenceCacheCell in addition to the source + * also carried an QAbstractXmlForwardIterator which is the source, such + * that it can continue to populate the cache when it runs out. + * + * @author Frans Englich + */ + class ItemSequenceCacheCell + { + public: + typedef QList List; + typedef QVector Vector; + + enum CacheState + { + Full, + Empty, + PartiallyPopulated + }; + + inline ItemSequenceCacheCell() : cacheState(Empty) + , inUse(false) + { + } + + Item::List cachedItems; + Item::Iterator::Ptr sourceIterator; + CacheState cacheState; + /** + * In XSL-T, we can have circularity which we cannot detect statically. + * For instance, a global variable invokes a template, and the template + * uses the variable. We can't detect that, because we can't figure out + * what template will be invoked. + * + * For solution we have this toggle, which is set temporarily on the + * cell such that EvaluationCache can detect whether it's trashing + * itself. + * + * One might think that it would be sufficient to flag usage of the + * variable in an arbitrary template, but that would also flag valid + * cases. + */ + bool inUse; + }; +} + +Q_DECLARE_TYPEINFO(QPatternist::ItemCacheCell, Q_MOVABLE_TYPE); +Q_DECLARE_TYPEINFO(QPatternist::ItemSequenceCacheCell, Q_MOVABLE_TYPE); + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qcallsite.cpp b/src/xmlpatterns/expr/qcallsite.cpp new file mode 100644 index 0000000..7137bb4 --- /dev/null +++ b/src/xmlpatterns/expr/qcallsite.cpp @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcallsite_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +CallSite::CallSite(const QXmlName &name) : m_isRecursive(false) + , m_name(name) +{ +} + +QXmlName CallSite::name() const +{ + return m_name; +} + +bool CallSite::isRecursive() const +{ + return m_isRecursive; +} + +void CallSite::setIsRecursive(const bool value) +{ + m_isRecursive = value; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qcallsite_p.h b/src/xmlpatterns/expr/qcallsite_p.h new file mode 100644 index 0000000..6c0013c --- /dev/null +++ b/src/xmlpatterns/expr/qcallsite_p.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_CallSite_H +#define Patternist_CallSite_H + +#include "qunlimitedcontainer_p.h" +#include "qcalltargetdescription_p.h" +#include "qxmlname.h" + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Abstract base-class for Expression instances that are callsites + * to other components, such as templates or user functions. + * + * @author Frans Englich + * @ingroup Patternist_expressions + * @since 4.5 + */ + class CallSite : public UnlimitedContainer + { + public: + QXmlName name() const; + bool isRecursive() const; + void setIsRecursive(const bool value); + + /** + * Called in the earliest stages of the compilation process. @p sign can + * be any function signature for a user declared function. If @p sign + * matches this UserFunctionCallsite, it means the UserFunction represented + * by @p sign is recursive and that this UserFunctionCallsite should take + * appropriate measures. + * + * @returns @c true if is recursive, otherwise @c false + */ + virtual bool configureRecursion(const CallTargetDescription::Ptr &sign) = 0; + + /** + * @short Returns the body of the function/template/component that is + * being called. + */ + virtual Expression::Ptr body() const = 0; + + virtual CallTargetDescription::Ptr callTargetDescription() const = 0; + + protected: + CallSite(const QXmlName &name = QXmlName()); + + private: + Q_DISABLE_COPY(CallSite) + bool m_isRecursive; + const QXmlName m_name; + }; +} + +QT_END_NAMESPACE +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qcalltargetdescription.cpp b/src/xmlpatterns/expr/qcalltargetdescription.cpp new file mode 100644 index 0000000..0e14469 --- /dev/null +++ b/src/xmlpatterns/expr/qcalltargetdescription.cpp @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcallsite_p.h" + +#include "qcalltargetdescription_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +CallTargetDescription::CallTargetDescription(const QXmlName &name) : m_name(name) +{ + Q_ASSERT(!m_name.isNull()); +} + +QXmlName CallTargetDescription::name() const +{ + return m_name; +} + +void CallTargetDescription::checkArgumentsCircularity(CallTargetDescription::List &signList, + const Expression::Ptr callsite) +{ + /* Check the arguments. */ + const Expression::List ops(callsite->operands()); + const Expression::List::const_iterator end(ops.constEnd()); + Expression::List::const_iterator it(ops.constBegin()); + + for(; it != end; ++it) + checkCallsiteCircularity(signList, *it); +} + +void CallTargetDescription::checkCallsiteCircularity(CallTargetDescription::List &signList, + const Expression::Ptr expr) +{ + Q_ASSERT(expr); + + if(expr->is(Expression::IDUserFunctionCallsite)) + { + CallTargetDescription::List::const_iterator it(signList.constBegin()); + const CallTargetDescription::List::const_iterator end(signList.constEnd()); + CallSite *const callsite = static_cast(expr.data()); + + for(; it != end; ++it) + { + if(callsite->configureRecursion(*it)) + { + /* A callsite inside the function body to the function. This user function + * is recursive if it's to the same function, in other words. Which it was + * if configureRecursion() returned true. */ + + /* Now we continue and check the arguments of the callsite. That is, the arguments. + * This catches for instance local:foo(local:foo(3)). */ + checkArgumentsCircularity(signList, expr); + return; + } + } + /* Check the body of the function so this callsite isn't "indirectly" a + * recursive call to the function we're checking. XQTS test case + * default_namespace-011 is an example of this. */ + signList.append(callsite->callTargetDescription()); + checkCallsiteCircularity(signList, callsite->body()); + } + + checkArgumentsCircularity(signList, expr); /* We're done in this case. */ +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qcalltargetdescription_p.h b/src/xmlpatterns/expr/qcalltargetdescription_p.h new file mode 100644 index 0000000..ac614be --- /dev/null +++ b/src/xmlpatterns/expr/qcalltargetdescription_p.h @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_CallTargetDescription_H +#define Patternist_CallTargetDescription_H + +template class QHash; +template class QList; + +#include + +#include "qexpression_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + class CallSite; + + /** + * @short Contains metadata for a callable component, such as a function or + * template. + * + * CallTargetDescription can be used directly and is so for templates, but + * can also be sub-classed which FunctionSignature do. + * + * @ingroup Patternist_expr + * @author Frans Englich + */ + class Q_AUTOTEST_EXPORT CallTargetDescription : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer Ptr; + typedef QList List; + + CallTargetDescription(const QXmlName &name); + + /** + * The function's name. For example, the name of the signature + * fn:string() as xs:string is fn:string. + */ + QXmlName name() const; + + /** + * Flags callsites to be aware of their recursion by calling + * UserFunctionCallsite::configureRecursion(), if that is the case. + * + * @note We pass @p expr by value here intentionally. + */ + static void checkCallsiteCircularity(CallTargetDescription::List &signList, + const Expression::Ptr expr); + private: + /** + * Helper function for checkCallsiteCircularity(). If C++ allowed it, + * it would have been local to it. + */ + static void checkArgumentsCircularity(CallTargetDescription::List &signList, + const Expression::Ptr callsite); + + Q_DISABLE_COPY(CallTargetDescription) + const QXmlName m_name; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif + diff --git a/src/xmlpatterns/expr/qcalltemplate.cpp b/src/xmlpatterns/expr/qcalltemplate.cpp new file mode 100644 index 0000000..f16ffcf --- /dev/null +++ b/src/xmlpatterns/expr/qcalltemplate.cpp @@ -0,0 +1,153 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonsequencetypes_p.h" + +#include "qcalltemplate_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +CallTemplate::CallTemplate(const QXmlName &name, + const WithParam::Hash &withParams) : TemplateInvoker(withParams, name) +{ +} + +Item::Iterator::Ptr CallTemplate::evaluateSequence(const DynamicContext::Ptr &context) const +{ + Q_ASSERT(m_template); + return m_template->body->evaluateSequence(m_template->createContext(this, context, true)); +} + +bool CallTemplate::evaluateEBV(const DynamicContext::Ptr &context) const +{ + Q_ASSERT(m_template); + return m_template->body->evaluateEBV(m_template->createContext(this, context, true)); +} + +void CallTemplate::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const +{ + Q_ASSERT(m_template); + m_template->body->evaluateToSequenceReceiver(m_template->createContext(this, context, true)); +} + +Expression::Ptr CallTemplate::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + /* Check XTSE0680, that every @c xsl:with-param has a corresponding @c + * xsl:param declaration. */ + { + const WithParam::Hash::const_iterator end(m_withParams.constEnd()); + + for(WithParam::Hash::const_iterator it(m_withParams.constBegin()); + it != end; + ++it) + { + if(!VariableDeclaration::contains(m_template->templateParameters, it.value()->name())) + Template::raiseXTSE0680(context, it.value()->name(), this); + } + } + + const Expression::Ptr me(TemplateInvoker::typeCheck(context, reqType)); + + const VariableDeclaration::List args(m_template->templateParameters); + const VariableDeclaration::List::const_iterator end(args.constEnd()); + VariableDeclaration::List::const_iterator it(args.constBegin()); + + for(; it != end; ++it) + { + // TODO + Q_ASSERT((*it)->sequenceType); + } + + return me; +} + +Expression::Properties CallTemplate::properties() const +{ + Q_ASSERT(!m_template || m_template->body); + + /* We may be called before our m_template is resolved, namely when we're + * the body of a variable. In that case querytransformparser.ypp will + * manually call TypeChecker::applyFunctionConversion(), which is before + * ExpressionFactory::createExpression() has resolved us. */ + if(m_template && !isRecursive()) + return m_template->properties(); + else + return Properties(); +} + +Expression::Properties CallTemplate::dependencies() const +{ + if(m_template && !isRecursive()) + return m_template->dependencies(); + else + return Properties(); +} + +SequenceType::Ptr CallTemplate::staticType() const +{ + return CommonSequenceTypes::ZeroOrMoreItems; +} + +ExpressionVisitorResult::Ptr CallTemplate::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +bool CallTemplate::configureRecursion(const CallTargetDescription::Ptr &sign) +{ + Q_UNUSED(sign); + return false; +} + +Expression::Ptr CallTemplate::body() const +{ + return m_template->body; +} + +CallTargetDescription::Ptr CallTemplate::callTargetDescription() const +{ + return CallTargetDescription::Ptr(); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qcalltemplate_p.h b/src/xmlpatterns/expr/qcalltemplate_p.h new file mode 100644 index 0000000..df67121 --- /dev/null +++ b/src/xmlpatterns/expr/qcalltemplate_p.h @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_CallTemplate_H +#define Patternist_CallTemplate_H + +#include "qcallsite_p.h" +#include "qtemplateinvoker_p.h" +#include "qtemplate_p.h" + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements @c xsl:call-template. + * + * @since 4.5 + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class CallTemplate : public TemplateInvoker + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + CallTemplate(const QXmlName &name, + const WithParam::Hash &withParams); + + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + virtual bool evaluateEBV(const DynamicContext::Ptr &context) const; + virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const; + + virtual SequenceType::Ptr staticType() const; + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + virtual Properties properties() const; + virtual Properties dependencies() const; + + /** + * This is a bit complicated by that we have two required types, one + * specified by @c xsl:param in the template declaration, and one on @c + * xsl:with-param. + * + * @see UserFunctionCallsite::expectedOperandTypes() + * @see XSL + * Transformations (XSLT) Version 2.0, 10.1.1 Passing Parameters to Templates + */ + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + + inline void setTemplate(const Template::Ptr &templ) + { + m_template = templ; + } + + virtual bool configureRecursion(const CallTargetDescription::Ptr &sign); + virtual Expression::Ptr body() const; + virtual CallTargetDescription::Ptr callTargetDescription() const; + private: + Template::Ptr m_template; + }; +} + +QT_END_NAMESPACE +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qcastableas.cpp b/src/xmlpatterns/expr/qcastableas.cpp new file mode 100644 index 0000000..65b5305 --- /dev/null +++ b/src/xmlpatterns/expr/qcastableas.cpp @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qatomictype_p.h" +#include "qitem_p.h" +#include "qboolean_p.h" +#include "qbuiltintypes_p.h" +#include "qcommonsequencetypes_p.h" +#include "qcommonvalues_p.h" +#include "qliteral_p.h" + +#include "qcastableas_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +CastableAs::CastableAs(const Expression::Ptr &operand, + const SequenceType::Ptr &tType) : SingleContainer(operand), + m_targetType(tType) +{ + Q_ASSERT(tType); + Q_ASSERT(!tType->cardinality().allowsMany()); + Q_ASSERT(tType->itemType()->isAtomicType()); +} + +bool CastableAs::evaluateEBV(const DynamicContext::Ptr &context) const +{ + Item item; + + if(m_operand->staticType()->cardinality().allowsMany()) + { + const Item::Iterator::Ptr it(m_operand->evaluateSequence(context)); + item = it->next(); + + if(it->next()) + return false; + } + else + item = m_operand->evaluateSingleton(context); + + if(item) + return !cast(item, context).as()->hasError(); + else + return m_targetType->cardinality().allowsEmpty(); +} + +Expression::Ptr CastableAs::compress(const StaticContext::Ptr &context) +{ + const Expression::Ptr me(SingleContainer::compress(context)); + + if(me != this) /* We already managed to const fold, how convenient. */ + return me; + + const AtomicType::Ptr t(m_targetType->itemType()); + + const SequenceType::Ptr opType(m_operand->staticType()); + + /* Casting to these always succeeds, assuming the cardinality also matches, + * although the cardinality can fail. */ + if(( *t == *BuiltinTypes::xsString + || *t == *BuiltinTypes::xsUntypedAtomic + || *t == *opType->itemType()) + &&(m_targetType->cardinality().isMatch(opType->cardinality()))) + { + return wrapLiteral(CommonValues::BooleanTrue, context, this); + } + else + return me; +} + +Expression::Ptr CastableAs::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + checkTargetType(context); + const Expression::Ptr me(SingleContainer::typeCheck(context, reqType)); + + return me; + if(BuiltinTypes::xsQName->xdtTypeMatches(m_targetType->itemType())) + { + const SequenceType::Ptr seqt(m_operand->staticType()); + /* We can cast a string literal, an xs:QName value, and an + * empty sequence(if empty is allowed), to xs:QName. */ + if(m_operand->is(IDStringValue) || + BuiltinTypes::xsQName->xdtTypeMatches(seqt->itemType()) || + (*seqt->itemType() == *CommonSequenceTypes::Empty && m_targetType->cardinality().allowsEmpty())) + { + return wrapLiteral(CommonValues::BooleanTrue, context, this)->typeCheck(context, reqType); + } + else + return wrapLiteral(CommonValues::BooleanFalse, context, this)->typeCheck(context, reqType); + } + else + { + /* Let the CastingPlatform look up its AtomicCaster. */ + prepareCasting(context, m_operand->staticType()->itemType()); + + return me; + } +} + +SequenceType::List CastableAs::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ZeroOrMoreAtomicTypes); + return result; +} + +SequenceType::Ptr CastableAs::staticType() const +{ + return CommonSequenceTypes::ExactlyOneBoolean; +} + +ExpressionVisitorResult::Ptr CastableAs::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qcastableas_p.h b/src/xmlpatterns/expr/qcastableas_p.h new file mode 100644 index 0000000..fe216b1 --- /dev/null +++ b/src/xmlpatterns/expr/qcastableas_p.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_CastableAs_H +#define Patternist_CastableAs_H + +#include "qsinglecontainer_p.h" +#include "qcastingplatform_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Implements XPath 2.0's castable as expression. + * + * @see XML Path Language + * (XPath) 2.0, 3.10.3 Castable + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class CastableAs : public SingleContainer, + public CastingPlatform + { + public: + CastableAs(const Expression::Ptr &operand, + const SequenceType::Ptr &targetType); + + virtual bool evaluateEBV(const DynamicContext::Ptr &) const; + + /** + * Overridden to const fold to @c true when the target type + * is a type which casting to always succeeds. This is + * the type identical to the target type, xs:string, + * and xs:untypedAtomic. + */ + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + virtual SequenceType::List expectedOperandTypes() const; + virtual SequenceType::Ptr staticType() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + + inline ItemType::Ptr targetType() const + { + return m_targetType->itemType(); + } + + private: + const SequenceType::Ptr m_targetType; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qcastas.cpp b/src/xmlpatterns/expr/qcastas.cpp new file mode 100644 index 0000000..741d052 --- /dev/null +++ b/src/xmlpatterns/expr/qcastas.cpp @@ -0,0 +1,204 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qitem_p.h" +#include "qbuiltintypes_p.h" +#include "qcardinalityverifier_p.h" +#include "qcommonsequencetypes_p.h" +#include "qemptysequence_p.h" +#include "qgenericsequencetype_p.h" +#include "qliteral_p.h" +#include "qpatternistlocale_p.h" +#include "qnamespaceresolver_p.h" +#include "qqnameconstructor_p.h" +#include "qqnamevalue_p.h" +#include "qatomicstring_p.h" +#include "qvalidationerror_p.h" + +#include "qcastas_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +CastAs::CastAs(const Expression::Ptr &source, + const SequenceType::Ptr &tType) : SingleContainer(source), + m_targetType(tType) +{ + Q_ASSERT(source); + Q_ASSERT(tType); + Q_ASSERT(!tType->cardinality().allowsMany()); + Q_ASSERT(tType->itemType()->isAtomicType()); +} + +Item CastAs::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + Q_ASSERT(context); + const Item val(m_operand->evaluateSingleton(context)); + + if(val) + return cast(val, context); + else + { + /* No item supplied, let's handle the cardinality part. */ + + if(m_targetType->cardinality().allowsEmpty()) + return Item(); + else + { + Q_ASSERT(context); + context->error(QtXmlPatterns::tr("Type error in cast, expected %1, " + "received %2.") + .arg(formatType(Cardinality::exactlyOne())) + .arg(formatType(Cardinality::empty())), + ReportContext::XPTY0004, this); + return Item(); + } + } +} + +Expression::Ptr CastAs::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + checkTargetType(context); + const SequenceType::Ptr seqt(m_operand->staticType()); + ItemType::Ptr t(seqt->itemType()); + + /* Special case xs:QName */ + if(BuiltinTypes::xsQName->xdtTypeMatches(m_targetType->itemType())) + { + /* Ok, We're casting to xs:QName. */ + if(m_operand->is(IDStringValue)) /* A valid combination, let's do the cast. */ + return castToQName(context)->typeCheck(context, reqType); + else if(BuiltinTypes::xsQName->xdtTypeMatches(t)) + return m_operand->typeCheck(context, reqType); + else if(seqt->cardinality().isEmpty() && m_targetType->cardinality().allowsEmpty()) + return EmptySequence::create(this, context); + else if(!(seqt->cardinality().isEmpty() && !m_targetType->cardinality().allowsEmpty())) + { + context->error(QtXmlPatterns::tr("When casting to %1 or types " + "derived from it, the source " + "value must be of the same type, " + "or it must be a string literal. " + "Type %2 is not allowed.") + .arg(formatType(context->namePool(), BuiltinTypes::xsQName)) + .arg(formatType(context->namePool(), seqt)), + ReportContext::XPTY0004, this); + return Expression::Ptr(this); + } + } + + const Expression::Ptr me(SingleContainer::typeCheck(context, reqType)); + /* Type may have changed, such as that atomization has been applied. */ + t = m_operand->staticType()->itemType(); + + if(m_targetType->itemType()->xdtTypeMatches(t) && + !BuiltinTypes::xsDayTimeDuration->xdtTypeMatches(t) && + !BuiltinTypes::xsYearMonthDuration->xdtTypeMatches(t)) + { /* At least casting is superflorous. */ + if(m_operand->staticType()->cardinality().isMatch(m_targetType->cardinality())) + return m_operand; /* The whole cast expression is redundant. */ + else + { /* Only cardinality check is needed, rewrite to CardinalityVerifier. */ + return Expression::Ptr(new CardinalityVerifier(m_operand, + m_targetType->cardinality(), + ReportContext::FORG0001)); + } + } + + /* Let the CastingPlatform look up its AtomicCaster. */ + prepareCasting(context, t); + + return me; +} + +Expression::Ptr CastAs::compress(const StaticContext::Ptr &context) +{ + /* Simplify casts to itself. */ + if(*m_targetType->itemType() == *m_operand->staticType()->itemType()) + return m_operand->compress(context); + else + return SingleContainer::compress(context); +} + +Expression::Ptr CastAs::castToQName(const StaticContext::Ptr &context) const +{ + /* Apply the whitespace facet by calling trimmed(). */ + /* We can assume m_operand is an Expression because this is a requirement + * for casting to xs:QName. */ + const QString lexQName(m_operand->as()->item().as()->stringValue().trimmed()); + + const QXmlName + expName(QNameConstructor::expandQName(lexQName, + context, + context->namespaceBindings(), this)); + return wrapLiteral(toItem(QNameValue::fromValue(context->namePool(), expName)), context, this); +} + +SequenceType::Ptr CastAs::staticType() const +{ + if(m_operand->staticType()->cardinality().allowsEmpty()) + return m_targetType; + else + return makeGenericSequenceType(m_targetType->itemType(), + Cardinality::exactlyOne()); +} + +SequenceType::List CastAs::expectedOperandTypes() const +{ + SequenceType::List result; + + if(m_targetType->cardinality().allowsEmpty()) + result.append(CommonSequenceTypes::ZeroOrOneAtomicType); + else + result.append(CommonSequenceTypes::ExactlyOneAtomicType); + + return result; +} + +ExpressionVisitorResult::Ptr CastAs::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qcastas_p.h b/src/xmlpatterns/expr/qcastas_p.h new file mode 100644 index 0000000..892b064 --- /dev/null +++ b/src/xmlpatterns/expr/qcastas_p.h @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_CastAs_H +#define Patternist_CastAs_H + +#include "qsinglecontainer_p.h" +#include "qcastingplatform_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements XPath 2.0's cast as expression. + * + * Implements the casting expression, such as '3' cast as xs:integer. This class also + * implements constructor functions, which are created in the ConstructorFunctionsFactory. + * + * CastAs uses CastingPlatform for carrying out the actual casting. + * + * @see XQuery 1.0 + * and XPath 2.0 Functions and Operators, 7 Casting + * @see XML Path Language + * (XPath) 2.0, 3.10.2 Cast + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class CastAs : public SingleContainer, + public CastingPlatform + { + public: + + /** + * @todo Wrong/old documentation + * + * Creates a cast expression for the type @p name via the schema type + * factory @p factory. This function is used by parser when creating + * 'cast to' expressions, and the ConstructorFunctionsFactory, when creating + * constructor functions. + * + * @param targetType the type which the CastAs should cast to + * @param source the operand to evaluate and then cast from + */ + CastAs(const Expression::Ptr &source, + const SequenceType::Ptr &targetType); + + virtual Item evaluateSingleton(const DynamicContext::Ptr &) const; + + virtual SequenceType::List expectedOperandTypes() const; + + /** + * @returns a SequenceType where the ItemType is this CastAs's + * target type, as per targetType(), and the Cardinality is inferred from the + * source operand to reflect whether this CastAs always will evaluate to + * exactly-one or zero-or-one values. + */ + virtual SequenceType::Ptr staticType() const; + + /** + * Overridden in order to check that casting to an abstract type + * is not attempted. + */ + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + /** + * If the target type is the same as the source type, it is rewritten + * to the operand. + */ + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + + inline ItemType::Ptr targetType() const + { + return m_targetType->itemType(); + } + + inline SequenceType::Ptr targetSequenceType() const + { + return m_targetType; + } + + private: + /** + * Performs casting to @c xs:QName. This case is special, and is always done at compile time. + */ + Expression::Ptr castToQName(const StaticContext::Ptr &context) const; + + const SequenceType::Ptr m_targetType; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qcastingplatform.cpp b/src/xmlpatterns/expr/qcastingplatform.cpp new file mode 100644 index 0000000..04b6349 --- /dev/null +++ b/src/xmlpatterns/expr/qcastingplatform.cpp @@ -0,0 +1,221 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/** + * @file + * @short This file is included by qcastingplatform_p.h. + * If you need includes in this file, put them in CasttingPlatform.h, outside of the namespace. + */ + +template +Item CastingPlatform::castWithCaster(const Item &sourceValue, + const AtomicCaster::Ptr &caster, + const ReportContext::Ptr &context) const +{ + Q_ASSERT(sourceValue); + Q_ASSERT(caster); + Q_ASSERT(context); + + const Item retval(caster->castFrom(sourceValue, context)); + + if(issueError) + { + if(retval.template as()->hasError()) + { + issueCastError(retval, sourceValue, context); + return Item(); + } + else + return retval; + } + else + return retval; +} + +template +Item CastingPlatform::cast(const Item &sourceValue, + const ReportContext::Ptr &context) const +{ + Q_ASSERT(sourceValue); + Q_ASSERT(context); + Q_ASSERT(targetType()); + + if(m_caster) + return castWithCaster(sourceValue, m_caster, context); + else + { + bool castImpossible = false; + const AtomicCaster::Ptr caster(locateCaster(sourceValue.type(), context, castImpossible, static_cast(this), targetType())); + + if(!issueError && castImpossible) + { + /* If we're supposed to issue an error(issueError) then this + * line will never be reached, because locateCaster() will in + * that case throw. */ + return ValidationError::createError(); + } + else + return castWithCaster(sourceValue, caster, context); + } +} + +template +bool CastingPlatform::prepareCasting(const ReportContext::Ptr &context, + const ItemType::Ptr &sourceType) +{ + Q_ASSERT(sourceType); + Q_ASSERT(context); + + if(*sourceType == *BuiltinTypes::xsAnyAtomicType || + *sourceType == *BuiltinTypes::item || + *sourceType == *CommonSequenceTypes::Empty || + *sourceType == *BuiltinTypes::numeric) + return true; /* The type could not be narrowed better than xs:anyAtomicType + or numeric at compile time. We'll do lookup at runtime instead. */ + + bool castImpossible = false; + m_caster = locateCaster(sourceType, context, castImpossible, static_cast(this), targetType()); + + return !castImpossible; +} + +template +AtomicCaster::Ptr CastingPlatform::locateCaster(const ItemType::Ptr &sourceType, + const ReportContext::Ptr &context, + bool &castImpossible, + const SourceLocationReflection *const location, + const ItemType::Ptr &targetType) +{ + Q_ASSERT(sourceType); + Q_ASSERT(targetType); + + const AtomicCasterLocator::Ptr locator(static_cast( + targetType.data())->casterLocator()); + if(!locator) + { + if(issueError) + { + context->error(QtXmlPatterns::tr("No casting is possible with %1 as the target type.") + .arg(formatType(context->namePool(), targetType)), + ReportContext::XPTY0004, location); + } + else + castImpossible = true; + + return AtomicCaster::Ptr(); + } + + const AtomicCaster::Ptr caster(static_cast(sourceType.data())->accept(locator, location)); + if(!caster) + { + if(issueError) + { + context->error(QtXmlPatterns::tr("It is not possible to cast from %1 to %2.") + .arg(formatType(context->namePool(), sourceType)) + .arg(formatType(context->namePool(), targetType)), + ReportContext::XPTY0004, location); + } + else + castImpossible = true; + + return AtomicCaster::Ptr(); + } + + return caster; +} + +template +void CastingPlatform::checkTargetType(const ReportContext::Ptr &context) const +{ + Q_ASSERT(context); + + const ItemType::Ptr tType(targetType()); + Q_ASSERT(tType); + Q_ASSERT(tType->isAtomicType()); + const AtomicType::Ptr asAtomic(tType); + + /* This catches casting to xs:NOTATION and xs:anyAtomicType. */ + if(asAtomic->isAbstract()) + { + context->error(QtXmlPatterns::tr("Casting to %1 is not possible because it " + "is an abstract type, and can therefore never be instantiated.") + .arg(formatType(context->namePool(), tType)), + ReportContext::XPST0080, + static_cast(this)); + } +} + +template +void CastingPlatform::issueCastError(const Item &validationError, + const Item &sourceValue, + const ReportContext::Ptr &context) const +{ + Q_ASSERT(validationError); + Q_ASSERT(context); + Q_ASSERT(validationError.isAtomicValue()); + Q_ASSERT(validationError.template as()->hasError()); + + const ValidationError::Ptr err(validationError.template as()); + QString msg(err->message()); + + if(msg.isNull()) + { + msg = QtXmlPatterns::tr("It's not possible to cast the value %1 of type %2 to %3") + .arg(formatData(sourceValue.stringValue())) + .arg(formatType(context->namePool(), sourceValue.type())) + .arg(formatType(context->namePool(), targetType())); + } + else + { + Q_ASSERT(!msg.isEmpty()); + msg = QtXmlPatterns::tr("Failure when casting from %1 to %2: %3") + .arg(formatType(context->namePool(), sourceValue.type())) + .arg(formatType(context->namePool(), targetType())) + .arg(msg); + } + + /* If m_errorCode is FORG0001, we assume our sub-classer doesn't have a + * special wish about error code, so then we use the error object's code. + */ + context->error(msg, m_errorCode == ReportContext::FORG0001 ? err->errorCode() : m_errorCode, + static_cast(this)); +} + diff --git a/src/xmlpatterns/expr/qcastingplatform_p.h b/src/xmlpatterns/expr/qcastingplatform_p.h new file mode 100644 index 0000000..415003f --- /dev/null +++ b/src/xmlpatterns/expr/qcastingplatform_p.h @@ -0,0 +1,206 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_CastingPlatform_H +#define Patternist_CastingPlatform_H + +#include "qatomiccasterlocator_p.h" +#include "qatomiccaster_p.h" +#include "qatomicstring_p.h" +#include "qatomictype_p.h" +#include "qbuiltintypes_p.h" +#include "qcommonsequencetypes_p.h" +#include "qpatternistlocale_p.h" +#include "qqnamevalue_p.h" +#include "qschematypefactory_p.h" +#include "qstaticcontext_p.h" +#include "qvalidationerror_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Provides casting functionality for classes, such as CastAs or NumberFN, which + * needs to perform casting. + * + * Classes which need to perform casting can simply from this class and gain + * access to casting functinality wrapped in a convenient way. At the center of this + * class is the cast() function, which is used at runtime to perform the actual cast. + * + * The actual circumstances where casting is used, such as in the 'castable as' + * expression or the fn:number() function, often have other things to handle as well, + * error handling and cardinality checks for example. This class handles only casting + * and leaves the other case-specific details to the sub-class such that this class only + * do one thing well. + * + * This template class takes two parameters: + * - TSubClass This should be the class inheriting from CastingPlatform. + * - issueError if true, errors are issued via ReportContext, otherwise + * ValidationError instances are returned appropriately. + * + * The class inheriting CastingPlatform must implement the following function: + * @code + * ItemType::Ptr targetType() const + * @endcode + * + * that returns the type that should be cast to. The type must be an AtomicType. + * Typically, it is appropriate to declare this function @c inline. + * + * A sub-class calls prepareCasting() at compile time(such that CastingPlatform can attempt + * to lookup the proper AtomicCaster) and then it simply uses the cast() function at runtime. The + * function targetType() must be implemented such that CastingPlatform knows + * what type it shall cast to. + * + * @see ValueFactory + * @author Frans Englich + * @ingroup Patternist_expressions + */ + template + class CastingPlatform + { + protected: + /** + * @note issueCastError() depends on the default value. + */ + inline CastingPlatform(const ReportContext::ErrorCode code = ReportContext::FORG0001) : m_errorCode(code) + { + } + + /** + * Attempts to cast @p sourceValue to targetType(), and returns + * the created value. Remember that prepareCasting() should have been + * called at compile time, otherwise this function will be slow. + * + * Error reporting is done in two ways. If a cast fails because + * of an error in lexical representation a ValidationError is returned. + * If the cause of failure is that the casting combination is invalid(such as + * when attempting to cast @c xs:date to @c xs:integer), a ValidationError + * is returned if @c false was passed in the template instantiation, + * an error is issued via @p context. + * + * @param sourceValue the value to cast. Must be non @c null. + * @param context the usual ReportContext, used for error reporting. + * @returns the new value which was the result of the cast. If the + * cast failed, an ValidationError is returned. + */ + Item cast(const Item &sourceValue, + const ReportContext::Ptr &context) const; + + /** + * This function should be called at compiled time, it attempts to determine + * what AtomicCaster that should be used when casting from @p sourceType to + * targetType(). If that is not possible, because the @p sourceType is + * @c xs:anyAtomicType for instance, the AtomicCaster lookup will done at + * runtime on a case-per-case basis. + * + * @returns @c true if the requested casting combination is valid or might be valid. + * If it is guranteed to be invalid, @c false is returned. + */ + bool prepareCasting(const ReportContext::Ptr &context, + const ItemType::Ptr &sourceType); + + /** + * Checks that the targetType() is a valid target type for castable as + * and cast as. For example, that it is not abstract. If the type is + * invalid, an error is raised via the @p context. Note that it is assumed the type + * is atomic. + */ + void checkTargetType(const ReportContext::Ptr &context) const; + + private: + inline Item castWithCaster(const Item &sourceValue, + const AtomicCaster::Ptr &caster, + const ReportContext::Ptr &context) const; + + /** + * Locates the caster for casting values of type @p sourceType to targetType(), if + * possible. + * + * @p castImpossible is not initialized. Initialize it to @c false. + */ + static AtomicCaster::Ptr locateCaster(const ItemType::Ptr &sourceType, + const ReportContext::Ptr &context, + bool &castImpossible, + const SourceLocationReflection *const location, + const ItemType::Ptr &targetType); + private: + inline Item castWithCaster(const Item &sourceValue, + const AtomicCaster::Ptr &caster, + const DynamicContext::Ptr &context) const; + + + inline ItemType::Ptr targetType() const + { + Q_ASSERT(static_cast(this)->targetType()); + return static_cast(this)->targetType(); + } + + void issueCastError(const Item &validationError, + const Item &sourceValue, + const ReportContext::Ptr &context) const; + + Q_DISABLE_COPY(CastingPlatform) + AtomicCaster::Ptr m_caster; + const ReportContext::ErrorCode m_errorCode; + }; + +#include "qcastingplatform.cpp" + +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qcollationchecker.cpp b/src/xmlpatterns/expr/qcollationchecker.cpp new file mode 100644 index 0000000..91e4848 --- /dev/null +++ b/src/xmlpatterns/expr/qcollationchecker.cpp @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonsequencetypes_p.h" +#include "qxpathhelper_p.h" + +#include "qcollationchecker_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +CollationChecker::CollationChecker(const Expression::Ptr &source) : SingleContainer(source) +{ +} + +Item CollationChecker::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item val(m_operand->evaluateSingleton(context)); + XPathHelper::checkCollationSupport(val.stringValue(), context, this); + return val; +} + +SequenceType::List CollationChecker::expectedOperandTypes() const +{ + SequenceType::List list; + list.append(CommonSequenceTypes::ExactlyOneString); + return list; +} + +SequenceType::Ptr CollationChecker::staticType() const +{ + return m_operand->staticType(); +} + +ExpressionVisitorResult::Ptr CollationChecker::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qcollationchecker_p.h b/src/xmlpatterns/expr/qcollationchecker_p.h new file mode 100644 index 0000000..b57e8c9 --- /dev/null +++ b/src/xmlpatterns/expr/qcollationchecker_p.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_CollationChecker_H +#define Patternist_CollationChecker_H + +#include "qsinglecontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Checks that its operand evaluates to a supported string collation. + * + * CollationChecker is inserted in the AST when an Expression has LastOperandIsCollation + * set. If the argument that CollationChecker is a string literal the CollationChecker + * will const-fold as usual, but otherwise will simply pipe through the value of its argument, + * if it's a supported collation. Otherwise it raise an error, with code ReportContext::FOCH0002. + * + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class CollationChecker : public SingleContainer + { + public: + CollationChecker(const Expression::Ptr &source); + + virtual Item evaluateSingleton(const DynamicContext::Ptr &) const; + + /** + * Expects exactly one string. + */ + virtual SequenceType::List expectedOperandTypes() const; + + /** + * @returns its operand's static type. + */ + virtual SequenceType::Ptr staticType() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qcombinenodes.cpp b/src/xmlpatterns/expr/qcombinenodes.cpp new file mode 100644 index 0000000..0670faf --- /dev/null +++ b/src/xmlpatterns/expr/qcombinenodes.cpp @@ -0,0 +1,172 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonsequencetypes_p.h" +#include "qexceptiterator_p.h" +#include "qgenericsequencetype_p.h" +#include "qintersectiterator_p.h" +#include "qitemmappingiterator_p.h" +#include "qnodesort_p.h" +#include "qunioniterator_p.h" + +#include "qcombinenodes_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +CombineNodes::CombineNodes(const Expression::Ptr &operand1, + const Operator op, + const Expression::Ptr &operand2) : PairContainer(operand1, operand2), + m_operator(op) +{ + Q_ASSERT(op == Union || + op == Except || + op == Intersect); +} + +Item::Iterator::Ptr CombineNodes::evaluateSequence(const DynamicContext::Ptr &context) const +{ + const Item::Iterator::Ptr op1(m_operand1->evaluateSequence(context)); + const Item::Iterator::Ptr op2(m_operand2->evaluateSequence(context)); + + switch(m_operator) + { + case Intersect: + return Item::Iterator::Ptr(new IntersectIterator(op1, op2)); + case Except: + return Item::Iterator::Ptr(new ExceptIterator(op1, op2)); + default: + { + Q_ASSERT(m_operator == Union); + return Item::Iterator::Ptr(new UnionIterator(op1, op2)); + } + } +} + +Item CombineNodes::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + return evaluateSequence(context)->next(); +} + +Expression::Ptr CombineNodes::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + + const Expression::Ptr me(PairContainer::typeCheck(context, reqType)); + + m_operand1 = NodeSortExpression::wrapAround(m_operand1, context); + m_operand2 = NodeSortExpression::wrapAround(m_operand2, context); + + return me; +} + +bool CombineNodes::evaluateEBV(const DynamicContext::Ptr &context) const +{ + /* If it's the union operator, we can possibly avoid + * evaluating the second operand. */ + + if(m_operator == Union) + { + return m_operand1->evaluateEBV(context) || + m_operand2->evaluateEBV(context); + } + else + return PairContainer::evaluateEBV(context); +} + +QString CombineNodes::displayName(const Operator op) +{ + switch(op) + { + case Intersect: + return QLatin1String("intersect"); + case Except: + return QLatin1String("except"); + default: + { + Q_ASSERT(op == Union); + return QLatin1String("union"); + } + } +} + +SequenceType::Ptr CombineNodes::staticType() const +{ + const SequenceType::Ptr t1(m_operand1->staticType()); + const SequenceType::Ptr t2(m_operand2->staticType()); + + Cardinality card; + + /* Optimization: the cardinality can be better inferred for + * Intersect and Except, although it's not trivial code. */ + if(m_operator == Union) + card = t1->cardinality() | t2->cardinality(); + else /* Except. */ + card = Cardinality::zeroOrMore(); + + return makeGenericSequenceType(t1->itemType() | t2->itemType(), card); +} + +SequenceType::List CombineNodes::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ZeroOrMoreNodes); + result.append(CommonSequenceTypes::ZeroOrMoreNodes); + return result; +} + +CombineNodes::Operator CombineNodes::operatorID() const +{ + return m_operator; +} + +ExpressionVisitorResult::Ptr CombineNodes::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +Expression::ID CombineNodes::id() const +{ + return IDCombineNodes; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qcombinenodes_p.h b/src/xmlpatterns/expr/qcombinenodes_p.h new file mode 100644 index 0000000..4baf196 --- /dev/null +++ b/src/xmlpatterns/expr/qcombinenodes_p.h @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_CombineNodes_H +#define Patternist_CombineNodes_H + +#include "qpaircontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements XPath 2.0's operators for combining node sequences: @c union, + * @c intersect and @c except. + * + * @see XQuery 1.0: An XML Query + * Language, 3.3.3 Combining QXmlNodeModelIndex Sequences + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class Q_AUTOTEST_EXPORT CombineNodes : public PairContainer + { + public: + enum Operator + { + Union = 1, + Intersect = 2, + Except = 4 + }; + + CombineNodes(const Expression::Ptr &operand1, + const Operator op, + const Expression::Ptr &operand2); + + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + virtual bool evaluateEBV(const DynamicContext::Ptr &context) const; + virtual SequenceType::Ptr staticType() const; + virtual SequenceType::List expectedOperandTypes() const; + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + Operator operatorID() const; + virtual ID id() const; + + /** + * Determines the string representation for operator @p op. + * + * @return "union" if @p op is Union, "intersect" if @p op + * is Intersect and "except" if @p op is Except. + */ + static QString displayName(const Operator op); + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + + private: + const Operator m_operator; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qcommentconstructor.cpp b/src/xmlpatterns/expr/qcommentconstructor.cpp new file mode 100644 index 0000000..8d7144f --- /dev/null +++ b/src/xmlpatterns/expr/qcommentconstructor.cpp @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonsequencetypes_p.h" +#include "qpatternistlocale_p.h" +#include "qnodebuilder_p.h" + +#include "qcommentconstructor_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +CommentConstructor::CommentConstructor(const Expression::Ptr &op) : SingleContainer(op) +{ +} + +QString CommentConstructor::evaluateContent(const DynamicContext::Ptr &context) const +{ + const Item item(m_operand->evaluateSingleton(context)); + + if(!item) + return QString(); + + const QString content(item.stringValue()); + + if(content.contains(QLatin1String("--"))) + { + context->error(QtXmlPatterns::tr("A comment cannot contain %1") + .arg(formatData("--")), + ReportContext::XQDY0072, this); + } + else if(content.endsWith(QLatin1Char('-'))) + { + context->error(QtXmlPatterns::tr("A comment cannot end with a %1.") + .arg(formatData(QLatin1Char('-'))), + ReportContext::XQDY0072, this); + } + + return content; +} + +Item CommentConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const QString content(evaluateContent(context)); + const NodeBuilder::Ptr nodeBuilder(context->nodeBuilder(QUrl())); + nodeBuilder->comment(content); + + const QAbstractXmlNodeModel::Ptr nm(nodeBuilder->builtDocument()); + context->addNodeModel(nm); + + return nm->root(QXmlNodeModelIndex()); +} + +void CommentConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const +{ + const QString content(evaluateContent(context)); + QAbstractXmlReceiver *const receiver = context->outputReceiver(); + + receiver->comment(content); +} + +SequenceType::Ptr CommentConstructor::staticType() const +{ + return CommonSequenceTypes::ExactlyOneComment; +} + +SequenceType::List CommentConstructor::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ZeroOrOneString); + return result; +} + +Expression::Properties CommentConstructor::properties() const +{ + return DisableElimination | IsNodeConstructor; +} + +ExpressionVisitorResult::Ptr +CommentConstructor::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qcommentconstructor_p.h b/src/xmlpatterns/expr/qcommentconstructor_p.h new file mode 100644 index 0000000..75467ec --- /dev/null +++ b/src/xmlpatterns/expr/qcommentconstructor_p.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_CommentConstructor_H +#define Patternist_CommentConstructor_H + +#include "qsinglecontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Constructs a comment node. This covers both computed and directly constructed + * text nodes. + * + * @see XQuery + * 1.0: An XML Query Language, 3.7 Constructors + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class CommentConstructor : public SingleContainer + { + public: + CommentConstructor(const Expression::Ptr &operand); + + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const; + + virtual SequenceType::Ptr staticType() const; + + /** + * The first operand must be exactly one @c xs:string. + */ + virtual SequenceType::List expectedOperandTypes() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + + virtual Properties properties() const; + + private: + inline QString evaluateContent(const DynamicContext::Ptr &context) const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qcomparisonplatform.cpp b/src/xmlpatterns/expr/qcomparisonplatform.cpp new file mode 100644 index 0000000..625dd01 --- /dev/null +++ b/src/xmlpatterns/expr/qcomparisonplatform.cpp @@ -0,0 +1,199 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/** + * @file + * @short This file is included by qcomparisonplatform_p.h. + * If you need includes in this file, put them in qcomparisonplatform_p.h, outside of the namespace. + */ + +template +bool ComparisonPlatform:: +flexibleCompare(const Item &it1, + const Item &it2, + const DynamicContext::Ptr &context) const +{ + if(m_comparator) + /* The comparator was located at compile time. */ + return compare(it1, it2, m_comparator, operatorID()); + else + { + const AtomicComparator::Ptr cp(fetchComparator(it1.type(), + it2.type(), + context)); + + return cp ? compare(it1, it2, cp, operatorID()) : false; + } +} + +template +AtomicComparator::ComparisonResult +ComparisonPlatform:: +detailedFlexibleCompare(const Item &it1, + const Item &it2, + const DynamicContext::Ptr &context) const +{ + AtomicComparator::Ptr comp; + + if(m_comparator) + comp = m_comparator; + else + { + comp = fetchComparator(it1.type(), + it2.type(), + context); + } + + Q_ASSERT_X(operatorID() == AtomicComparator::OperatorLessThanNaNLeast || operatorID() == AtomicComparator::OperatorLessThanNaNGreatest, + Q_FUNC_INFO, "Only OperatorLessThan is currently supported for this function."); + return comp->compare(it1, operatorID(), it2); +} + +template +bool ComparisonPlatform:: +compare(const Item &oand1, + const Item &oand2, + const AtomicComparator::Ptr &comp, + const AtomicComparator::Operator op) const +{ + Q_ASSERT(oand1); + Q_ASSERT(oand2); + Q_ASSERT(comp); + + switch(op) + { + case AtomicComparator::OperatorEqual: + return comp->equals(oand1, oand2); + case AtomicComparator::OperatorNotEqual: + return !comp->equals(oand1, oand2); + case AtomicComparator::OperatorLessThanNaNLeast: + case AtomicComparator::OperatorLessThanNaNGreatest: + /* Fallthrough. */ + case AtomicComparator::OperatorLessThan: + return comp->compare(oand1, op, oand2) == AtomicComparator::LessThan; + case AtomicComparator::OperatorGreaterThan: + return comp->compare(oand1, op, oand2) == AtomicComparator::GreaterThan; + case AtomicComparator::OperatorLessOrEqual: + { + const AtomicComparator::ComparisonResult ret = comp->compare(oand1, op, oand2); + return ret == AtomicComparator::LessThan || ret == AtomicComparator::Equal; + } + case(AtomicComparator::OperatorGreaterOrEqual): + { + const AtomicComparator::ComparisonResult ret = comp->compare(oand1, op, oand2); + return ret == AtomicComparator::GreaterThan || ret == AtomicComparator::Equal; + } + } + + /* GCC unbarfer, this line should never be reached. */ + Q_ASSERT(false); + return false; +} + +template +AtomicComparator::Ptr ComparisonPlatform:: +fetchComparator(const ItemType::Ptr &t1, + const ItemType::Ptr &t2, + const ReportContext::Ptr &context) const +{ + Q_ASSERT(t1); + Q_ASSERT(t2); + + if(*BuiltinTypes::xsAnyAtomicType == *t1 || + *BuiltinTypes::xsAnyAtomicType == *t2 || + *BuiltinTypes::item == *t1 || + *BuiltinTypes::item == *t2 || + *BuiltinTypes::numeric == *t1 || + *BuiltinTypes::numeric == *t2 || + *CommonSequenceTypes::Empty == *t1 || + *CommonSequenceTypes::Empty == *t2) + { + /* The static type of(at least) one of the operands could not + * be narrowed further, so we do the operator + * lookup at runtime. + */ + return AtomicComparator::Ptr(); + } + + const AtomicComparatorLocator::Ptr locator + (static_cast(t1.data())->comparatorLocator()); + + if(!locator) + { + if(issueError) + { + context->error(QtXmlPatterns::tr("No comparisons can be done involving the type %1.") + .arg(formatType(context->namePool(), t1)), + errorCode, static_cast(this)->actualReflection()); + } + return AtomicComparator::Ptr(); + } + + const AtomicComparator::Ptr comp(static_cast(t2.data())->accept(locator, operatorID(), + static_cast(this)->actualReflection())); + + if(comp) + return comp; + else if(issueError) + { + context->error(QtXmlPatterns::tr("Operator %1 is not available between atomic values of type %2 and %3.") + .arg(formatKeyword(AtomicComparator::displayName(operatorID(), + comparisonType)), + formatType(context->namePool(), t1), + formatType(context->namePool(), t2)), + errorCode, static_cast(this)->actualReflection()); + } + + return AtomicComparator::Ptr(); +} + +template +void ComparisonPlatform:: +prepareComparison(const AtomicComparator::Ptr &c) +{ + m_comparator = c; +} + diff --git a/src/xmlpatterns/expr/qcomparisonplatform_p.h b/src/xmlpatterns/expr/qcomparisonplatform_p.h new file mode 100644 index 0000000..359e247 --- /dev/null +++ b/src/xmlpatterns/expr/qcomparisonplatform_p.h @@ -0,0 +1,208 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ComparisonPlatform_H +#define Patternist_ComparisonPlatform_H + +#include "qatomiccomparators_p.h" +#include "qitem_p.h" +#include "qcommonsequencetypes_p.h" +#include "qdynamiccontext_p.h" +#include "qbuiltintypes_p.h" +#include "qitemtype_p.h" +#include "qpatternistlocale_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Provides comparison functionality for classes that compare Items, + * such as ValueComparison or MaxFN. + * + * Classes which need comparison functionalities should inherit from this class. + * + * The parameter of this template class is the class inheriting from ComparisonPlatform. + * + * The class inheriting ComparisonPlatform must implement the following function: + * @code + * AtomicComparator::Operator operatorID() const + * @endcode + * + * @author Vincent Ricard + * @ingroup Patternist_expressions + */ + template + class ComparisonPlatform + { + protected: + /** + * Makes ComparisonPlatform use the AtomicComparator @p comparator. + */ + void prepareComparison(const AtomicComparator::Ptr &comparator); + + /** + * Default constructor. Does nothing. It is implemented in order make template + * instantiation easier. + */ + inline ComparisonPlatform() + { + } + + /** + * Utility function for fetching the appropriate AtomicComparator + * for two atomic values of type @p type1 and @p type2, for the operator @p op. + * + * This function is used throughout the implementation, ranging from the ValueComparison + * itself, to for example the aggregate functions. + * + * @param context the ordinary ReportContext, used for issuing errors. + * @param type1 the type of the first operand value in a comparison for which the + * returned AtomicComparator is intended for + * @param type2 the type of the second operand value in a comparison for which the + * returned AtomicComparator is intended for. Whether @p type1 and @p type2 corresponds + * to what is the first second operand type does not have significance, the order + * can be arbitrary + */ + AtomicComparator::Ptr + fetchComparator(const ItemType::Ptr &type1, + const ItemType::Ptr &type2, + const ReportContext::Ptr &context) const; + + /** + * @short Compares @p i1 and @p i2 with operator @p op, using comparator @p + * comp. All input arguments must be valid, and not @c null. + * + * This is a fast, raw function which has the requirement that the + * caller knows what to compare and with what. + */ + bool compare(const Item &i1, + const Item &i2, + const AtomicComparator::Ptr &comp, + const AtomicComparator::Operator op) const; + + /** + * @short Compares @p it1 against @p it2, using comparator() and operatorID(). + * + * If the comparator wasn't looked up at compile time, it will be + * attempted before comparing. If this fails, errors are reported via + * @p context. + */ + bool + flexibleCompare(const Item &it1, + const Item &it2, + const DynamicContext::Ptr &context) const; + + /** + * @short like flexibleCompare(), but returns the result + * as an AtomicComparator::Operator instead of @c bool. + * + * This is useful when it is significant how a less than comparison + * fails; whether the two values are equal or greater than. + */ + AtomicComparator::ComparisonResult + detailedFlexibleCompare(const Item &it1, + const Item &it2, + const DynamicContext::Ptr &context) const; + + /** + * @returns the AtomicComparator that has been allocated at compile time, + * with prepareComparison(). If no AtomicComparator has been allocated + * for some reason, this function returns @c null. + */ + inline const AtomicComparator::Ptr &comparator() const + { + return m_comparator; + } + + /** + * Calling this function makes ComparisonPlatform use a comparator that + * compares strings case insensitively. + * + * @see ValueComparison::isCaseInsensitiveCompare() + */ + inline void useCaseInsensitiveComparator() + { + m_comparator = AtomicComparator::Ptr(new CaseInsensitiveStringComparator()); + } + + private: + /** + * @returns the operator that is used. + */ + inline AtomicComparator::Operator operatorID() const + { + Q_ASSERT(static_cast(this)->operatorID()); + return static_cast(this)->operatorID(); + } + + /** + * The comparator that is used for comparing atomic values. The AtomicComparator + * that is used, depends on the static type of the operands. m_comparator can be + * @c null if it wasn't possible to determine what comparator to use at compile time. + */ + AtomicComparator::Ptr m_comparator; + }; + +#include "qcomparisonplatform.cpp" + +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qcomputednamespaceconstructor.cpp b/src/xmlpatterns/expr/qcomputednamespaceconstructor.cpp new file mode 100644 index 0000000..6eb0c0e --- /dev/null +++ b/src/xmlpatterns/expr/qcomputednamespaceconstructor.cpp @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qanyuri_p.h" +#include "qbuiltintypes_p.h" +#include "qcommonsequencetypes_p.h" +#include "qpatternistlocale_p.h" +#include "private/qxmlutils_p.h" + +#include "qcomputednamespaceconstructor_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +ComputedNamespaceConstructor::ComputedNamespaceConstructor(const Expression::Ptr &prefix, + const Expression::Ptr &namespaceURI) : PairContainer(prefix, namespaceURI) +{ +} + +void ComputedNamespaceConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const +{ + const Item prefixItem(m_operand1->evaluateSingleton(context)); + const QString prefix(prefixItem ? prefixItem.stringValue() : QString()); + + const Item namespaceItem(m_operand2->evaluateSingleton(context)); + const QString namespaceURI(namespaceItem ? namespaceItem.stringValue() : QString()); + + if(namespaceURI.isEmpty()) + { + context->error(QtXmlPatterns::tr("In a namespace constructor, the value for a namespace cannot be an empty string."), + ReportContext::XTDE0930, + this); + } + + /* One optimization could be to store a pointer to + * the name pool as a member in order to avoid the virtual call(s). */ + const NamePool::Ptr np(context->namePool()); + + if(!prefix.isEmpty() && !QXmlUtils::isNCName(prefix)) + { + context->error(QtXmlPatterns::tr("The prefix must be a valid %1, which %2 is not.") + .arg(formatType(np, BuiltinTypes::xsNCName), + formatKeyword(prefix)), + ReportContext::XTDE0920, + this); + } + const QXmlName binding(np->allocateBinding(prefix, namespaceURI)); + + AnyURI::toQUrl(namespaceURI, + context, + this); + + if(binding.prefix() == StandardPrefixes::xmlns) + { + context->error(QtXmlPatterns::tr("The prefix %1 cannot be bound.") + .arg(formatKeyword(prefix)), + ReportContext::XTDE0920, + this); + } + + if((binding.prefix() == StandardPrefixes::xml && binding.namespaceURI() != StandardNamespaces::xml) + || + (binding.prefix() != StandardPrefixes::xml && binding.namespaceURI() == StandardNamespaces::xml)) + { + context->error(QtXmlPatterns::tr("Only the prefix %1 can be bound to %2 and vice versa.") + .arg(formatKeyword(prefix), formatKeyword(namespaceURI)), + ReportContext::XTDE0925, + this); + } + + context->outputReceiver()->namespaceBinding(binding); +} + +SequenceType::Ptr ComputedNamespaceConstructor::staticType() const +{ + return CommonSequenceTypes::ExactlyOneAttribute; +} + +SequenceType::List ComputedNamespaceConstructor::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ZeroOrOneString); + result.append(CommonSequenceTypes::ZeroOrOneString); + return result; +} + +Expression::Properties ComputedNamespaceConstructor::properties() const +{ + return DisableElimination | IsNodeConstructor; +} + +ExpressionVisitorResult::Ptr ComputedNamespaceConstructor::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qcomputednamespaceconstructor_p.h b/src/xmlpatterns/expr/qcomputednamespaceconstructor_p.h new file mode 100644 index 0000000..3950052 --- /dev/null +++ b/src/xmlpatterns/expr/qcomputednamespaceconstructor_p.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ComputedNamespaceConstructor_H +#define Patternist_ComputedNamespaceConstructor_H + +#include "qpaircontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Constructs a namespace on an element, and naturally only appears + * as a child of ElementConstructor. + * + * @author Frans Englich + * @ingroup Patternist_expressions + * @since 4.5 + */ + class ComputedNamespaceConstructor : public PairContainer + { + public: + ComputedNamespaceConstructor(const Expression::Ptr &prefix, + const Expression::Ptr &namespaceURI); + + virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const; + + /** + * @returns a list containing one CommonSequenceTypes::ExactlyOneString instance. + */ + virtual SequenceType::List expectedOperandTypes() const; + + /** + * The static type is exactly one attribute node. It's unclear what + * affects the static type has, but specifying anything else could lead + * to complications wrt. node order, XQTY0024. Of course, it's not + * conceptually correct, since a namespace node isn't an attribute + * node. + */ + virtual SequenceType::Ptr staticType() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + virtual Expression::Properties properties() const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qcontextitem.cpp b/src/xmlpatterns/expr/qcontextitem.cpp new file mode 100644 index 0000000..caa6653 --- /dev/null +++ b/src/xmlpatterns/expr/qcontextitem.cpp @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" +#include "qcommonsequencetypes_p.h" +#include "qgenericsequencetype_p.h" + +#include "qcontextitem_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Item ContextItem::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + return context->contextItem(); +} + +Expression::Ptr ContextItem::compress(const StaticContext::Ptr &context) +{ + m_itemType = context->contextItemType(); + return EmptyContainer::compress(context); +} + +Expression::Ptr ContextItem::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + m_itemType = context->contextItemType(); + return EmptyContainer::typeCheck(context, reqType); +} + +SequenceType::Ptr ContextItem::staticType() const +{ + /* We test m_itemType here because Patternist View calls staticType() before the typeCheck() + * stage. */ + if(m_itemType) + return makeGenericSequenceType(m_itemType, Cardinality::exactlyOne()); + else + return CommonSequenceTypes::ExactlyOneItem; +} + +Expression::Properties ContextItem::properties() const +{ + return DisableElimination | RequiresContextItem | EvaluationCacheRedundant; +} + +ExpressionVisitorResult::Ptr ContextItem::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +Expression::ID ContextItem::id() const +{ + return IDContextItem; +} + +ItemType::Ptr ContextItem::expectedContextItemType() const +{ + return BuiltinTypes::item; +} + +const SourceLocationReflection *ContextItem::actualReflection() const +{ + if(m_expr) + return m_expr.data(); + else + return this; +} + +void ContextItem::announceFocusType(const ItemType::Ptr &type) +{ + Q_ASSERT(type); + m_itemType = type; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qcontextitem_p.h b/src/xmlpatterns/expr/qcontextitem_p.h new file mode 100644 index 0000000..e3ae81e --- /dev/null +++ b/src/xmlpatterns/expr/qcontextitem_p.h @@ -0,0 +1,128 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ContextItem_H +#define Patternist_ContextItem_H + +#include "qemptycontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the context item, the dot: .. + * + * @see XML Path Language + * (XPath) 2.0, 3.1.4 Context Item Expression + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class ContextItem : public EmptyContainer + { + public: + /** + * @p expr is possibly used for error reporting. If this context item has been + * created implicitly, such as for the expression fn:string(), @p expr + * should be passed a valid pointer to the Expression that this context + * item is generated for. + */ + inline ContextItem(const Expression::Ptr &expr = Expression::Ptr()) : m_expr(expr) + { + } + + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + virtual SequenceType::Ptr staticType() const; + + /** + * @returns always DisableElimination and RequiresContextItem + */ + virtual Expression::Properties properties() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + + /** + * Overridden to store a pointer to StaticContext::contextItemType(). + */ + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + + /** + * Overridden to store a pointer to StaticContext::contextItemType(). + */ + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + /** + * @returns always IDContextItem + */ + virtual ID id() const; + + /** + * @returns always BuiltinTypes::item; + */ + virtual ItemType::Ptr expectedContextItemType() const; + + virtual const SourceLocationReflection *actualReflection() const; + virtual void announceFocusType(const ItemType::Ptr &type); + + private: + ItemType::Ptr m_itemType; + const Expression::Ptr m_expr; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qcopyof.cpp b/src/xmlpatterns/expr/qcopyof.cpp new file mode 100644 index 0000000..ddb5a2c --- /dev/null +++ b/src/xmlpatterns/expr/qcopyof.cpp @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" +#include "qcommonsequencetypes_p.h" +#include "qitemmappingiterator_p.h" + +#include "qcopyof_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +CopyOf::CopyOf(const Expression::Ptr &operand, + const bool inheritNSS, + const bool preserveNSS) : SingleContainer(operand) + , m_inheritNamespaces(inheritNSS) + , m_preserveNamespaces(preserveNSS) + , m_settings((m_inheritNamespaces ? QAbstractXmlNodeModel::InheritNamespaces : QAbstractXmlNodeModel::NodeCopySettings()) | + (m_preserveNamespaces ? QAbstractXmlNodeModel::PreserveNamespaces : QAbstractXmlNodeModel::NodeCopySettings())) +{ +} + +Expression::Ptr CopyOf::compress(const StaticContext::Ptr &context) +{ + /* We have zero effect if we have these settings. */ + if(m_inheritNamespaces && m_preserveNamespaces) + return m_operand->compress(context); + else + { + const ItemType::Ptr t(m_operand->staticType()->itemType()); + /* We have no effect on the empty sequence or atomic values. */ + if(BuiltinTypes::xsAnyAtomicType->xdtTypeMatches(t) + || *t == *CommonSequenceTypes::Empty) + return m_operand->compress(context); + else + return SingleContainer::compress(context); + } +} + +void CopyOf::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const +{ + /* Optimization: this completely breaks streaming. We get a call to + * evaluateToSequenceReceiver() but we require heap allocations by calling + * evaluateSequence(). */ + + const Item::Iterator::Ptr it(m_operand->evaluateSequence(context)); + QAbstractXmlReceiver *const receiver = context->outputReceiver(); + Item next(it->next()); + + while(next) + { + if(next.isNode()) + { + const QXmlNodeModelIndex &asNode = next.asNode(); + asNode.model()->copyNodeTo(asNode, receiver, m_settings); + } + else + receiver->item(next); + + next = it->next(); + } +} + +ExpressionVisitorResult::Ptr CopyOf::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +SequenceType::Ptr CopyOf::staticType() const +{ + return m_operand->staticType(); +} + +SequenceType::List CopyOf::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ZeroOrMoreItems); + return result; +} + +Expression::Properties CopyOf::properties() const +{ + /* We have the content of node constructors as children, but even though + * createCopyOf() typically avoids creating us, we can still end up with an operand + * that allows compression. We must always avoid that, because we don't have + * implementation of evaluateSequence(), and so on. */ + return (m_operand->properties() & ~CreatesFocusForLast) | DisableElimination; +} + +ItemType::Ptr CopyOf::expectedContextItemType() const +{ + return m_operand->expectedContextItemType(); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qcopyof_p.h b/src/xmlpatterns/expr/qcopyof_p.h new file mode 100644 index 0000000..7a89b69 --- /dev/null +++ b/src/xmlpatterns/expr/qcopyof_p.h @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_CopyOf_H +#define Patternist_CopyOf_H + +#include "qsinglecontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Does node copying in a parameterized way, in order to deal with + * namespace preservation/inheritance. + * + * If someone tries to call evaluateEBV(), evaluateSingleton() or + * evaluateSequence() on us, we will infinitely loop. But apparently + * that's not possible because we're always a child of ElementConstructor, + * currently. + * + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class CopyOf : public SingleContainer + { + public: + /** + * Creats a CopyOf where it is checked that the expression @p operand conforms + * to the type @p reqType. + */ + CopyOf(const Expression::Ptr &operand, + const bool inheritNSS, + const bool preserveNSS); + + virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const; + + /** + * @returns always the SequenceType passed in the constructor to this class. That is, the + * SequenceType that the operand must conform to. + */ + virtual SequenceType::Ptr staticType() const; + + /** + * @returns a list containing one CommonSequenceTypes::ZeroOrMoreItems + */ + virtual SequenceType::List expectedOperandTypes() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + + inline Item mapToItem(const Item &source, + const DynamicContext::Ptr &context) const; + + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + + virtual Properties properties() const; + virtual ItemType::Ptr expectedContextItemType() const; + + private: + typedef QExplicitlySharedDataPointer ConstPtr; + const bool m_inheritNamespaces; + const bool m_preserveNamespaces; + const QAbstractXmlNodeModel::NodeCopySettings m_settings; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qcurrentitemstore.cpp b/src/xmlpatterns/expr/qcurrentitemstore.cpp new file mode 100644 index 0000000..0bfab8b --- /dev/null +++ b/src/xmlpatterns/expr/qcurrentitemstore.cpp @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" +#include "qcommonsequencetypes_p.h" +#include "qcurrentitemcontext_p.h" +#include "qstaticcurrentcontext_p.h" + +#include "qcurrentitemstore_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +CurrentItemStore::CurrentItemStore(const Expression::Ptr &operand) : SingleContainer(operand) +{ +} + +DynamicContext::Ptr CurrentItemStore::createContext(const DynamicContext::Ptr &old) const +{ + return DynamicContext::Ptr(new CurrentItemContext(old->contextItem(), old)); +} + +bool CurrentItemStore::evaluateEBV(const DynamicContext::Ptr &context) const +{ + return m_operand->evaluateEBV(createContext(context)); +} + +Item::Iterator::Ptr CurrentItemStore::evaluateSequence(const DynamicContext::Ptr &context) const +{ + return m_operand->evaluateSequence(createContext(context)); +} + +Item CurrentItemStore::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + return m_operand->evaluateSingleton(createContext(context)); +} + +SequenceType::Ptr CurrentItemStore::staticType() const +{ + return m_operand->staticType(); +} + +SequenceType::List CurrentItemStore::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ZeroOrMoreItems); + return result; +} + +StaticContext::Ptr CurrentItemStore::newStaticContext(const StaticContext::Ptr &context) +{ + /* It might be we are generated despite there is no focus. In that case + * an error will reported in case current() is used, but in any case we cannot + * crash, so use item() in case we have no focus. + * + * Such a case is when we're inside a named template, and it's invoked + * without focus. */ + const ItemType::Ptr t(context->contextItemType()); + return StaticContext::Ptr(new StaticCurrentContext(t ? t : BuiltinTypes::item, context)); +} + +Expression::Ptr CurrentItemStore::compress(const StaticContext::Ptr &context) +{ + const Expression::Ptr me(SingleContainer::compress(newStaticContext(context))); + + if(me != this) + return me; + else + { + /* If fn:current() isn't called, there's no point in us sticking + * around. */ + if(m_operand->deepProperties().testFlag(RequiresCurrentItem)) + return me; + else + return m_operand; + } +} + +Expression::Ptr CurrentItemStore::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + return SingleContainer::typeCheck(newStaticContext(context), reqType); +} + +ExpressionVisitorResult::Ptr CurrentItemStore::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +const SourceLocationReflection *CurrentItemStore::actualReflection() const +{ + return m_operand->actualReflection(); +} + +Expression::Properties CurrentItemStore::properties() const +{ + return m_operand->properties() & (RequiresFocus | IsEvaluated | DisableElimination); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qcurrentitemstore_p.h b/src/xmlpatterns/expr/qcurrentitemstore_p.h new file mode 100644 index 0000000..f7cc5d8 --- /dev/null +++ b/src/xmlpatterns/expr/qcurrentitemstore_p.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_CurrentItemStore_H +#define Patternist_CurrentItemStore_H + +#include "qsinglecontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Creates a DynamicContext which provides the focus item for the + * function @c fn:current(). + * + * @author Frans Englich + * @ingroup Patternist_expressions + * @since 4.5 + */ + class CurrentItemStore : public SingleContainer + { + public: + CurrentItemStore(const Expression::Ptr &operand); + + virtual bool evaluateEBV(const DynamicContext::Ptr &) const; + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &) const; + virtual Item evaluateSingleton(const DynamicContext::Ptr &) const; + + virtual SequenceType::List expectedOperandTypes() const; + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + virtual Properties properties() const; + + /** + * @returns the staticType() of its operand. + */ + virtual SequenceType::Ptr staticType() const; + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + virtual const SourceLocationReflection *actualReflection() const; + + private: + static inline StaticContext::Ptr newStaticContext(const StaticContext::Ptr &context); + inline DynamicContext::Ptr createContext(const DynamicContext::Ptr &old) const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qdocumentconstructor.cpp b/src/xmlpatterns/expr/qdocumentconstructor.cpp new file mode 100644 index 0000000..9dfbe09 --- /dev/null +++ b/src/xmlpatterns/expr/qdocumentconstructor.cpp @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonsequencetypes_p.h" +#include "qdocumentcontentvalidator_p.h" +#include "qnodebuilder_p.h" + +#include "qdocumentconstructor_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +DocumentConstructor::DocumentConstructor(const Expression::Ptr &op) : SingleContainer(op) +{ +} + +Item DocumentConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + NodeBuilder::Ptr nodeBuilder(context->nodeBuilder(m_staticBaseURI)); + + DocumentContentValidator validator(nodeBuilder.data(), context, ConstPtr(this)); + const DynamicContext::Ptr receiverContext(context->createReceiverContext(&validator)); + + validator.startDocument(); + m_operand->evaluateToSequenceReceiver(receiverContext); + validator.endDocument(); + + const QAbstractXmlNodeModel::Ptr nm(nodeBuilder->builtDocument()); + context->addNodeModel(nm); + + return nm->root(QXmlNodeModelIndex()); +} + +void DocumentConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const +{ + QAbstractXmlReceiver *const receiver = context->outputReceiver(); + + DocumentContentValidator validator(receiver, context, ConstPtr(this)); + + const DynamicContext::Ptr receiverContext(context->createReceiverContext(&validator)); + + validator.startDocument(); + m_operand->evaluateToSequenceReceiver(receiverContext); + validator.endDocument(); +} + +Expression::Ptr DocumentConstructor::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + m_staticBaseURI = context->baseURI(); + return SingleContainer::typeCheck(context, reqType); +} + +SequenceType::Ptr DocumentConstructor::staticType() const +{ + return CommonSequenceTypes::ExactlyOneDocumentNode; +} + +SequenceType::List DocumentConstructor::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ZeroOrMoreItems); + return result; +} + +Expression::Properties DocumentConstructor::properties() const +{ + return DisableElimination | IsNodeConstructor; +} + +ExpressionVisitorResult::Ptr +DocumentConstructor::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qdocumentconstructor_p.h b/src/xmlpatterns/expr/qdocumentconstructor_p.h new file mode 100644 index 0000000..8b685f9 --- /dev/null +++ b/src/xmlpatterns/expr/qdocumentconstructor_p.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_DocumentConstructor_H +#define Patternist_DocumentConstructor_H + +#include + +#include "qsinglecontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Constructs a text node. This covers both computed and directly constructed + * text nodes. + * + * @see XQuery + * 1.0: An XML Query Language, 3.7 Constructors + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class DocumentConstructor : public SingleContainer + { + public: + DocumentConstructor(const Expression::Ptr &operand); + + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const; + + /** + * The first operand must be exactly one @c xs:string. + */ + virtual SequenceType::List expectedOperandTypes() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + virtual Properties properties() const; + virtual SequenceType::Ptr staticType() const; + + private: + QUrl m_staticBaseURI; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qdocumentcontentvalidator.cpp b/src/xmlpatterns/expr/qdocumentcontentvalidator.cpp new file mode 100644 index 0000000..75e9ae6 --- /dev/null +++ b/src/xmlpatterns/expr/qdocumentcontentvalidator.cpp @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qpatternistlocale_p.h" + +#include "qdocumentcontentvalidator_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +DocumentContentValidator:: +DocumentContentValidator(QAbstractXmlReceiver *const receiver, + const DynamicContext::Ptr &context, + const Expression::ConstPtr &expr) : m_receiver(receiver) + , m_context(context) + , m_expr(expr) + , m_elementDepth(0) +{ + Q_ASSERT(receiver); + Q_ASSERT(m_expr); + Q_ASSERT(context); +} + +void DocumentContentValidator::namespaceBinding(const QXmlName &nb) +{ + m_receiver->namespaceBinding(nb); +} + +void DocumentContentValidator::startElement(const QXmlName &name) +{ + ++m_elementDepth; + m_receiver->startElement(name); +} + +void DocumentContentValidator::endElement() +{ + Q_ASSERT(m_elementDepth > 0); + --m_elementDepth; + m_receiver->endElement(); +} + +void DocumentContentValidator::attribute(const QXmlName &name, + const QStringRef &value) +{ + if(m_elementDepth == 0) + { + m_context->error(QtXmlPatterns::tr("An attribute node cannot be a " + "child of a document node. " + "Therefore, the attribute %1 " + "is out of place.") + .arg(formatKeyword(m_context->namePool(), name)), + ReportContext::XPTY0004, m_expr.data()); + } + else + m_receiver->attribute(name, value); +} + +void DocumentContentValidator::comment(const QString &value) +{ + m_receiver->comment(value); +} + +void DocumentContentValidator::characters(const QStringRef &value) +{ + m_receiver->characters(value); +} + +void DocumentContentValidator::processingInstruction(const QXmlName &name, + const QString &value) +{ + m_receiver->processingInstruction(name, value); +} + +void DocumentContentValidator::item(const Item &outputItem) +{ + /* We can't send outputItem directly to m_receiver since its item() function + * won't dispatch to this DocumentContentValidator, but to itself. We're not sub-classing here, + * we're delegating. */ + + if(outputItem.isNode()) + sendAsNode(outputItem); + else + m_receiver->item(outputItem); +} + +void DocumentContentValidator::startDocument() +{ + m_receiver->startDocument(); +} + +void DocumentContentValidator::endDocument() +{ + m_receiver->endDocument(); +} + +void DocumentContentValidator::atomicValue(const QVariant &value) +{ + Q_UNUSED(value); +} + +void DocumentContentValidator::startOfSequence() +{ +} + +void DocumentContentValidator::endOfSequence() +{ +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qdocumentcontentvalidator_p.h b/src/xmlpatterns/expr/qdocumentcontentvalidator_p.h new file mode 100644 index 0000000..92bee3f --- /dev/null +++ b/src/xmlpatterns/expr/qdocumentcontentvalidator_p.h @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_DocumentContentValidator_H +#define Patternist_DocumentContentValidator_H + +#include "qdynamiccontext_p.h" +#include "qexpression_p.h" +#include "qabstractxmlreceiver.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Receives QAbstractXmlReceiver events and validates that they are correct, + * before sending them on to a second QAbstractXmlReceiver. + * + * @ingroup Patternist_xdm + * @author Frans Englich + * @todo Escape data + */ + class DocumentContentValidator : public QAbstractXmlReceiver + { + public: + /** + * DocumentContentValidator does not own @p receiver. + */ + DocumentContentValidator(QAbstractXmlReceiver *const receiver, + const DynamicContext::Ptr &context, + const Expression::ConstPtr &expr); + + virtual void namespaceBinding(const QXmlName &nb); + virtual void characters(const QStringRef &value); + virtual void comment(const QString &value); + + virtual void startElement(const QXmlName &name); + + virtual void endElement(); + + virtual void attribute(const QXmlName &name, + const QStringRef &value); + + virtual void processingInstruction(const QXmlName &name, + const QString &value); + + virtual void item(const Item &item); + + virtual void startDocument(); + virtual void endDocument(); + virtual void atomicValue(const QVariant &value); + virtual void startOfSequence(); + virtual void endOfSequence(); + + private: + QAbstractXmlReceiver *const m_receiver; + const DynamicContext::Ptr m_context; + const Expression::ConstPtr m_expr; + xsInteger m_elementDepth; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qdynamiccontextstore.cpp b/src/xmlpatterns/expr/qdynamiccontextstore.cpp new file mode 100644 index 0000000..762b7d6 --- /dev/null +++ b/src/xmlpatterns/expr/qdynamiccontextstore.cpp @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qboolean_p.h" +#include "qcommonsequencetypes_p.h" +#include "qcommonvalues_p.h" + +#include "qdynamiccontextstore_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +DynamicContextStore::DynamicContextStore(const Expression::Ptr &operand, + const DynamicContext::Ptr &context) : SingleContainer(operand), + m_context(context) +{ + Q_ASSERT(context); +} + +bool DynamicContextStore::evaluateEBV(const DynamicContext::Ptr &) const +{ + return m_operand->evaluateEBV(m_context); +} + +Item::Iterator::Ptr DynamicContextStore::evaluateSequence(const DynamicContext::Ptr &) const +{ + return m_operand->evaluateSequence(m_context); +} + +Item DynamicContextStore::evaluateSingleton(const DynamicContext::Ptr &) const +{ + return m_operand->evaluateSingleton(m_context); +} + +SequenceType::Ptr DynamicContextStore::staticType() const +{ + return m_operand->staticType(); +} + +SequenceType::List DynamicContextStore::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ZeroOrMoreItems); + return result; +} + +ExpressionVisitorResult::Ptr DynamicContextStore::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +const SourceLocationReflection *DynamicContextStore::actualReflection() const +{ + return m_operand->actualReflection(); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qdynamiccontextstore_p.h b/src/xmlpatterns/expr/qdynamiccontextstore_p.h new file mode 100644 index 0000000..1d5d035 --- /dev/null +++ b/src/xmlpatterns/expr/qdynamiccontextstore_p.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_DynamicContextStore_H +#define Patternist_DynamicContextStore_H + +#include "qsinglecontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Evaluates its operand with an assigned DynamicContext, not + * the one passed to one of the evaluation functions. + * + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class DynamicContextStore : public SingleContainer + { + public: + DynamicContextStore(const Expression::Ptr &operand, + const DynamicContext::Ptr &context); + + virtual bool evaluateEBV(const DynamicContext::Ptr &) const; + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &) const; + virtual Item evaluateSingleton(const DynamicContext::Ptr &) const; + + virtual SequenceType::List expectedOperandTypes() const; + /** + * @returns the staticType() of its operand. + */ + virtual SequenceType::Ptr staticType() const; + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + virtual const SourceLocationReflection *actualReflection() const; + + private: + const DynamicContext::Ptr m_context; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qelementconstructor.cpp b/src/xmlpatterns/expr/qelementconstructor.cpp new file mode 100644 index 0000000..41f7b11 --- /dev/null +++ b/src/xmlpatterns/expr/qelementconstructor.cpp @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonsequencetypes_p.h" +#include "qdelegatingnamespaceresolver_p.h" +#include "qnamespaceconstructor_p.h" +#include "qnodebuilder_p.h" +#include "qoutputvalidator_p.h" +#include "qqnamevalue_p.h" +#include "qstaticnamespacecontext_p.h" + +#include "qelementconstructor_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +ElementConstructor::ElementConstructor(const Expression::Ptr &op1, + const Expression::Ptr &op2, + const bool isXSLT) : PairContainer(op1, op2) + , m_isXSLT(isXSLT) +{ +} + +Item ElementConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item name(m_operand1->evaluateSingleton(context)); + + const NodeBuilder::Ptr nodeBuilder(context->nodeBuilder(m_staticBaseURI)); + OutputValidator validator(nodeBuilder.data(), context, this, m_isXSLT); + + const DynamicContext::Ptr receiverContext(context->createReceiverContext(&validator)); + + nodeBuilder->startElement(name.as()->qName()); + m_operand2->evaluateToSequenceReceiver(receiverContext); + nodeBuilder->endElement(); + + const QAbstractXmlNodeModel::Ptr nm(nodeBuilder->builtDocument()); + context->addNodeModel(nm); + + return nm->root(QXmlNodeModelIndex()); +} + +void ElementConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const +{ + /* We create an OutputValidator here too. If we're serializing(a common + * case, unfortunately) the receiver is already validating in order to + * catch cases where a computed attribute constructor is followed by an + * element constructor, but in the cases where we're not serializing it's + * necessary that we validate in this step. */ + const Item name(m_operand1->evaluateSingleton(context)); + QAbstractXmlReceiver *const receiver = context->outputReceiver(); + + OutputValidator validator(receiver, context, this, m_isXSLT); + const DynamicContext::Ptr receiverContext(context->createReceiverContext(&validator)); + + receiver->startElement(name.as()->qName()); + m_operand2->evaluateToSequenceReceiver(receiverContext); + receiver->endElement(); +} + +Expression::Ptr ElementConstructor::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + /* What does this code do? When type checking our children, our namespace + * bindings, which are also children of the form of NamespaceConstructor + * instances, must be statically in-scope for them, so find them and + * shuffle their bindings into the StaticContext. */ + + m_staticBaseURI = context->baseURI(); + + /* Namespace declarations changes the in-scope bindings, so let's + * first lookup our child NamespaceConstructors. */ + const ID operandID = m_operand2->id(); + + NamespaceResolver::Bindings overrides; + if(operandID == IDExpressionSequence) + { + const Expression::List operands(m_operand2->operands()); + const int len = operands.count(); + + for(int i = 0; i < len; ++i) + { + if(operands.at(i)->is(IDNamespaceConstructor)) + { + const QXmlName &nb = operands.at(i)->as()->namespaceBinding(); + overrides.insert(nb.prefix(), nb.namespaceURI()); + } + } + } + + const NamespaceResolver::Ptr newResolver(new DelegatingNamespaceResolver(context->namespaceBindings(), overrides)); + const StaticContext::Ptr augmented(new StaticNamespaceContext(newResolver, context)); + + return PairContainer::typeCheck(augmented, reqType); +} + +SequenceType::Ptr ElementConstructor::staticType() const +{ + return CommonSequenceTypes::ExactlyOneElement; +} + +SequenceType::List ElementConstructor::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ExactlyOneQName); + result.append(CommonSequenceTypes::ZeroOrMoreItems); + return result; +} + +Expression::Properties ElementConstructor::properties() const +{ + return DisableElimination | IsNodeConstructor; +} + +ExpressionVisitorResult::Ptr +ElementConstructor::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qelementconstructor_p.h b/src/xmlpatterns/expr/qelementconstructor_p.h new file mode 100644 index 0000000..55c18a2 --- /dev/null +++ b/src/xmlpatterns/expr/qelementconstructor_p.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ElementConstructor_H +#define Patternist_ElementConstructor_H + +#include + +#include "qpaircontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Constructs an element node. This covers both computed and directly constructed + * element nodes. + * + * @see XQuery + * 1.0: An XML Query Language, 3.7 Constructors + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class ElementConstructor : public PairContainer + { + public: + ElementConstructor(const Expression::Ptr &operand1, + const Expression::Ptr &operand2, + const bool isXSLT); + + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const; + + virtual SequenceType::Ptr staticType() const; + + /** + * The first operand must be exactly one @c xs:QName, and the second + * argument can be zero or more items. + */ + virtual SequenceType::List expectedOperandTypes() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + virtual Properties properties() const; + + private: + QUrl m_staticBaseURI; + const bool m_isXSLT; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qemptycontainer.cpp b/src/xmlpatterns/expr/qemptycontainer.cpp new file mode 100644 index 0000000..4681fc0 --- /dev/null +++ b/src/xmlpatterns/expr/qemptycontainer.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qemptycontainer_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Expression::List EmptyContainer::operands() const +{ + return Expression::List(); +} + +SequenceType::List EmptyContainer::expectedOperandTypes() const +{ + return SequenceType::List(); +} + +void EmptyContainer::setOperands(const Expression::List &) +{ +} + +bool EmptyContainer::compressOperands(const StaticContext::Ptr &) +{ + return true; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qemptycontainer_p.h b/src/xmlpatterns/expr/qemptycontainer_p.h new file mode 100644 index 0000000..d1eace6 --- /dev/null +++ b/src/xmlpatterns/expr/qemptycontainer_p.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_EmptyContainer_H +#define Patternist_EmptyContainer_H + +#include "qexpression_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Base class for expressions that has no operands. + * + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class Q_AUTOTEST_EXPORT EmptyContainer : public Expression + { + public: + /** + * @returns always an empty list. + */ + virtual Expression::List operands() const; + + /** + * Does nothing, since sub-classes has no operands. Calling + * it makes hence no sense, and it also results in an assert crash. + */ + virtual void setOperands(const Expression::List &); + + protected: + /** + * @returns always @c true + */ + virtual bool compressOperands(const StaticContext::Ptr &context); + + /** + * @returns always an empty list since it has no operands. + */ + virtual SequenceType::List expectedOperandTypes() const; + + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qemptysequence.cpp b/src/xmlpatterns/expr/qemptysequence.cpp new file mode 100644 index 0000000..66b6381 --- /dev/null +++ b/src/xmlpatterns/expr/qemptysequence.cpp @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonvalues_p.h" +#include "qcommonsequencetypes_p.h" +#include "qemptysequencetype_p.h" + +#include "qemptysequence_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Expression::Ptr EmptySequence::create(const Expression *const replacementFor, + const StaticContext::Ptr &context) +{ + Q_ASSERT(replacementFor); + Q_ASSERT(context); + + const Expression::Ptr retval(new EmptySequence()); + context->wrapExpressionWith(replacementFor, retval); + return retval; +} + +Item::Iterator::Ptr EmptySequence::evaluateSequence(const DynamicContext::Ptr &) const +{ + return CommonValues::emptyIterator; +} + +Item EmptySequence::evaluateSingleton(const DynamicContext::Ptr &) const +{ + return Item(); +} + +void EmptySequence::evaluateToSequenceReceiver(const DynamicContext::Ptr &) const +{ +} + +ItemType::Ptr EmptySequence::type() const +{ + return CommonSequenceTypes::Empty; +} + +SequenceType::Ptr EmptySequence::staticType() const +{ + return CommonSequenceTypes::Empty; +} + +bool EmptySequence::evaluateEBV(const DynamicContext::Ptr &) const +{ + return false; +} + +QString EmptySequence::stringValue() const +{ + return QString(); +} + +ExpressionVisitorResult::Ptr EmptySequence::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +Expression::ID EmptySequence::id() const +{ + return IDEmptySequence; +} + +Expression::Properties EmptySequence::properties() const +{ + return IsEvaluated; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qemptysequence_p.h b/src/xmlpatterns/expr/qemptysequence_p.h new file mode 100644 index 0000000..d6a72a2 --- /dev/null +++ b/src/xmlpatterns/expr/qemptysequence_p.h @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_EmptySequence_H +#define Patternist_EmptySequence_H + +#include "qemptycontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the value instance of empty sequence: (). + * + * @author Frans Englich + * @ingroup Patternist_xdm + */ + class EmptySequence : public EmptyContainer + { + public: + /** + * @short Creates an EmptySequence that is a replacement for @p + * replacementFor. + * + * @see EmptySequence() + */ + static Expression::Ptr create(const Expression *const replacementFor, + const StaticContext::Ptr &context); + + + /** + * @short Creates an instance of EmptySequence. + * + * @note In most cases create() should be used, since it takes care of + * adjusting source location annotations. + * + * @see create() + */ + inline EmptySequence() + { + } + + virtual QString stringValue() const; + + /** + * @returns always an empty iterator, an instance of EmptyIterator. + */ + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &) const; + + /** + * @returns always @c null. + */ + virtual Item evaluateSingleton(const DynamicContext::Ptr &) const; + + /** + * Does nothing. + */ + virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &) const; + + /** + * @returns always @c false. + */ + virtual bool evaluateEBV(const DynamicContext::Ptr &context) const; + + /** + * @returns always CommonSequenceTypes::Empty + */ + virtual ItemType::Ptr type() const; + + /** + * @returns always CommonSequenceTypes::Empty + */ + virtual SequenceType::Ptr staticType() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + virtual ID id() const; + virtual Properties properties() const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qevaluationcache.cpp b/src/xmlpatterns/expr/qevaluationcache.cpp new file mode 100644 index 0000000..2d1bb56 --- /dev/null +++ b/src/xmlpatterns/expr/qevaluationcache.cpp @@ -0,0 +1,274 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/** + * @file + * @short This file is included by qevaluationcache_p.h. + * If you need includes in this file, put them in qevaluationcache_p.h, outside of the namespace. + */ + +template +EvaluationCache::EvaluationCache(const Expression::Ptr &op, + const VariableDeclaration::Ptr &varDecl, + const VariableSlotID aSlot) : SingleContainer(op) + , m_declaration(varDecl) + , m_varSlot(aSlot) +{ + Q_ASSERT(m_declaration); + Q_ASSERT(m_varSlot > -1); +} + +template +DynamicContext::Ptr EvaluationCache::topFocusContext(const DynamicContext::Ptr &context) +{ + DynamicContext::Ptr result(context); + + while(true) + { + DynamicContext::Ptr candidate(result->previousContext()); + + /* We want the top focus, not GenericDynamicContext. */ + if(candidate && candidate->focusIterator()) + result = candidate; + else + return result; + } +} + +template +Item EvaluationCache::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + ItemCacheCell &cell = IsForGlobal ? context->globalItemCacheCell(m_varSlot) : context->itemCacheCell(m_varSlot); + + if(cell.cacheState == ItemCacheCell::Full) + return cell.cachedItem; + else + { + Q_ASSERT(cell.cacheState == ItemCacheCell::Empty); + cell.cachedItem = m_operand->evaluateSingleton(IsForGlobal ? topFocusContext(context) : context); + cell.cacheState = ItemCacheCell::Full; + return cell.cachedItem; + } +} + +#if defined(Q_OS_IRIX) && defined(Q_CC_MIPS) +/** + * @short Compile workaround for MIPSPro on IRIX. + * + * This function is never called. + * + * It's mere presence means the MIPSPro compiler can accept some other code below. + * + * I recommend Buddism. + */ +static inline Item::Iterator::Ptr workaroundIrixMIPSPro(const ItemSequenceCacheCell &cell) +{ + return Item::Iterator::Ptr(new ListIterator(cell.cachedItems)); +} +#endif + +template +Item::Iterator::Ptr EvaluationCache::evaluateSequence(const DynamicContext::Ptr &context) const +{ + ItemSequenceCacheCell::Vector &cells = IsForGlobal ? context->globalItemSequenceCacheCells(m_varSlot) : context->itemSequenceCacheCells(m_varSlot); + ItemSequenceCacheCell &cell = cells[m_varSlot]; + + + if(cell.inUse) + { + context->error(QtXmlPatterns::tr("Circularity detected"), + ReportContext::XTDE0640, this); + } + + switch(cell.cacheState) + { + case ItemSequenceCacheCell::Full: + { + /** + * We don't use makeListIterator() here because the MIPSPro compiler can't handle it. + */ + return Item::Iterator::Ptr(new ListIterator(cell.cachedItems)); + } + case ItemSequenceCacheCell::Empty: + { + cell.inUse = true; + cell.sourceIterator = m_operand->evaluateSequence(IsForGlobal ? topFocusContext(context) : context); + cell.cacheState = ItemSequenceCacheCell::PartiallyPopulated; + /* Fallthrough. */ + } + case ItemSequenceCacheCell::PartiallyPopulated: + { + cell.inUse = false; + Q_ASSERT_X(cells.at(m_varSlot).sourceIterator, Q_FUNC_INFO, + "This trigger for a cache bug which hasn't yet been analyzed."); + return Item::Iterator::Ptr(new CachingIterator(cells, m_varSlot, IsForGlobal ? topFocusContext(context) : context)); + } + default: + { + Q_ASSERT_X(false, Q_FUNC_INFO, "This path is not supposed to be run."); + return Item::Iterator::Ptr(); + } + } +} + +template +Expression::Ptr EvaluationCache::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + /* It's important that we do the typeCheck() before checking for the use of local variables, + * because ExpressionVariableReference can reference an expression that is a local variable, + * so it must rewrite itself to it operand before, and it does that in EvaluationCache::typeCheck(). */ + const Expression::Ptr me(SingleContainer::typeCheck(context, reqType)); + + OperandsIterator it(me, OperandsIterator::ExcludeParent); + Expression::Ptr next(it.next()); + + /* If our operand or any sub operand gets its value from a for-loop, we cannot + * cache it since then our cache would be filled -- but not invalidated -- on the + * first for-iteration. Consider this query: + * + * for $i in expr + * let $v := $i/p + * return ($v, $v) + * + * An evaluation cache is inserted for the two operands in the return clause. However, + * $i changes for each iteration so the cache can only be active on a per-iteration basis, + * it it's possible(which it isn't). + * + * This means that for some queries we don't cache what we really should, and hence evaluate + * in a sub-optimal way, since this DependsOnLocalVariable don't communicate whether it references + * a loop that affects us. The correct fix for this would be to let ForExpression reset the + * relevant caches only, but we don't know which ones that are. */ + while(next) + { + if(next->has(DependsOnLocalVariable)) + return m_operand->typeCheck(context, reqType); + + next = it.next(); + } + + return me; +} + +template +Expression::Ptr EvaluationCache::compress(const StaticContext::Ptr &context) +{ + const Expression::Ptr me(SingleContainer::compress(context)); + + if(me != this) + return me; + + if(m_operand->is(IDRangeVariableReference)) + return m_operand; + + if(m_declaration->usedByMany()) + { + /* If it's only an atomic value an EvaluationCache is overkill. However, + * it's still needed for functions like fn:current-time() that must adhere to + * query stability. */ + const Properties props(m_operand->properties()); + + if(props.testFlag(EvaluationCacheRedundant) || + ((props.testFlag(IsEvaluated)) && + !props.testFlag(DisableElimination) && + CommonSequenceTypes::ExactlyOneAtomicType->matches(m_operand->staticType()))) + { + return m_operand; + } + else + return me; + } + else + { + /* If we're only used once, there's no need for an EvaluationCache. */ + return m_operand; + } +} + +template +SequenceType::Ptr EvaluationCache::staticType() const +{ + return m_operand->staticType(); +} + +template +SequenceType::List EvaluationCache::expectedOperandTypes() const +{ + /* Remember that EvaluationCache::typeCheck() will be called from multiple locations, + * which potentially have different type requirements. For instance, one wants a node, + * and another requires atomization and casting. + * + * Returning ZeroOrMoreItems is safe here because staticType() returns the operand's type + * and therefore the convertors like Atomizer will be parents to us, and hence only affect + * the relevant path. + * + * ZeroOrMoreItems also make sense logically since we're actually only used where the + * variable references reference us. */ + SequenceType::List result; + result.append(CommonSequenceTypes::ZeroOrMoreItems); + + return result; +} + +template +Expression::Properties EvaluationCache::properties() const +{ + /* We cannot return the operand's properties unconditionally, because some + * doesn't hold for this Expression. + * + * However, some of the properties must propagate through, which are the ones being OR'd here. + */ + return m_operand->properties() & (DisableElimination | IsEvaluated | DisableTypingDeduction); +} + +template +ExpressionVisitorResult::Ptr +EvaluationCache::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +template +const SourceLocationReflection *EvaluationCache::actualReflection() const +{ + return m_operand->actualReflection(); +} + diff --git a/src/xmlpatterns/expr/qevaluationcache_p.h b/src/xmlpatterns/expr/qevaluationcache_p.h new file mode 100644 index 0000000..86aeaf8 --- /dev/null +++ b/src/xmlpatterns/expr/qevaluationcache_p.h @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_EvaluationCache_H +#define Patternist_EvaluationCache_H + +#include "qcachingiterator_p.h" +#include "qcommonsequencetypes_p.h" +#include "qnodebuilder_p.h" +#include "qoperandsiterator_p.h" +#include "qsinglecontainer_p.h" +#include "qvariabledeclaration_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Evaluates to the same result as its operand, but ensures the + * operand is evaluated once even if this Expression is evaluated several + * times. + * + * EvaluationCache does this in a pipelined way, by delivering items from + * its cache, which is stored in the DynamicContext. If the cache has less + * items than what the caller requests, EvaluationCache continues to + * deliver but this time from the source, which it also populates into the + * cache. + * + * EvaluationCache is used as an optimization in order to avoid running + * expensive code paths multiple times, but also is sometimes a necessity: + * for instance, when objects must be unique, such as potentially in the + * case of node identity. + * + * EvaluationCache is in particular used for variables, whose sole purpose + * is to store it once(at least conceptually) and then use it in multiple + * places. + * + * In some cases an EvaluationCache isn't necessary. For instance, when a + * variable is only referenced once. In those cases EvaluationCache removes + * itself as an optimization; implemented in compress(). + * + * @author Frans Englich + * @ingroup Patternist_expressions + */ + template + class EvaluationCache : public SingleContainer + { + public: + EvaluationCache(const Expression::Ptr &operand, + const VariableDeclaration::Ptr &varDecl, + const VariableSlotID slot); + + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + + virtual SequenceType::Ptr staticType() const; + + /** + * The first operand must be exactly one @c xs:string. + */ + virtual SequenceType::List expectedOperandTypes() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + virtual Properties properties() const; + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + virtual const SourceLocationReflection *actualReflection() const; + + inline VariableSlotID slot() const + { + return m_varSlot; + } + + private: + static DynamicContext::Ptr topFocusContext(const DynamicContext::Ptr &context); + const VariableDeclaration::Ptr m_declaration; + /** + * This variable must not be called m_slot. If it so, a compiler bug on + * HP-UX-aCC-64 is triggered in the constructor initializor. See the + * preprocessor output. + * + * Note that this is the cache slot, and is disjoint to any variable's + * regular slot. + */ + const VariableSlotID m_varSlot; + }; + +#include "qevaluationcache.cpp" +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qexpression.cpp b/src/xmlpatterns/expr/qexpression.cpp new file mode 100644 index 0000000..7a045e8 --- /dev/null +++ b/src/xmlpatterns/expr/qexpression.cpp @@ -0,0 +1,414 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qboolean_p.h" +#include "qcommonvalues_p.h" +#include "qemptysequence_p.h" +#include "qliteral_p.h" +#include "qliteralsequence_p.h" +#include "qoperandsiterator_p.h" +#include "qoptimizerframework_p.h" +#include "qstaticfocuscontext_p.h" +#include "qtypechecker_p.h" + +#include "qexpression_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Expression::~Expression() +{ +} + +StaticContext::Ptr Expression::finalizeStaticContext(const StaticContext::Ptr &context) const +{ + Q_ASSERT(context); + const ItemType::Ptr focusType(newFocusType()); + Q_ASSERT(focusType); + return StaticContext::Ptr(new StaticFocusContext(focusType, context)); +} + +Expression::Ptr Expression::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + Q_ASSERT(reqType); + typeCheckOperands(context); + return TypeChecker::applyFunctionConversion(Expression::Ptr(this), reqType, context); +} + +void Expression::typeCheckOperands(const StaticContext::Ptr &context) +{ + const Expression::List ops(operands()); + + /* Check if this expression has any operands at all. */ + if(ops.isEmpty()) + return; /* We're done, early exit. */ + + const SequenceType::List opTypes(expectedOperandTypes()); + Expression::List result; + + /* If we create a focus, we handle the last one specially, so avoid it in the loop. */ + const bool createsFocus = has(CreatesFocusForLast); + const SequenceType::List::const_iterator typeEnd(createsFocus ? --opTypes.constEnd() + : opTypes.constEnd()); + const Expression::List::const_iterator end(createsFocus ? --ops.constEnd() + : ops.constEnd()); + + SequenceType::List::const_iterator reqType(opTypes.constBegin()); + SequenceType::Ptr t(*reqType); + // TODO we assign twice to t here(also below in loop) when ops.size() > 1 + + Expression::List::const_iterator it(ops.constBegin()); + + for(; it != end; ++it) + { + /* This ensures that the last expectedOperandType stays, and is + * used for all other operands. This is used for expressions that + * have an infinite amount of operands, such as the concat() function. */ + if(reqType != typeEnd) + { + t = *reqType; + ++reqType; + } + + /* Let the child & its children typecheck. */ + result.append((*it)->typeCheck(context, t)); + } + + if(createsFocus) + { + const StaticContext::Ptr newContext(finalizeStaticContext(context)); + result.append(ops.last()->typeCheck(newContext, opTypes.last())); + } + + setOperands(result); +} + +Expression::Ptr Expression::invokeOptimizers(const Expression::Ptr &expr, + const StaticContext::Ptr &context) +{ + Q_ASSERT(expr); + + const OptimizationPass::List opts(expr->optimizationPasses()); + + if(opts.isEmpty()) /* Early exit. */ + { + return expr; + } + + const OptimizationPass::List::const_iterator passEnd(opts.constEnd()); + const OptimizationPass::List::const_iterator end(opts.constEnd()); + OptimizationPass::List::const_iterator passIt(opts.constBegin()); + + for(; passIt != passEnd; ++passIt) /* Invoke each optimization pass. */ + { + const OptimizationPass::Ptr pass(*passIt); /* Alias, for readability. */ + OptimizationPass::ExpressionMarker sourceMarker(pass->sourceExpression); + + if(pass->startIdentifier && !pass->startIdentifier->matches(expr)) + { + /* This pass specified a start identifier and it did + * not match -- let's try the next OptimizationPass. */ + continue; + } + + const ExpressionIdentifier::List::const_iterator idEnd(pass->operandIdentifiers.constEnd()); + ExpressionIdentifier::List::const_iterator idIt(pass->operandIdentifiers.constBegin()); + const Expression::List ops(expr->operands()); + const Expression::List::const_iterator opEnd(ops.constEnd()); + Expression::List::const_iterator opIt(ops.constBegin()); + + switch(pass->operandsMatchMethod) + { + case OptimizationPass::Sequential: + { + for(; opIt != opEnd; ++opIt) + { + const Expression::Ptr operand(*opIt); /* Alias, for readability. */ + const ExpressionIdentifier::Ptr opIdentifier(*idIt); /* Alias, for readability. */ + if(opIdentifier && !opIdentifier->matches(operand)) + { + break; + } + + ++idIt; + } + + if(opIt == opEnd) + break; /* All operands matched, so this pass matched. */ + else + { + /* The loop above did not finish which means all operands did not match. + Therefore, this OptimizationPass did not match -- let's try the next one. */ + continue; + } + } + case OptimizationPass::AnyOrder: + { + Q_ASSERT_X(ops.count() == 2, Q_FUNC_INFO, + "AnyOrder is currently only supported for Expressions with two operands."); + if(pass->operandIdentifiers.first()->matches(ops.first()) && + pass->operandIdentifiers.last()->matches(ops.last())) + { + break; + } + else if(pass->operandIdentifiers.first()->matches(ops.last()) && + pass->operandIdentifiers.last()->matches(ops.first())) + { + sourceMarker.first() = 1; + sourceMarker[1] = 0; + break; /* This pass matched. */ + } + else + continue; /* This pass didn't match, let's loop through the next pass. */ + } + } + + /* Figure out the source Expression, if any. */ + Expression::List operands; + Expression::Ptr sourceExpr; + + if(!sourceMarker.isEmpty()) + { + const OptimizationPass::ExpressionMarker::const_iterator mEnd(sourceMarker.constEnd()); + OptimizationPass::ExpressionMarker::const_iterator mIt(sourceMarker.constBegin()); + sourceExpr = expr; + + for(; mIt != mEnd; ++mIt) + { + Q_ASSERT(*mIt >= 0); + sourceExpr = sourceExpr->operands().at(*mIt); + } + + operands.append(sourceExpr); + } + + if(operands.isEmpty()) + { + Q_ASSERT(pass->resultCreator); + return pass->resultCreator->create(Expression::List(), context, expr.data())->compress(context); + } + else if(pass->resultCreator) + return pass->resultCreator->create(operands, context, expr.data())->compress(context); + else + { + return sourceExpr; + } + } + + return expr; +} + +Expression::Ptr Expression::compress(const StaticContext::Ptr &context) +{ + if(!compressOperands(context)) + { + /* At least one of the operands cannot be evaluated at compile, so + * 'this' Expression cannot const fold. */ + return invokeOptimizers(Expression::Ptr(this), context); + } + + Expression::Ptr retval; + + if(hasDependency(DisableElimination)) + retval = Expression::Ptr(this); + else + retval = constantPropagate(context); + + return invokeOptimizers(retval, context); +} + +Expression::Ptr Expression::constantPropagate(const StaticContext::Ptr &context) const +{ + Q_ASSERT(context); + + /* Optimization: We rewrite literals to literals here, which is pointless. + * Maybe we should have a property which says "doesn't disable elimination + * but don't eliminate me." */ + if(staticType()->cardinality().allowsMany()) + { + Item::Iterator::Ptr it(evaluateSequence(context->dynamicContext())); + Item::List result; + Item item(it->next()); + + while(item) + { + result.append(item); + item = it->next(); + } + + switch(result.count()) + { + case 0: + return EmptySequence::create(this, context); + case 1: + return rewrite(Expression::Ptr(new Literal(result.first())), context); + default: + return rewrite(Expression::Ptr(new LiteralSequence(result)), context); + } + } + else + { + const Item item(evaluateSingleton(context->dynamicContext())); + + if(item) + return rewrite(Expression::Ptr(new Literal(item)), context); + else + return EmptySequence::create(this, context); + } +} + +Item::Iterator::Ptr Expression::evaluateSequence(const DynamicContext::Ptr &context) const +{ + const Item item(evaluateSingleton(context)); + + if(item) + return makeSingletonIterator(item); + else + return CommonValues::emptyIterator; +} + +Item Expression::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + return Boolean::fromValue(evaluateEBV(context)); +} + +bool Expression::evaluateEBV(const DynamicContext::Ptr &context) const +{ + return Boolean::evaluateEBV(evaluateSequence(context), context); +} + +void Expression::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const +{ + QAbstractXmlReceiver *const receiver = context->outputReceiver(); + const Item::Iterator::Ptr it(evaluateSequence(context)); + Item next(it->next()); + + while(next) + { + receiver->item(next); + next = it->next(); + } +} + +ItemType::Ptr Expression::expectedContextItemType() const +{ + Q_ASSERT_X(false, Q_FUNC_INFO, + "expectedContextItemType() must be overridden when RequiresContextItem is set."); + return ItemType::Ptr(); +} + +Expression::Properties Expression::properties() const +{ + return Properties(); +} + +Expression::Properties Expression::dependencies() const +{ + OperandsIterator it(Ptr(const_cast(this)), OperandsIterator::ExcludeParent); + Expression::Ptr next(it.next()); + + Properties dependencies(properties()); + + while(next) + { + dependencies |= next->dependencies(); + next = it.next(); + } + + return dependencies & (Expression::RequiresFocus | Expression::IsEvaluated | Expression::DisableElimination); +} + +void Expression::announceFocusType(const ItemType::Ptr &itemType) +{ + const Expression::List ops(operands()); + const int len = ops.count(); + + for(int i = 0; i < len; ++i) + ops.at(i)->announceFocusType(itemType); +} + +Expression::Properties Expression::deepProperties() const +{ + Properties props(properties()); + const Expression::List ops(operands()); + const int len = ops.count(); + + for(int i = 0; i < len; ++i) + props |= ops.at(i)->deepProperties(); + + return props; +} + +Expression::ID Expression::id() const +{ + return IDIgnorableExpression; +} + +OptimizationPass::List Expression::optimizationPasses() const +{ + return OptimizationPass::List(); +} + +ItemType::Ptr Expression::newFocusType() const +{ + Q_ASSERT_X(false, Q_FUNC_INFO, + "This function must be overridden when CreatesFocusForLast is set."); + return ItemType::Ptr(); +} + +const SourceLocationReflection *Expression::actualReflection() const +{ + return this; +} + +QString Expression::description() const +{ + return QString::fromLatin1("Expression, id: %1").arg(QString::number(id())); +} + +PatternPriority Expression::patternPriority() const +{ + return 0.5; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qexpression_p.h b/src/xmlpatterns/expr/qexpression_p.h new file mode 100644 index 0000000..8bf37df --- /dev/null +++ b/src/xmlpatterns/expr/qexpression_p.h @@ -0,0 +1,909 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_Expression_H +#define Patternist_Expression_H + +#include +#include + +#include "qcppcastinghelper_p.h" +#include "qdebug_p.h" +#include "qdynamiccontext_p.h" +#include "qexpressiondispatch_p.h" +#include "qitem_p.h" +#include "qsequencetype_p.h" +#include "qsourcelocationreflection_p.h" +#include "qstaticcontext_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +template class QList; +template class QVector; + +namespace QPatternist +{ + template class ListIterator; + class OptimizationPass; + + /** + * @short Base class for all AST nodes in an XPath/XQuery/XSL-T expression. + * + * @section ExpressionCreation Expression Compilation + * + * @subsection ExpressionCreationParser The process of creating an Expression + * + * The initial step of creating an internal representation(in some circles + * called an IR tree) of the XPath string follows classic compiler design: a scanner + * is invoked, resulting in tokens, which sub-sequently are consumed by a parser + * which groups the tokens into rules, resulting in the creation of + * Abstract Syntax Tree(AST) nodes that are arranged in a hierarchical structure + * similar to the EBNF. + * + * More specifically, ExpressionFactory::createExpression() is called with a + * pointer to a static context, and the string for the expression. This is subsequently + * tokenized by a Flex scanner. Mistakes detected at this stage is syntax + * errors, as well as a few semantical errors. Syntax errors can be divided + * in two types: + * + * - The scanner detects it. An example is the expression "23Eb3" which + * is not a valid number literal, or "1prefix:my-element" which is not a + * valid QName. + * - The parser detects it. This means a syntax error at a + * higher level, that a group of tokens couldn't be reduced to a + * rule(expression). An example is the expression "if(a = b) 'match' else + * 'no match'"; the tokenizer would handle it fine, but the parser would + * fail because the tokens could not be reduced to a rule due to the token + * for the "then" word was missing. + * + * Apart from the syntax errors, the actions in the parser also detects + * errors when creating the corresponding expressions. This is for example + * that no namespace binding for a prefix could be found, or that a function + * call was used which no function implementation could be found for. + * + * When the parser has finished, the result is an AST. That is, a + * hierarchical structure consisting of Expression sub-classes. The + * individual expressions haven't at this point done anything beyond + * receiving their child-expressions(if any), and hence reminds of a + * "construction scaffold". In other words, a tree for the expression + * 'string' + 1 and xs:date('2001-03-13') could have been created, even if + * that expression contains errors(one can't add a xs:integer to a xs:string, + * and the Effective %Boolean Value cannot be extracted for date types). + * + * @subsection ExpressionCreationTypeChecking Type Checking + * + * After the AST creation, ExpressionFactory::createExpression continues with + * calling the AST node(which is an Expression instance)'s typeCheck() + * function. This step ensures that the static types of the operands matches + * the operators, and in the cases where it doesn't, modifies the AST such + * that the necessary conversions are done -- if possible, otherwise the + * result is a type error. + * + * + * This step corresponds roughly to what 2.2.3.1 Static Analysis Phase + * labels operation tree normalization; step SQ5. + * + * @subsection ExpressionCreationCompression Compressing -- Optimization and Fixup + * + * The last step is calling compress(). This function is not called + * 'optimize', 'simplify' or the like, because although it performs all + * optimization, it also involves mandatory stages. + * + * One such is const folding, which while being an efficient optimization, + * also is a necessity for many XSL-T constructs. Another important step is + * that functions which had an evaluation dependency on the static context(as + * opposed to the dynamic) performs their "fixup". + * + * In other words, this stage potentially performs AST re-writes. For example, + * the expression 3 + 3, concat('foo', '-', 'bar'), true() and false() would + * result in an AST corresponding to 6, 'foo-bar', false(). This process + * is done backwards; each expression asks its operands to compress before it + * performs its own compression(and so forth, until the root expression's call + * returns to the caller). + * + * @see XML Path Language + * (XPath) 2.0, 2.3.4 Errors and Optimization + * @see XML Path + * Language (XPath) 2.0, 2.2.3 Expression Processing + * @see Building a Tokenizer + * for XPath or XQuery + * @see ExpressionFactory + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class Q_AUTOTEST_EXPORT Expression : public QSharedData + , public CppCastingHelper + , public SourceLocationReflection + { + public: + /** + * @short A smart pointer wrapping mutable Expression instances. + */ + typedef QExplicitlySharedDataPointer Ptr; + + /** + * @short A smart pointer wrapping @c const Expression instances. + */ + typedef QExplicitlySharedDataPointer ConstPtr; + + /** + * A list of Expression instances, each wrapped in a smart pointer. + */ + typedef QList List; + + /** + * A vector of Expression instances, each wrapped in a smart pointer. + */ + typedef QVector Vector; + + typedef QT_PREPEND_NAMESPACE(QAbstractXmlForwardIterator) + QAbstractXmlForwardIterator; + + /** + * Enum flags describing the characteristics of the expression. + * + * @see Expression::properties() + */ + enum Property + { + /** + * This flag applies for functions, and results in the expression . + * being appended to its operands if its operand count is lower than the + * maximum amount of arguments. + * + * In effect, it result in a modification of the function's arguments to have + * appended the context item. + * + * One function which has this property is fn:number(). + * + * @see ContextItem + * @see XQuery 1.0 and + * XPath 2.0 Functions and Operators, 1.3 Function Signatures and Descriptions + */ + UseContextItem = 1, + + /** + * Disables compression(evaluation at compile time), such that the + * Expression isn't const-folded, but ensured to be run at runtime. The + * operands are still attempted to be compressed, unless + * they override compression as well. + * + * @see compress() + */ + DisableElimination = 1 << 1, + + /** + * Signals that the expression is already evaluated and can be considered + * a constant value. + * For example, atomic values return this flag in their + * implementations of the properties() functions. + * + * @see isEvaluated() + */ + IsEvaluated = 1 << 2, + + /** + * Signals that the expression cannot be optimized away by judging + * its static type. + * + * This is currently used for properly handling the @c none type, in + * the fn:error() function. In type operations, the none type doesn't show + * up and that can make expressions, such as InstanceOf, believe + * it is safe to const fold, while it in fact is not. + */ + DisableTypingDeduction = 1 << 3, + + /** + * This property affects the static type -- staticType() -- of an expression. It + * is implemented in FunctionCall::staticType() and therefore only work for FunctionCall + * sub-classes and when that function is not re-implemented in an inhibiting way. + * + * When set, the cardinality of the static type is zero if the Expression's first + * operand allows an empty sequence, otherwise it is the cardinality of the Expression's + * static type modulo Cardinality::empty(). This is used for specifying proper static + * type inference for functions that have "If $arg is the empty sequence, + * the empty sequence is returned." However, before setting this property one + * must be aware that no other conditions can lead to the empty sequence, since + * otherwise the static type would be wrong. + */ + EmptynessFollowsChild = 1 << 4, + + /** + * This is similar to EmptynessFollowsChild, and also implemented in FunctionCall. + * When set, it makes FunctionCall::typeCheck() rewrite itself into an empty sequence + * if the first operand is the empty sequence. + * + * This property is often used together with EmptynessFollowsChild. + */ + RewriteToEmptyOnEmpty = 1 << 5, + + /** + * When set, it signals that the focus cannot be undefined. For example, + * the fn:position() function extracts information from the focus. Setting + * this flag ensures type checking is carried out appropriately. + * + * However, setting RequiresFocus does not imply this Expression requires the context + * item to be defined. It only means the focus, of somekind, needs to be defined. + * + * @see RequiresContextItem + */ + RequiresFocus = 1 << 6, + + /** + * An Expression with this Property set, signals that it only affects + * the order of its return value. + */ + AffectsOrderOnly = 1 << 7, + + /** + * When set, signals that the context item, must be defined for this Expression. When + * setting this property, expectedContextItemType() must be re-implemented. + * + * Setting this property also sets RequiresFocus. + * + * @see DynamicContext::contextItem() + */ + RequiresContextItem = (1 << 8) | RequiresFocus, + + /** + * When set, signals that this expression creates a focus for its last operand. + * When set, newFocusType() must be overridden to return the static type + * of the context item. + * + * @see announceFocusType() + * @see newFocusType() + */ + CreatesFocusForLast = 1 << 9, + + /** + * Signals that the last operand is a collation argument. This ensures + * that the necessary code is generated for checking that the collation + * is supported. + * + * This only applies to sub-classes of FunctionCall. + */ + LastOperandIsCollation = 1 << 10, + + /** + * When set, the Expression depends on local variables such as + * those found in @c for expressions. However, this does not + * include let bindings. + */ + DependsOnLocalVariable = (1 << 11) | DisableElimination, + + /** + * When set, it signals that the Expression does not need + * an evaluation cache, despite what other flags might imply. + */ + EvaluationCacheRedundant = (1 << 12), + + /** + * Signals that the Expression constructs nodes, either directly + * or computationally. For example, AttributeConstructor has this property + * set. + * + * Since node constructors constructs nodes which have node + * identities, node constructors are considered creative on + * evaluation. + */ + IsNodeConstructor = 1 << 13, + + /** + * Whether this expression requires the current item, as returned + * from @c fn:current(). + * + * CurrentFN uses this flag. + */ + RequiresCurrentItem = 1 << 14 + }; + + /** + * A QFlags template for type-safe handling of ExpressionProperty values. If + * Expression::Property flags needs to be stored in a class, declared the variable + * to be of type Expression::Properties. + * + * @see QFlags + */ + typedef QFlags Properties; + + /** + * Enumerators that identifies Expression sub-classes. + * + * @see id() + */ + enum ID + { + /** + * Identifies Boolean. + */ + IDBooleanValue = 1, + + /** + * Identifies CountFN. + */ + IDCountFN, + + /** + * Identifies EmptyFN. + */ + IDEmptyFN, + + /** + * Identifies ExistsFN. + */ + IDExistsFN, + + /** + * Identifies ExpressionSequence and LiteralSequence. + */ + IDExpressionSequence, + + /** + * Identifies GeneralComparison. + */ + IDGeneralComparison, + + /** + * Identifies IfThenClause. + */ + IDIfThenClause, + + /** + * Identifies nothing in particular. The default implementation + * of id() returns this, which is suitable for Expression instances + * which never needs to be identified in this aspect. + */ + IDIgnorableExpression, + + /** + * Identifies Integer. + */ + IDIntegerValue, + + /** + * Identifies PositionFN. + */ + IDPositionFN, + + /** + * Identifies AtomicString, AnyURI, and UntypedAtomic. + */ + IDStringValue, + + /** + * Identifies ValueComparison. + */ + IDValueComparison, + + /** + * Identifies VariableReference. + */ + IDRangeVariableReference, + + /** + * Identifies ContextItem. + */ + IDContextItem, + + /** + * Identifies UserFunctionCallsite. + */ + IDUserFunctionCallsite, + + /** + * Identifies ExpressionVariableReference. + */ + IDExpressionVariableReference, + + /** + * Identifies ExpressionVariableReference. + */ + IDAttributeConstructor, + + /** + * Identifies UpperCaseFN. + */ + IDUpperCaseFN, + + /** + * Identifies LowerCaseFN. + */ + IDLowerCaseFN, + + /** + * Identifies FirstItemPredicate. + */ + IDFirstItemPredicate, + IDEmptySequence, + IDReturnOrderBy, + IDLetClause, + IDForClause, + IDPath, + IDNamespaceConstructor, + IDArgumentReference, + IDGenericPredicate, + IDAxisStep, + + /** + * A literal which is either @c xs:float or + * @c xs:double. + */ + IDFloat, + + IDCombineNodes, + IDUnresolvedVariableReference, + IDCardinalityVerifier + }; + + inline Expression() + { + } + virtual ~Expression(); + + /** + * Evaluate this Expression by iterating over it. This is a central function + * for evaluating expressions. + * + * Expressions must always always return a valid QAbstractXmlForwardIterator and may + * never return 0. If an empty result is of interest to be returned, the + * EmptyIterator should be returned. + * + * The default implementation returns a SingletonIterator over the + * item returned from evaluateSingleton(). + * + * @note This function may raise an exception when calling, not only + * when QAbstractXmlForwardIterator::next() is called on the return value. This is because + * in some cases evaluateSingleton() is called directly. + */ + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + + /** + * @todo Docs + */ + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + + /** + * Determines the Effective %Boolean Value of the expression. + * + * The Effective %Boolean Value of a value is not necessarily the same + * as converting the value to a new value of type xs:boolean. + * + * Note that this function cannot return the empty sequence, + * evaluateSingleton() must be overridden in order to be able to do + * that. + * + * The default implementation results in a type error. Hence, this function + * must be overridden if such behavior is not of interest. + * + * @see XML Path Language (XPath) 2.0, + * 2.4.3 Effective Boolean Value + */ + virtual bool evaluateEBV(const DynamicContext::Ptr &context) const; + + /** + * Evaluates this Expression by sending its output to DynamicContext::outputReceiver(). + */ + virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const; + + /** + * @returns the expression's child expressions. For example, a function's + * arguments is returned here. + * + * If this Expression has no operands, an empty list should be returned. + */ + virtual Expression::List operands() const = 0; + + virtual void setOperands(const Expression::List &operands) = 0; + + /** + * @returns the static type of this Expression. For example, an 'and' expression + * have as static type xs:boolean + */ + virtual SequenceType::Ptr staticType() const = 0; + + /** + * Returns a list of Sequence Types, describing the type of each of the + * expression's operands. Hence, this function has a relationship to + * the operands() function: + * + * - The lengths of the lists returned by expectedOperandTypes() + * and operands() should always be equal in length, since one + * cannot describe the type of a non-existent operand(and all + * operands must have type information). + * - A significant difference between the two functions is that while + * the type of objects in the list returned by operands() may vary + * between compilations/static context, simply because the particular + * Expression is part of different XPath expressions, the + * types in the list returned by expectedOperandTypes is always the same + * since the function/operator signature never changes. + * + * This function should not be confused with staticType(), + * which returns the static type of the expression itself, not its operands. The + * function call is an expression where this is clear: the type of the return + * value is not the same as the arguments' types. The static type of the + * operands supplied to the expression can be determined via the staticType() + * function of the instances returned by operands(). + * + * If the expression has no operands, an empty list should be returned. + */ + virtual SequenceType::List expectedOperandTypes() const = 0; + + /** + * This implementation guarantees to never rewrite away this Expression, but + * at most rewrite it as a child of another expression(that presumably have a + * type checking role). It is therefore always safe to override this + * function and call this implementation and not worry about that this Expression + * becomes deleted. + * + * Many Expressions override typeCheck() and performs optimizations, as opposed + * to doing it in the compress() stage. This is due to that the design + * of those Expressions often are tied to that certain simplifications + * are done at the typeCheck() stage of the compilation process or that + * it in some other way is related to what the typeCheck() do. Also, the earlier + * the AST can be simplified, the better the chances are for subsequent + * optimizations. + * + * It is important that the super class's typeCheck() is called before doing + * any custom type checking, since the call can change the children(notably, + * the childrens' static types). For example, if the Expression, MyExpression + * in the example, does not match the required type, typeCheck returns the Expression + * wrapped in for example ItemVerifier, CardinalityVerifier, or both. + * + * typeCheck() may be called many times. typeCheck() must either raise an error + * if this Expression is an invalid expression. Thus, it is guaranteed that an Expression + * is valid after typeCheck() is called. + * + * @param context supplies information, such as namespace bindings and + * available function signatures, that can be needed at compilation time. @p context is + * guaranteed by the caller to never null. + * @param reqType the static type that this Expression must match when evaluated. @p reqType is + * guaranteed by the caller to never null. + * @returns an Expression that can be this Expression, or another expression, + * which somehow is necessary for making this Expression conforming to + * @p reqType + */ + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + /** + * compress() is the last stage performs in compiling an expression, done after + * the initial AST build and calling typeCheck(). compress() performs crucial + * simplifications, either by having drastic performance implications or that + * some expressions depend on it for proper behavior. + * + * The default implementation performs a sparse conditional constant + * propagation. In short, a recursive process is performed in the AST + * which examines if the Expression's operands are constant values, and if so, + * performs a const fold(AST rewrite) into the result of evaluating the expression + * in question. This default behavior can be disabled by letting properties() return + * DisableElimination. + * + * This compress() stage can be relative effective due to the design of XPath, in + * part because intrinsic functions are heavily used. Many Expressions override compress() + * and do optimizations specific to what they do. Also, many Expressions performs + * optimizations in their typeCheck(). + * + * @param context the static context. Supplies compile time information, and is + * the channel for communicating error messages. + * @see Wikipedia, + * the free encyclopedia, Sparse conditional constant propagation + * @see Wikipedia, + * the free encyclopedia, Intrinsic function + * @see Wikipedia, the + * free encyclopedia, Compiler optimization + */ + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + + /** + * @returns a bitwise OR'd value of properties, describing the + * characteristics of the expression. These properties affects how + * this Expression is treated in for example type checking stages. + * + * The default implementation returns 0. Override and let the function return + * a different value, if that's of interest. + * + * An important decision when re-implementing properties() is whether + * to OR in the properties() of ones operands. For instance, if an + * operand has RequiresFocus set, that flag nost likely applies to the + * apparent as well, since it depends on its operand. + * + * @see deepProperties() + * @returns Expression::None, meaning no special properties + */ + virtual Properties properties() const; + + /** + * Recursively computes through all descendants until a Property + * is encount + */ + virtual Properties dependencies() const; + + /** + * @short Computes the union of properties for this Expression and all + * its descending children. + * + * @see properties() + */ + Properties deepProperties() const; + + /** + * This function is a utility function, which performs bitwise logic + * on properties() in order to find out whether the Expression::IsEvaluated + * flag is set. + * + * @note Do not attempt to re-implement this function. Instead, return the + * IsEvaluated flag by re-implementing the properties() function. + */ + inline bool isEvaluated() const; + + /** + * This function is a utility function, syntactic sugar for determining + * whether this Expression is @p id. For example, calling is(IDIfThenClause) + * is equivalent to id() == IDIfThenClause + * + * @note Do not attempt to re-implement this function. Instead, return the + * appropriate flag in the virtual id() function. + */ + inline bool is(const ID id) const; + + /** + * Determines whether this Expression has Property @p prop set. + * + * Calling expr->has(MyProperty) is semantically equivalent + * to expr->properties().testFlag(MyProperty). In + * other words, has(), as well as is(), provides syntacti sugar + * and makes code more readable. + * + * @note Do not attempt to re-implement this function. Instead, return + * the appropriate flag by re-implementing the properties() function. + */ + inline bool has(const Property prop) const; + + inline bool hasDependency(const Property prop) const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const = 0; + + /** + * This property, which has no setter, returns an enum value that uniquely identifies + * this Expression. Patternist makes no use of C++'s dynamic_cast feature, but uses this + * polymorphic function instead. + * + * @returns always IgnorableExpression. + */ + virtual ID id() const; + + /** + * Returns the OptimizationPasses that applies for this Expression. The + * default implementation returns an empty list. Sub-classes can re-implement + * this function and return actual OptimizationPasses. + * + * @returns always an empty list. + */ + virtual QList > optimizationPasses() const; + + /** + * Returns the required type the context item must be an instance of. + * + * If this Expression requires a focus, meaning its properties() + * function returns RequiresContextItem, + * it must return a type from this function. If any type is ok, BuiltinTypes::item should be + * returned. + * + * In other words, this function must only be re-implemented if the focus is used. The default + * implementation performs an assert crash. + */ + virtual ItemType::Ptr expectedContextItemType() const; + + /** + * If an Expression creates a focus because it has set the property CreatesFocusForLast, + * it should override this function and make it return the ItemType that + * the context item in the focus has. + * + * @returns never @c null. + * @see announceFocusType() + */ + virtual ItemType::Ptr newFocusType() const; + + /** + * @short Returns @c this. + */ + virtual const SourceLocationReflection *actualReflection() const; + + /** + * Reimplementation of SourceLocationReflection::description(). + */ + virtual QString description() const; + + /** + * When this function is called, it signals that the parent will create + * a focus of type @p itemType. + * + * This type can also be retrieved through StaticContext::contextItemType() + * when inside typeCheck(), but in some cases this is too late. For + * instance, a parent needs to have the static type of its child + * properly reported before it calls its typeCheck()(and the child's + * type is inferred from the focus). + * + * The default implementation delegates the call on to the children. + * + * This function may be called at arbitrary times, in arbitrary + * amounts. + * + * If the AST node overriding this call has children, it should be + * considered whether the default implementation should be called, such + * that they type is announced to them too. + * + * The caller guarantees that @p itemType is not @c null. + */ + virtual void announceFocusType(const ItemType::Ptr &itemType); + + /** + * This function take the two Expression pointers @p old and @p New, and + * in a safe way, by handling reference counting and being aware of whether + * the two pointers actually are different, switches the two. When compiling + * in debug mode, informative debug messages are printed. + * + * This function is conceptually similar to Qt's qSwap(), but has + * debugging functionality and also handles source locations. + */ + static inline void rewrite(Expression::Ptr &old, + const Expression::Ptr &New, + const StaticContext::Ptr &context); + + /** + * @short Rewrites this Expression to @p to, and return @p to. + * + * Source location annotations are adjusted appropriately. + */ + inline const Expression::Ptr &rewrite(const Expression::Ptr &to, + const StaticContext::Ptr &context) const; + + /** + * By default 0.5 is returned. + */ + virtual PatternPriority patternPriority() const; + + protected: + + /** + * @returns @c true if all operands are constant values of somekind, and are already + * evaluated. A string literal, is a typical example. + */ + virtual bool compressOperands(const StaticContext::Ptr &) = 0; + + void typeCheckOperands(const StaticContext::Ptr &context); + + private: + static Expression::Ptr invokeOptimizers(const Expression::Ptr &expr, + const StaticContext::Ptr &context); + /** + * @return a StaticContext that has adopted the context item type properly + * for this Expression. + */ + inline StaticContext::Ptr finalizeStaticContext(const StaticContext::Ptr &context) const; + + /** + * @short Performs constant propagation, also called constant folding, on this expression. + * + * This means that it attempts to evaluate this expression at compile and returns the result value + * appropriately as an Expression. For example, for the XPath expression + * 1 + 3 would an Integer of value 4 would be returned. + * + * It is not checked whether constant propagation is possible, the + * caller is responsible for this. + * + * @see Constant folding, + * From Wikipedia, the free encyclopedia + */ + Expression::Ptr constantPropagate(const StaticContext::Ptr &context) const; + + Q_DISABLE_COPY(Expression) + }; + + Q_DECLARE_OPERATORS_FOR_FLAGS(Expression::Properties) + + inline bool Expression::is(const Expression::ID i) const + { + return id() == i; + } + + inline bool Expression::isEvaluated() const + { + return has(IsEvaluated); + } + + inline bool Expression::has(const Expression::Property prop) const + { + return properties().testFlag(prop); + } + + inline bool Expression::hasDependency(const Expression::Property prop) const + { + return dependencies().testFlag(prop); + } + + inline void Expression::rewrite(Expression::Ptr &old, + const Expression::Ptr &New, + const StaticContext::Ptr &context) + { + Q_ASSERT(old); + Q_ASSERT(New); + + if(old != New) + { + pDebug() << "AST REWRITE:" << old.data() << "to" << New.data() + << '(' << old->actualReflection() << "to" << New->actualReflection() << ", " + << old->description() << "to" << New->description() << ')'; + + /* The order of these two lines is significant.. */ + context->addLocation(New.data(), context->locationFor(old->actualReflection())); + old = New; + } + } + + inline const Expression::Ptr &Expression::rewrite(const Expression::Ptr &to, + const StaticContext::Ptr &context) const + { + context->addLocation(to.data(), context->locationFor(this)); + return to; + } +} + +Q_DECLARE_TYPEINFO(QPatternist::Expression::Ptr, Q_MOVABLE_TYPE); + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qexpressiondispatch_p.h b/src/xmlpatterns/expr/qexpressiondispatch_p.h new file mode 100644 index 0000000..23b2408 --- /dev/null +++ b/src/xmlpatterns/expr/qexpressiondispatch_p.h @@ -0,0 +1,241 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ExpressionDispatch_H +#define Patternist_ExpressionDispatch_H + +#include + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + class AndExpression; + class ApplyTemplate; + class ArgumentConverter; + class ArgumentReference; + class ArithmeticExpression; + class Atomizer; + class AttributeConstructor; + class AttributeNameValidator; + class AxisStep; + class CallTemplate; + class CardinalityVerifier; + class CardinalityVerifier; + class CastableAs; + class CastableAs; + class CastAs; + class CastAs; + class CollationChecker; + class CollationChecker; + class CombineNodes; + class CombineNodes; + class CommentConstructor; + class CommentConstructor; + class ComputedNamespaceConstructor; + class ContextItem; + class CopyOf; + class CurrentItemStore; + class DocumentConstructor; + class DynamicContextStore; + class EBVExtractor; + class ElementConstructor; + class EmptySequence; + class ExpressionSequence; + class ExpressionVariableReference; + class ExternalVariableReference; + class FirstItemPredicate; + class ForClause; + class FunctionCall; + class GeneralComparison; + class GenericPredicate; + class IfThenClause; + class InstanceOf; + class ItemVerifier; + class LetClause; + class Literal; + class LiteralSequence; + class NamespaceConstructor; + class NCNameConstructor; + class NodeComparison; + class NodeSortExpression; + class OrderBy; + class OrExpression; + class ParentNodeAxis; + class Path; + class PositionalVariableReference; + class ProcessingInstructionConstructor; + class QNameConstructor; + class QuantifiedExpression; + class RangeExpression; + class RangeVariableReference; + class ReturnOrderBy; + class SimpleContentConstructor; + class StaticBaseURIStore; + class StaticCompatibilityStore; + class TemplateParameterReference; + class TextNodeConstructor; + class TreatAs; + class TruthPredicate; + class UnresolvedVariableReference; + class UntypedAtomicConverter; + class UserFunctionCallsite; + class ValidationError; + class ValueComparison; + template class EvaluationCache; + + /** + * @todo Documentation's missing + * + * @defgroup Patternist_expr_dispatch Expression Dispatching + */ + + /** + * @ingroup Patternist_expr_dispatch + * @author Frans Englich + */ + class ExpressionVisitorResult : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer Ptr; + ExpressionVisitorResult() {} + virtual ~ExpressionVisitorResult() {} + }; + + /** + * @ingroup Patternist_expr_dispatch + * @author Frans Englich + */ + class ExpressionVisitor : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer Ptr; + virtual ~ExpressionVisitor() {} + + virtual ExpressionVisitorResult::Ptr visit(const AndExpression *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const ApplyTemplate *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const ArgumentConverter *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const ArgumentReference *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const ArithmeticExpression *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const Atomizer *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const AttributeConstructor *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const AttributeNameValidator *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const AxisStep *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const CallTemplate *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const CardinalityVerifier *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const CastableAs *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const CastAs *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const CollationChecker *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const CombineNodes *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const CommentConstructor *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const ComputedNamespaceConstructor *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const ContextItem *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const CopyOf *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const CurrentItemStore *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const DocumentConstructor *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const DynamicContextStore *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const EBVExtractor *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const ElementConstructor *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const EmptySequence *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const EvaluationCache *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const EvaluationCache *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const ExpressionSequence *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const ExpressionVariableReference *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const ExternalVariableReference *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const FirstItemPredicate *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const ForClause *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const FunctionCall *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const GeneralComparison *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const GenericPredicate *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const IfThenClause *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const InstanceOf *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const ItemVerifier *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const LetClause *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const Literal *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const LiteralSequence *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const NamespaceConstructor *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const NCNameConstructor *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const NodeComparison *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const NodeSortExpression *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const OrderBy *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const OrExpression *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const ParentNodeAxis *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const Path *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const PositionalVariableReference *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const ProcessingInstructionConstructor *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const QNameConstructor *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const QuantifiedExpression *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const RangeExpression *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const RangeVariableReference *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const ReturnOrderBy *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const SimpleContentConstructor *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const StaticBaseURIStore *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const StaticCompatibilityStore *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const TemplateParameterReference *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const TextNodeConstructor *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const TreatAs *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const TruthPredicate *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const UnresolvedVariableReference *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const UntypedAtomicConverter *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const UserFunctionCallsite *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const ValidationError *) const = 0; + virtual ExpressionVisitorResult::Ptr visit(const ValueComparison *) const = 0; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qexpressionfactory.cpp b/src/xmlpatterns/expr/qexpressionfactory.cpp new file mode 100644 index 0000000..861b980 --- /dev/null +++ b/src/xmlpatterns/expr/qexpressionfactory.cpp @@ -0,0 +1,473 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include "qcalltemplate_p.h" +#include "qcommonsequencetypes_p.h" +#include "qdebug_p.h" +#include "qexpression_p.h" +#include "qgenericstaticcontext_p.h" +#include "qoperandsiterator_p.h" +#include "qoptimizationpasses_p.h" +#include "qparsercontext_p.h" +#include "qpath_p.h" +#include "qquerytransformparser_p.h" +#include "qstaticfocuscontext_p.h" +#include "qtokenrevealer_p.h" +#include "qxquerytokenizer_p.h" +#include "qxslttokenizer_p.h" + +#include "qexpressionfactory_p.h" + +QT_BEGIN_NAMESPACE + +namespace QPatternist { + +/** + * @short The entry point to the parser. + * + * @param info supplies the information the parser & scanner + * needs to create expressions. The created expression, if everything + * succeeds, can be retrieved via the object @p info points to. + * @returns non-negative if the parser fails. + * @see ExpressionFactory::createExpression() + */ +extern int XPathparse(QPatternist::ParserContext *const info); + +Expression::Ptr ExpressionFactory::createExpression(const QString &expr, + const StaticContext::Ptr &context, + const QXmlQuery::QueryLanguage lang, + const SequenceType::Ptr &requiredType, + const QUrl &queryURI, + const QXmlName &initialTemplateName) +{ + if(lang == QXmlQuery::XSLT20) + { + QByteArray query(expr.toUtf8()); + QBuffer buffer(&query); + buffer.open(QIODevice::ReadOnly); + + return createExpression(&buffer, + context, + lang, + requiredType, + queryURI, + initialTemplateName); + } + else + { + return createExpression(Tokenizer::Ptr(new XQueryTokenizer(expr, queryURI)), + context, + lang, + requiredType, + queryURI, + initialTemplateName); + } +} + +Expression::Ptr ExpressionFactory::createExpression(QIODevice *const device, + const StaticContext::Ptr &context, + const QXmlQuery::QueryLanguage lang, + const SequenceType::Ptr &requiredType, + const QUrl &queryURI, + const QXmlName &initialTemplateName) +{ + Q_ASSERT(device); + Q_ASSERT(device->isReadable()); + + Tokenizer::Ptr tokenizer; + + if(lang == QXmlQuery::XSLT20) + tokenizer = Tokenizer::Ptr(new XSLTTokenizer(device, queryURI, context, context->namePool())); + else + tokenizer = Tokenizer::Ptr(new XQueryTokenizer(QString::fromUtf8(device->readAll()), queryURI)); + + return createExpression(tokenizer, context, lang, requiredType, queryURI, initialTemplateName); +} + +Expression::Ptr ExpressionFactory::createExpression(const Tokenizer::Ptr &tokenizer, + const StaticContext::Ptr &context, + const QXmlQuery::QueryLanguage lang, + const SequenceType::Ptr &requiredType, + const QUrl &queryURI, + const QXmlName &initialTemplateName) +{ + Q_ASSERT(context); + Q_ASSERT(requiredType); + Q_ASSERT(queryURI.isValid()); + + Tokenizer::Ptr effectiveTokenizer(tokenizer); +#ifdef Patternist_DEBUG + effectiveTokenizer = Tokenizer::Ptr(new TokenRevealer(queryURI, tokenizer)); +#endif + + OptimizationPasses::Coordinator::init(); + + const ParserContext::Ptr info(new ParserContext(context, lang, effectiveTokenizer.data())); + info->initialTemplateName = initialTemplateName; + + effectiveTokenizer->setParserContext(info); + + const int bisonRetval = XPathparse(info.data()); + + Q_ASSERT_X(bisonRetval == 0, Q_FUNC_INFO, + "We shouldn't be able to get an error, because we throw exceptions."); + Q_UNUSED(bisonRetval); /* Needed when not compiled in debug mode, since bisonRetval won't + * be used in the Q_ASSERT_X above. */ + + Expression::Ptr result(info->queryBody); + + if(!result) + { + context->error(QtXmlPatterns::tr("A library module cannot be evaluated " + "directly. It must be imported from a " + "main module."), + ReportContext::XPST0003, + QSourceLocation(queryURI, 1, 1)); + } + + /* Optimization: I think many things are done in the wrong order below. We + * probably want everything typechecked before compressing, since we can + * have references all over the place(variable references, template + * invocations, function callsites). This could even be a source to bugs. + */ + + /* Here, we type check user declared functions and global variables. This + * means that variables and functions that are not used are type + * checked(which they otherwise wouldn't have been), and those which are + * used, are type-checked twice, unfortunately. */ + + const bool hasExternalFocus = context->contextItemType(); + + if(lang == QXmlQuery::XSLT20) + { + /* Bind xsl:call-template instructions to their template bodies. + * + * We do this before type checking and compressing them, because a + * CallTemplate obviously needs its template before being compressed. + * + * Also, we do this before type checking and compressing user + * functions, since they can contain template call sites. + */ + for(int i = 0; i < info->templateCalls.count(); ++i) + { + CallTemplate *const site = info->templateCalls.at(i)->as(); + const QXmlName targetName(site->name()); + const Template::Ptr t(info->namedTemplates.value(targetName)); + + if(t) + site->setTemplate(t); + else + { + context->error(QtXmlPatterns::tr("No template by name %1 exists.").arg(formatKeyword(context->namePool(), targetName)), + ReportContext::XTSE0650, + site); + } + } + } + + /* Type check and compress user functions. */ + { + const UserFunction::List::const_iterator end(info->userFunctions.constEnd()); + UserFunction::List::const_iterator it(info->userFunctions.constBegin()); + + /* If the query has a focus(which is common, in the case of a + * stylesheet), we must ensure that the focus isn't visible in the + * function body. */ + StaticContext::Ptr effectiveContext; + + if(hasExternalFocus) + { + effectiveContext = StaticContext::Ptr(new StaticFocusContext(ItemType::Ptr(), + context)); + } + else + effectiveContext = context; + + for(; it != end; ++it) + { + pDebug() << "----- User Function Typecheck -----"; + registerLastPath((*it)->body()); + + /* We will most likely call body()->typeCheck() again, once for + * each callsite. That is, it will be called from + * UserFunctionCallsite::typeCheck(), which will be called + * indirectly when we check the query body. */ + const Expression::Ptr typeCheck((*it)->body()->typeCheck(effectiveContext, + (*it)->signature()->returnType())); + /* We don't have to call (*it)->setBody(typeCheck) here since it's + * only used directly below. */ + processTreePass(typeCheck, UserFunctionTypeCheck); + pDebug() << "------------------------------"; + + pDebug() << "----- User Function Compress -----"; + const Expression::Ptr comp(typeCheck->compress(effectiveContext)); + (*it)->setBody(comp); + processTreePass(comp, UserFunctionCompression); + pDebug() << "------------------------------"; + } + } + + /* Type check and compress global variables. */ + { + const VariableDeclaration::Stack::const_iterator vend(info->variables.constEnd()); + VariableDeclaration::Stack::const_iterator vit(info->variables.constBegin()); + for(; vit != vend; ++vit) + { + Q_ASSERT(*vit); + /* This is a bit murky, the global variable will have it + * Expression::typeCheck() function called from all its references, + * but we also want to check it here globally, so we do + * typechecking using a proper focus. */ + if((*vit)->type == VariableDeclaration::ExternalVariable) + continue; + + pDebug() << "----- Global Variable Typecheck -----"; + Q_ASSERT((*vit)->expression()); + /* We supply ZeroOrMoreItems, meaning the variable can evaluate to anything. */ + // FIXME which is a source to bugs + // TODO What about compressing variables? + const Expression::Ptr + nev((*vit)->expression()->typeCheck(context, CommonSequenceTypes::ZeroOrMoreItems)); + processTreePass(nev, GlobalVariableTypeCheck); + pDebug() << "------------------------------"; + } + } + + /* Do all tests specific to XSL-T. */ + if(lang == QXmlQuery::XSLT20) + { + /* Type check and compress named templates. */ + { + pDebug() << "Have " << info->namedTemplates.count() << "named templates"; + + QMutableHashIterator it(info->namedTemplates); + + while(it.hasNext()) + { + it.next(); + processNamedTemplate(it.key(), it.value()->body, TemplateInitial); + + it.value()->body = it.value()->body->typeCheck(context, CommonSequenceTypes::ZeroOrMoreItems); + processNamedTemplate(it.key(), it.value()->body, TemplateTypeCheck); + + it.value()->body = it.value()->body->compress(context); + processNamedTemplate(it.key(), it.value()->body, TemplateCompress); + + it.value()->compileParameters(context); + } + } + + /* Type check and compress template rules. */ + { + QHashIterator it(info->templateRules); + + /* Since a pattern can exist of AxisStep, its typeCheck() stage + * requires a focus. In the case that we're invoked with a name but + * no focus, this will yield a compile error, unless we declare a + * focus manually. This only needs to be done for the pattern + * expression, since the static type of the pattern is used as the + * static type for the focus of the template body. */ + StaticContext::Ptr patternContext; + if(hasExternalFocus) + patternContext = context; + else + patternContext = StaticContext::Ptr(new StaticFocusContext(BuiltinTypes::node, context)); + + /* For each template pattern. */ + while(it.hasNext()) + { + it.next(); + const TemplateMode::Ptr &mode = it.value(); + const int len = mode->templatePatterns.count(); + TemplatePattern::ID currentTemplateID = -1; + bool hasDoneItOnce = false; + + /* For each template pattern. */ + for(int i = 0; i < len; ++i) + { + /* We can't use references for these two members, since we + * assign to them. */ + const TemplatePattern::Ptr &pattern = mode->templatePatterns.at(i); + Expression::Ptr matchPattern(pattern->matchPattern()); + + processTemplateRule(pattern->templateTarget()->body, + pattern, mode->name(), TemplateInitial); + + matchPattern = matchPattern->typeCheck(patternContext, CommonSequenceTypes::ZeroOrMoreItems); + matchPattern = matchPattern->compress(patternContext); + pattern->setMatchPattern(matchPattern); + + if(currentTemplateID == -1 && hasDoneItOnce) + { + currentTemplateID = pattern->id(); + continue; + } + else if(currentTemplateID == pattern->id() && hasDoneItOnce) + { + hasDoneItOnce = false; + continue; + } + + hasDoneItOnce = true; + currentTemplateID = pattern->id(); + Expression::Ptr body(pattern->templateTarget()->body); + + /* Patterns for a new template has started, we must + * deal with the body & parameters. */ + { + /* TODO type is wrong, it has to be the union of all + * patterns. */ + const StaticContext::Ptr focusContext(new StaticFocusContext(matchPattern->staticType()->itemType(), + context)); + body = body->typeCheck(focusContext, CommonSequenceTypes::ZeroOrMoreItems); + + pattern->templateTarget()->compileParameters(focusContext); + } + + processTemplateRule(body, pattern, mode->name(), TemplateTypeCheck); + + body = body->compress(context); + + pattern->templateTarget()->body = body; + processTemplateRule(body, pattern, mode->name(), TemplateCompress); + } + + mode->finalize(); + } + } + + /* Add templates in mode #all to all other modes. + * + * We do this after the templates has been typechecked and compressed, + * since otherwise it will be done N times for the built-in templates, + * where N is the count of different templates, instead of once. */ + { + const QXmlName nameModeAll(QXmlName(StandardNamespaces::InternalXSLT, + StandardLocalNames::all)); + const TemplateMode::Ptr &modeAll = info->templateRules[nameModeAll]; + + Q_ASSERT_X(modeAll, Q_FUNC_INFO, + "We should at least have the builtin templates."); + QHashIterator it(info->templateRules); + + while(it.hasNext()) + { + it.next(); + + /* Don't add mode #all to mode #all. */ + if(it.key() == nameModeAll) + continue; + + it.value()->addMode(modeAll); + } + } + } + + /* Type check and compress the query body. */ + { + pDebug() << "----- Initial AST build. -----"; + processTreePass(result, QueryBodyInitial); + pDebug() << "------------------------------"; + + pDebug() << "----- Type Check -----"; + registerLastPath(result); + result->rewrite(result, result->typeCheck(context, requiredType), context); + processTreePass(result, QueryBodyTypeCheck); + pDebug() << "------------------------------"; + + pDebug() << "----- Compress -----"; + result->rewrite(result, result->compress(context), context); + processTreePass(result, QueryBodyCompression); + pDebug() << "------------------------------"; + } + + return result; +} + +void ExpressionFactory::registerLastPath(const Expression::Ptr &operand) +{ + OperandsIterator it(operand, OperandsIterator::IncludeParent); + Expression::Ptr next(it.next()); + + while(next) + { + if(next->is(Expression::IDPath)) + { + next->as()->setLast(); + next = it.skipOperands(); + } + else + next = it.next(); + } +} + +void ExpressionFactory::processTreePass(const Expression::Ptr &, + const CompilationStage) +{ +} + +void ExpressionFactory::processTemplateRule(const Expression::Ptr &body, + const TemplatePattern::Ptr &pattern, + const QXmlName &mode, + const TemplateCompilationStage stage) +{ + Q_UNUSED(body); + Q_UNUSED(pattern); + Q_UNUSED(mode); + Q_UNUSED(stage); +} + +void ExpressionFactory::processNamedTemplate(const QXmlName &name, + const Expression::Ptr &tree, + const TemplateCompilationStage stage) +{ + Q_UNUSED(name); + Q_UNUSED(tree); + Q_UNUSED(stage); +} + +} // namespace QPatternist + +QT_END_NAMESPACE + diff --git a/src/xmlpatterns/expr/qexpressionfactory_p.h b/src/xmlpatterns/expr/qexpressionfactory_p.h new file mode 100644 index 0000000..07235bb --- /dev/null +++ b/src/xmlpatterns/expr/qexpressionfactory_p.h @@ -0,0 +1,187 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ExpressionFactory_H +#define Patternist_ExpressionFactory_H + +#include + +#include "qexpression_p.h" +#include "qtokenizer_p.h" + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QIODevice; + +namespace QPatternist +{ + /** + * @short The central entry point for compiling expressions. + * + * @ingroup Patternist_expressions + * @author Frans Englich + */ + class Q_AUTOTEST_EXPORT ExpressionFactory : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * @short This constructor cannot be synthesized since we + * use the Q_DISABLE_COPY macro. + */ + inline ExpressionFactory() + { + } + + virtual ~ExpressionFactory() + { + } + + enum CompilationStage + { + QueryBodyInitial = 1, + QueryBodyTypeCheck = 1 << 1, + QueryBodyCompression = 1 << 2, + UserFunctionTypeCheck = 1 << 3, + UserFunctionCompression = 1 << 4, + GlobalVariableTypeCheck = 1 << 5 + }; + + /** + * Creates a compiled representation of the XPath expression @p expr, with Static + * Context information supplied via @p context. This is for example whether the expression + * is an XPath 1.0 or XPath 2.0 expression, or what functions that are available. + * + * @p requiredType specifies what type results of the evaluating the expression + * must match. Passing CommonValues::ZeroOrMoreItems allows anything as result, while + * passing CommonSequenceTypes::EBV means anything but an Effective %Boolean Value extractable + * result is a type error, for example. + * + * @note An empty @p expr is an invalid XPath expression. It will be reported as such, + * but it is neverthless the caller's resonsibility to ensure that it's not that(since + * it is likely invalid already in the medium it was stored). + */ + virtual Expression::Ptr createExpression(const QString &expr, + const StaticContext::Ptr &context, + const QXmlQuery::QueryLanguage lang, + const SequenceType::Ptr &requiredType, + const QUrl &queryURI, + const QXmlName &initialTemplateName); + + virtual Expression::Ptr createExpression(QIODevice *const device, + const StaticContext::Ptr &context, + const QXmlQuery::QueryLanguage lang, + const SequenceType::Ptr &requiredType, + const QUrl &queryURI, + const QXmlName &initialTemplateName); + + /** + * Finds the last paths of a set of paths(if any) and tells the Path + * so, such that it can generate the code for checking XPTY0018. + * + * Must be called before typeCheck() is called on the operand, since + * the typeCheck() uses the information for type checking. + */ + static void registerLastPath(const Expression::Ptr &operand); + + protected: + enum TemplateCompilationStage + { + TemplateInitial = 1, + TemplateTypeCheck = 1 << 1, + TemplateCompress = 1 << 2 + }; + + /** + * This function is called by createExpression() each time + * after a pass on the AST has been completed. Under a typical + * compilation this function is thus called three times: after the initial + * build, after the Expression::typeCheck() stage, and after + * Expression::compress(). @p tree is the AST after each pass. + * + * This mechanism is currently used for debugging, since it provides a + * way of introspecting what the compilation process do to the tree. The + * current implementation do nothing. + */ + virtual void processTreePass(const Expression::Ptr &tree, + const CompilationStage stage); + + virtual void processTemplateRule(const Expression::Ptr &body, + const TemplatePattern::Ptr &pattern, + const QXmlName &mode, + const TemplateCompilationStage stage); + + virtual void processNamedTemplate(const QXmlName &name, + const Expression::Ptr &tree, + const TemplateCompilationStage stage); + + Expression::Ptr createExpression(const Tokenizer::Ptr &tokenizer, + const StaticContext::Ptr &context, + const QXmlQuery::QueryLanguage lang, + const SequenceType::Ptr &requiredType, + const QUrl &queryURI, + const QXmlName &initialTemplateName); + private: + Q_DISABLE_COPY(ExpressionFactory) + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qexpressionsequence.cpp b/src/xmlpatterns/expr/qexpressionsequence.cpp new file mode 100644 index 0000000..a4d1ba6 --- /dev/null +++ b/src/xmlpatterns/expr/qexpressionsequence.cpp @@ -0,0 +1,206 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcardinalityverifier_p.h" +#include "qcommonsequencetypes_p.h" +#include "qemptysequence_p.h" +#include "qsequencemappingiterator_p.h" + +#include "qexpressionsequence_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +ExpressionSequence::ExpressionSequence(const Expression::List &ops) : UnlimitedContainer(ops) +{ + Q_ASSERT_X(1 < ops.count(), Q_FUNC_INFO, + "It makes no sense to have an ExpressionSequence containing less than two expressions."); +} + +Item::Iterator::Ptr ExpressionSequence::mapToSequence(const Expression::Ptr &expr, + const DynamicContext::Ptr &context) const +{ + return expr->evaluateSequence(context); +} + +Item::Iterator::Ptr ExpressionSequence::evaluateSequence(const DynamicContext::Ptr &context) const +{ + return makeSequenceMappingIterator(ConstPtr(this), + makeListIterator(m_operands), + context); +} + +void ExpressionSequence::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const +{ + Expression::List::const_iterator it(m_operands.constBegin()); + const Expression::List::const_iterator end(m_operands.constEnd()); + Expression::List result; + + for(; it != end; ++it) + (*it)->evaluateToSequenceReceiver(context); +} + +Expression::Ptr ExpressionSequence::compress(const StaticContext::Ptr &context) +{ + const Expression::Ptr me(UnlimitedContainer::compress(context)); + + if(me != this) + return me; + + Expression::List::const_iterator it(m_operands.constBegin()); + const Expression::List::const_iterator end(m_operands.constEnd()); + Expression::List result; + + for(; it != end; ++it) + { + const ID Id = (*it)->id(); + + /* Remove empty sequences. This is rather important because we have some steps in the parser that + * intentionally, unconditionally and for temporary reasons create expressions like (expr, ()). Of course, + * empty sequences also occur as part of optimizations. + * + * User function call sites that are of type empty-sequence() must be avoided since + * they may contain calls to fn:error(), which we would rewrite away otherwise. */ + if(Id != IDUserFunctionCallsite && (*it)->staticType()->cardinality().isEmpty()) + { + /* Rewrite "(1, (), 2)" into "(1, 2)" by not + * adding (*it) to result. */ + continue; + } + else if(Id == IDExpressionSequence) + { + /* Rewrite "(1, (2, 3), 4)" into "(1, 2, 3, 4)" */ + Expression::List::const_iterator seqIt((*it)->operands().constBegin()); + const Expression::List::const_iterator seqEnd((*it)->operands().constEnd()); + + for(; seqIt != seqEnd; ++seqIt) + result.append(*seqIt); + } + else + result.append(*it); + } + + if(result.isEmpty()) + return EmptySequence::create(this, context); + else if(result.count() == 1) + return result.first(); + else + { + m_operands = result; + return me; + } +} + +Expression::Ptr ExpressionSequence::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + Q_ASSERT(reqType); + Expression::List::iterator it(m_operands.begin()); + const Expression::List::iterator end(m_operands.end()); + + /* We treat the cardinality differently here by allowing the empty sequence + * for each individual Expression, since the Cardinality can be conformed to by + * the ExpressionSequence as a whole(which we check for at the end). */ + const SequenceType::Ptr testOnlyIT(makeGenericSequenceType(reqType->itemType(), + Cardinality::empty() | + reqType->cardinality())); + + for(; it != end; ++it) + *it = (*it)->typeCheck(context, testOnlyIT); + + /* The above loop is only guaranteed to find item type errors, but the cardinality + * can still be wrong since the operands were treated individually. */ + return CardinalityVerifier::verifyCardinality(Expression::Ptr(this), reqType->cardinality(), context); +} + +Expression::Properties ExpressionSequence::properties() const +{ + const Expression::List::const_iterator end(m_operands.constEnd()); + Expression::List::const_iterator it; + bool allEvaled = true; + Expression::Properties props(DisableElimination); /* Why do we have this flag? */ + + for(it = m_operands.constBegin(); it != end; ++it) + { + const Expression::Properties newp((*it)->properties()); + props |= newp; + + if((newp & IsEvaluated) != IsEvaluated) + { + allEvaled = false; + break; + } + } + + if(!allEvaled) + props &= ~IsEvaluated; /* Remove IsEvaluated. */ + + /* One of our children might need the focus, but we don't, so + * cut it out. */ + return props & ~RequiresFocus; +} + +SequenceType::Ptr ExpressionSequence::staticType() const +{ + return operandsUnionType(); +} + +SequenceType::List ExpressionSequence::expectedOperandTypes() const +{ + SequenceType::List result; + /* ExpressionSequence is a bit strange type wise since it has an + * infinite amount of operands. */ + result.append(CommonSequenceTypes::ZeroOrMoreItems); + return result; +} + +ExpressionVisitorResult::Ptr ExpressionSequence::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +Expression::ID ExpressionSequence::id() const +{ + return IDExpressionSequence; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qexpressionsequence_p.h b/src/xmlpatterns/expr/qexpressionsequence_p.h new file mode 100644 index 0000000..5074489 --- /dev/null +++ b/src/xmlpatterns/expr/qexpressionsequence_p.h @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ExpressionSequence_H +#define Patternist_ExpressionSequence_H + +#include "qunlimitedcontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements the comma(",") operator, the sequence constructor. + * + * For example, the expression alpha, beta evaluates to a sequence + * containing the items the nodetest @c alpha evaluates to, concatenated + * with the items the nodetest @c beta evaluates to. + * + * @see XML Path Language + * (XPath) 2.0, 3.3.1 Constructing Sequences + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class ExpressionSequence : public UnlimitedContainer + { + public: + /** + * Creates an ExpressionSequence with the operands @p operands. @p operands + * must contain two or more Expression instances. + */ + ExpressionSequence(const Expression::List &operands); + + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &) const; + + /** + * Forwards the call to its children. + */ + virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const; + + virtual SequenceType::List expectedOperandTypes() const; + virtual SequenceType::Ptr staticType() const; + + /** + * Removes any empty sequences, typically "()", from its list of children. If + * after that rewrite has no children, it rewrites itself to the CommonValues::empty; + * if it has only one, it rewrites to the child. + * + * This optimization is not very usable by itself, but potentially becomes effective after other + * optimizations have rewritten themselves into empty sequences. Thus, + * saving memory consumption and runtime overhead. + */ + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + + inline Item::Iterator::Ptr mapToSequence(const Expression::Ptr &, + const DynamicContext::Ptr &) const; + + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + /** + * @returns Expression::DisableElimination, plus the union + * of all this ExpressionSequence's children's properties. If any child + * does not have IsEvaluated, it is removed from the result. + */ + virtual Expression::Properties properties() const; + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + virtual ID id() const; + private: + typedef QExplicitlySharedDataPointer ConstPtr; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qexpressionvariablereference.cpp b/src/xmlpatterns/expr/qexpressionvariablereference.cpp new file mode 100644 index 0000000..3b9ecb1 --- /dev/null +++ b/src/xmlpatterns/expr/qexpressionvariablereference.cpp @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include "qexpressionvariablereference_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +ExpressionVariableReference::ExpressionVariableReference(const VariableSlotID slotP, + const VariableDeclaration::Ptr &varDecl) : VariableReference(slotP) + , m_varDecl(varDecl) +{ +} + +bool ExpressionVariableReference::evaluateEBV(const DynamicContext::Ptr &context) const +{ + return context->expressionVariable(slot())->evaluateEBV(context); +} + +Item ExpressionVariableReference::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + return context->expressionVariable(slot())->evaluateSingleton(context); +} + +Item::Iterator::Ptr ExpressionVariableReference::evaluateSequence(const DynamicContext::Ptr &context) const +{ + return context->expressionVariable(slot())->evaluateSequence(context); +} +Expression::Ptr ExpressionVariableReference::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + if(m_varDecl->canSourceRewrite) + return m_varDecl->expression()->typeCheck(context, reqType); + else + return VariableReference::typeCheck(context, reqType); +} + +Expression::ID ExpressionVariableReference::id() const +{ + return IDExpressionVariableReference; +} + +ExpressionVisitorResult::Ptr ExpressionVariableReference::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +SequenceType::Ptr ExpressionVariableReference::staticType() const +{ + return m_varDecl->expression()->staticType(); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qexpressionvariablereference_p.h b/src/xmlpatterns/expr/qexpressionvariablereference_p.h new file mode 100644 index 0000000..40c835e --- /dev/null +++ b/src/xmlpatterns/expr/qexpressionvariablereference_p.h @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ExpressionVariableReference_H +#define Patternist_ExpressionVariableReference_H + +#include "qvariabledeclaration_p.h" +#include "qvariablereference_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A reference to a variable declared with declare variable or @c let. + * + * It's also used by variable bindings in @c case branches of the @c typeswitch + * expression. + * + * This AST node is only used up until the typeCheck() stage. Therefore it + * has no functions for evaluation, such as evaluateSequence(). + * + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class ExpressionVariableReference : public VariableReference + { + public: + ExpressionVariableReference(const VariableSlotID slot, + const VariableDeclaration::Ptr &varDecl); + + virtual bool evaluateEBV(const DynamicContext::Ptr &context) const; + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + virtual SequenceType::Ptr staticType() const; + virtual ID id() const; + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + + inline const Expression::Ptr &sourceExpression() const; + inline const VariableDeclaration::Ptr &variableDeclaration() const; + private: + const VariableDeclaration::Ptr m_varDecl; + }; + + inline const Expression::Ptr &ExpressionVariableReference::sourceExpression() const + { + return m_varDecl->expression(); + } + + inline const VariableDeclaration::Ptr &ExpressionVariableReference::variableDeclaration() const + { + return m_varDecl; + } + +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qexternalvariableloader.cpp b/src/xmlpatterns/expr/qexternalvariableloader.cpp new file mode 100644 index 0000000..2099cb6 --- /dev/null +++ b/src/xmlpatterns/expr/qexternalvariableloader.cpp @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qboolean_p.h" +#include "qcommonvalues_p.h" +#include "qdynamiccontext_p.h" + +#include "qexternalvariableloader_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +ExternalVariableLoader::~ExternalVariableLoader() +{ +} + + +SequenceType::Ptr ExternalVariableLoader::announceExternalVariable(const QXmlName name, + const SequenceType::Ptr &declaredType) +{ + Q_ASSERT(!name.isNull()); + Q_ASSERT(declaredType); + Q_UNUSED(name); /* Needed when compiling in release mode. */ + Q_UNUSED(declaredType); /* Needed when compiling in release mode. */ + + return SequenceType::Ptr(); +} + +Item::Iterator::Ptr ExternalVariableLoader::evaluateSequence(const QXmlName name, + const DynamicContext::Ptr &context) +{ + Q_ASSERT(!name.isNull()); + const Item item(evaluateSingleton(name, context)); + + if(item) + return makeSingletonIterator(item); + else + return CommonValues::emptyIterator; +} + +Item ExternalVariableLoader::evaluateSingleton(const QXmlName name, + const DynamicContext::Ptr &context) +{ + Q_ASSERT(!name.isNull()); + return Boolean::fromValue(evaluateEBV(name, context)); +} + +bool ExternalVariableLoader::evaluateEBV(const QXmlName name, + const DynamicContext::Ptr &context) +{ + Q_ASSERT(!name.isNull()); + return Boolean::evaluateEBV(evaluateSequence(name, context), context); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qexternalvariableloader_p.h b/src/xmlpatterns/expr/qexternalvariableloader_p.h new file mode 100644 index 0000000..5dc3af5 --- /dev/null +++ b/src/xmlpatterns/expr/qexternalvariableloader_p.h @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ExternalVariableLoader_H +#define Patternist_ExternalVariableLoader_H + +#include "qitem_p.h" +#include "qsequencetype_p.h" +#include "qxmlname.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + class DynamicContext; + + /** + * @short Responsible for loading and declaring available external variables. + * + * An external variable in XQuery is a global variable that has been declared to receive + * its value from the XQuery implementation, as opposed to an initializing expression. Here + * is an example of a query with an external variable declaration, followed by a ordinary + * global variable: + * + * declare variable $theName external; + * declare variable $theName := "the value"; + * "And here's the query body(a string literal)" + * + * An external variable declaration can also specify a sequence type: + * + * declare variable $theName as xs:integer external; + * + * This class allows the user to supply the values to external variables. When + * an external variable declaration occur in the query, + * announceExternalVariable() is called. + * + * @ingroup Patternist_xdm + * @author Frans Englich + */ + class Q_AUTOTEST_EXPORT ExternalVariableLoader : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer Ptr; + inline ExternalVariableLoader() {} + + virtual ~ExternalVariableLoader(); + + /** + * Called when Patternist encounters an external variable in the query. It is guaranteed + * to be called once for each external variable appearing in a query module. + * + * @param name the name of the variable. Quaranteed to never be @c null. + * @param declaredType the type that the user declared the variable to be of. Whether + * this type matches the actual value of the variable or not is irrelevant. Patternist + * will do the necessary error handling based on the sequence type that is returned from + * this function. If the user didn't declare a type, the type is item()*(zero or + * more items). Quaranteed to never be @c null. + * @returns the sequence type of the value this ExternalVariableLoader actually supplies. However, + * if the ExternalVariableLoader knows it cannot supply a variable by this name, @c null should be + * returned. + */ + virtual SequenceType::Ptr announceExternalVariable(const QXmlName name, + const SequenceType::Ptr &declaredType); + + /** + * This function is called at runtime when the external variable by name @p name needs + * to be evaluated. It is not defined how many times this function will be called. It + * depends on aspects such as how the query was optimized. + * + * @param name the name of the variable. Quaranteed to never be @c null. + * @param context the DynamicContext. + * @returns the value of the variable. Remember that this value must match the + * sequence type returned from announceExternalVariable() for the same name. + */ + virtual Item::Iterator::Ptr evaluateSequence(const QXmlName name, + const QExplicitlySharedDataPointer &context); + + virtual Item evaluateSingleton(const QXmlName name, + const QExplicitlySharedDataPointer &context); + virtual bool evaluateEBV(const QXmlName name, + const QExplicitlySharedDataPointer &context); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qexternalvariablereference.cpp b/src/xmlpatterns/expr/qexternalvariablereference.cpp new file mode 100644 index 0000000..8016cc5 --- /dev/null +++ b/src/xmlpatterns/expr/qexternalvariablereference.cpp @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include "qexternalvariablereference_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +ExternalVariableReference::ExternalVariableReference(const QXmlName &name, + const SequenceType::Ptr &type) : m_name(name), + m_seqType(type) +{ + Q_ASSERT(!m_name.isNull()); + Q_ASSERT(m_seqType); +} + +Item::Iterator::Ptr ExternalVariableReference::evaluateSequence(const DynamicContext::Ptr &context) const +{ + Q_ASSERT(context->externalVariableLoader()); + return context->externalVariableLoader()->evaluateSequence(m_name, context); +} + +Item ExternalVariableReference::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + return context->externalVariableLoader()->evaluateSingleton(m_name, context); +} + +bool ExternalVariableReference::evaluateEBV(const DynamicContext::Ptr &context) const +{ + return context->externalVariableLoader()->evaluateEBV(m_name, context); +} + +SequenceType::Ptr ExternalVariableReference::staticType() const +{ + return m_seqType; +} + +Expression::Properties ExternalVariableReference::properties() const +{ + return DisableElimination; +} + +ExpressionVisitorResult::Ptr ExternalVariableReference::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qexternalvariablereference_p.h b/src/xmlpatterns/expr/qexternalvariablereference_p.h new file mode 100644 index 0000000..96d0dd2 --- /dev/null +++ b/src/xmlpatterns/expr/qexternalvariablereference_p.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ExternalVariableReference_H +#define Patternist_ExternalVariableReference_H + +#include "qemptycontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A reference to an external variable. + * + * ExternalVariableReference does not sub-class VariableReference, because it + * works differently from how sub-classes of VariableReference do. This class + * uses DynamicContext::externalVariableLoader() for retrieving its value, while + * a VariableReference sub-class uses slots in the DynamicContext. + * + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class ExternalVariableReference : public EmptyContainer + { + public: + ExternalVariableReference(const QXmlName &name, + const SequenceType::Ptr &type); + + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + virtual bool evaluateEBV(const DynamicContext::Ptr &context) const; + + virtual SequenceType::Ptr staticType() const; + + /** + * @returns always DisableElimination + */ + virtual Expression::Properties properties() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + + private: + const QXmlName m_name; + const SequenceType::Ptr m_seqType; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qfirstitempredicate.cpp b/src/xmlpatterns/expr/qfirstitempredicate.cpp new file mode 100644 index 0000000..651dff3 --- /dev/null +++ b/src/xmlpatterns/expr/qfirstitempredicate.cpp @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonsequencetypes_p.h" +#include "qgenericsequencetype_p.h" + +#include "qfirstitempredicate_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +FirstItemPredicate::FirstItemPredicate(const Expression::Ptr &source) : SingleContainer(source) +{ +} + +Item FirstItemPredicate::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + /* If our operand allows the empty sequence, this function can return Item(), otherwise + * it returns the first item. As simple as that. */ + return m_operand->evaluateSequence(context)->next(); +} + +SequenceType::Ptr FirstItemPredicate::staticType() const +{ + const SequenceType::Ptr t(m_operand->staticType()); + return makeGenericSequenceType(t->itemType(), t->cardinality().toWithoutMany()); +} + +Expression::Ptr FirstItemPredicate::compress(const StaticContext::Ptr &context) +{ + const Expression::Ptr me(SingleContainer::compress(context)); + if(me != this) + return me; + + if(m_operand->is(IDFirstItemPredicate)) + m_operand = m_operand->operands().first(); + + return me; +} + +SequenceType::List FirstItemPredicate::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ZeroOrMoreItems); + return result; +} + +ExpressionVisitorResult::Ptr FirstItemPredicate::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +Expression::ID FirstItemPredicate::id() const +{ + return IDFirstItemPredicate; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qfirstitempredicate_p.h b/src/xmlpatterns/expr/qfirstitempredicate_p.h new file mode 100644 index 0000000..df44195 --- /dev/null +++ b/src/xmlpatterns/expr/qfirstitempredicate_p.h @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_FirstItemPredicate_H +#define Patternist_FirstItemPredicate_H + +#include "qsinglecontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A predicate that always selects the first item from its sequence. + * + * FirstItemPredicate corresponds exactly to the predicate + * in the expression input[1]. + * + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class FirstItemPredicate : public SingleContainer + { + public: + /** + * Creates a FirstItemPredicate that filters @p source. + */ + FirstItemPredicate(const Expression::Ptr &source); + + /** + * @returns the first item, if any, from evaluating the source expression. + */ + virtual Item evaluateSingleton(const DynamicContext::Ptr &) const; + + /** + * @returns a list containing one CommonSequenceTypes::ZeroOrMoreItems instance. + */ + virtual SequenceType::List expectedOperandTypes() const; + + /** + * @returns a SequenceType where the item type is the same as the source expression + * and where the cardinality is either Cardinality::zeroOrOne() or Cardinality::exactlyOne(), + * depending on the source expression. + */ + virtual SequenceType::Ptr staticType() const; + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + + /** + * Rewrites expression[1][1] into expression[1]. + */ + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + + /** + * @returns always IDFirstItemPredicate. + */ + virtual ID id() const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qforclause.cpp b/src/xmlpatterns/expr/qforclause.cpp new file mode 100644 index 0000000..ad9262b --- /dev/null +++ b/src/xmlpatterns/expr/qforclause.cpp @@ -0,0 +1,200 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonsequencetypes_p.h" +#include "qemptysequence_p.h" +#include "qgenericsequencetype_p.h" +#include "qitemmappingiterator_p.h" +#include "qoptimizationpasses_p.h" +#include "qsequencemappingiterator_p.h" + +#include "qforclause_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +ForClause::ForClause(const VariableSlotID varSlot, + const Expression::Ptr &bindingSequence, + const Expression::Ptr &returnExpression, + const VariableSlotID positionSlot) : PairContainer(bindingSequence, returnExpression), + m_varSlot(varSlot), + m_positionSlot(positionSlot), + m_allowsMany(true) +{ + Q_ASSERT(m_positionSlot > -2); +} + +Item ForClause::mapToItem(const Item &item, + const DynamicContext::Ptr &context) const +{ + context->setRangeVariable(m_varSlot, item); + return m_operand2->evaluateSingleton(context); +} + +Item::Iterator::Ptr ForClause::mapToSequence(const Item &item, + const DynamicContext::Ptr &context) const +{ + context->setRangeVariable(m_varSlot, item); + return m_operand2->evaluateSequence(context); +} + +void ForClause::riggPositionalVariable(const DynamicContext::Ptr &context, + const Item::Iterator::Ptr &source) const +{ + if(m_positionSlot > -1) + context->setPositionIterator(m_positionSlot, source); +} + +Item::Iterator::Ptr ForClause::evaluateSequence(const DynamicContext::Ptr &context) const +{ + const Item::Iterator::Ptr source(m_operand1->evaluateSequence(context)); + + riggPositionalVariable(context, source); + + if(m_allowsMany) + { + return makeSequenceMappingIterator(ConstPtr(this), + source, + context); + } + else + { + return makeItemMappingIterator(ConstPtr(this), + source, + context); + } +} + +Item ForClause::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + return evaluateSequence(context)->next(); +} + +void ForClause::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const +{ + Item::Iterator::Ptr it; + const Item::Iterator::Ptr source(m_operand1->evaluateSequence(context)); + + riggPositionalVariable(context, source); + + Item next(source->next()); + + while(next) + { + context->setRangeVariable(m_varSlot, next); + m_operand2->evaluateToSequenceReceiver(context); + next = source->next(); + } +} + +Expression::Ptr ForClause::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + const Expression::Ptr me(PairContainer::typeCheck(context, reqType)); + const Cardinality card(m_operand1->staticType()->cardinality()); + + /* If our source is empty we will always evaluate to the empty sequence, so rewrite. */ + if(card.isEmpty()) + return EmptySequence::create(this, context); + else + return me; + + /* This breaks because the variable references haven't rewritten themselves, so + * they dangle. When this is fixed, evaluateSingleton can be removed. */ + /* + else if(card->allowsMany()) + return me; + else + return m_operand2; + */ +} + +Expression::Ptr ForClause::compress(const StaticContext::Ptr &context) +{ + const Expression::Ptr me(PairContainer::compress(context)); + if(me != this) + return me; + + /* This is done after calling PairContainer::typeCheck(). The advantage of this is that + * m_allowsMany is updated according to what the operand says after it has compressed. However, + * if it was initialized to false(as it once was..), ForClause::evaluateSequence() + * would potentially have been called by PairContainer::compress(), and it would have + * used an unsafe branch. */ + m_allowsMany = m_operand2->staticType()->cardinality().allowsMany(); + + return me; +} + +SequenceType::Ptr ForClause::staticType() const +{ + const SequenceType::Ptr returnType(m_operand2->staticType()); + + return makeGenericSequenceType(returnType->itemType(), + m_operand1->staticType()->cardinality() + * /* multiply operator */ + returnType->cardinality()); +} + +SequenceType::List ForClause::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ZeroOrMoreItems); + result.append(CommonSequenceTypes::ZeroOrMoreItems); + return result; +} + +ExpressionVisitorResult::Ptr ForClause::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +OptimizationPass::List ForClause::optimizationPasses() const +{ + return OptimizationPasses::forPasses; +} + +Expression::ID ForClause::id() const +{ + return IDForClause; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qforclause_p.h b/src/xmlpatterns/expr/qforclause_p.h new file mode 100644 index 0000000..5799e0d --- /dev/null +++ b/src/xmlpatterns/expr/qforclause_p.h @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ForClause_H +#define Patternist_ForClause_H + +#include "qpaircontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Implements XPath 2.0's @c for expression. + * + * @see XML Path Language + * (XPath) 2.0, 3.7 For Expressions + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class ForClause : public PairContainer + { + public: + /** + * If @p positionSlot is -1, no positional variable will be used. + */ + ForClause(const VariableSlotID varSlot, + const Expression::Ptr &bindingSequence, + const Expression::Ptr &returnExpression, + const VariableSlotID positionSlot); + + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const; + + virtual SequenceType::Ptr staticType() const; + virtual SequenceType::List expectedOperandTypes() const; + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + virtual QList > optimizationPasses() const; + + inline Item mapToItem(const Item &item, + const DynamicContext::Ptr &context) const; + virtual ID id() const; + inline Item::Iterator::Ptr mapToSequence(const Item &item, + const DynamicContext::Ptr &context) const; + + /** + * Sets m_allowsMany properly. + */ + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + + private: + inline void riggPositionalVariable(const DynamicContext::Ptr &context, + const Item::Iterator::Ptr &source) const; + typedef QExplicitlySharedDataPointer ConstPtr; + const VariableSlotID m_varSlot; + const VariableSlotID m_positionSlot; + /** + * Initialized to @c false. This default is always safe. + */ + bool m_allowsMany; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qgeneralcomparison.cpp b/src/xmlpatterns/expr/qgeneralcomparison.cpp new file mode 100644 index 0000000..a6d6399 --- /dev/null +++ b/src/xmlpatterns/expr/qgeneralcomparison.cpp @@ -0,0 +1,297 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" +#include "qcommonsequencetypes_p.h" +#include "qcommonvalues_p.h" +#include "qebvextractor_p.h" +#include "qitem_p.h" +#include "qliteral_p.h" +#include "qoptimizationpasses_p.h" +#include "quntypedatomicconverter_p.h" +#include "qvaluecomparison_p.h" + +#include "qgeneralcomparison_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +GeneralComparison::GeneralComparison(const Expression::Ptr &op1, + const AtomicComparator::Operator op, + const Expression::Ptr &op2, + const bool isBackwardsCompat) : PairContainer(op1, op2) + , m_operator(op) + , m_isBackwardsCompat(isBackwardsCompat) +{ +} + +bool GeneralComparison::generalCompare(const Item &op1, + const Item &op2, + const DynamicContext::Ptr &context) const +{ + Q_ASSERT(op1); + Q_ASSERT(op2); + + if(comparator()) + return compare(op1, op2, comparator(), m_operator); + + Expression::Ptr a1(new Literal(op1)); + Expression::Ptr a2(new Literal(op2)); + + const AtomicComparator::Ptr comp(fetchGeneralComparator(a1, a2, context)); + /* The fetchGeneralComparator call may rewrite a1 and/or a2. */ + Q_ASSERT(a1); + Q_ASSERT(a2); + Q_ASSERT(comp); + + return compare(a1->evaluateSingleton(context), + a2->evaluateSingleton(context), + comp, + m_operator); +} + +bool GeneralComparison::evaluateEBV(const DynamicContext::Ptr &context) const +{ + const Item::Iterator::Ptr it1(m_operand1->evaluateSequence(context)); + Item item1(it1->next()); + + if(!item1) + return false; + + const Item::Iterator::Ptr it2(m_operand2->evaluateSequence(context)); + Item::List cache; + Item item2; + + while(true) + { + item2 = it2->next(); + if(!item2) + break; + + if(generalCompare(item1, item2, context)) + return true; + + cache.append(item2); + } + + while(true) + { + item1 = it1->next(); + + if(!item1) + return false; + + const Item::List::const_iterator end(cache.constEnd()); + Item::List::const_iterator it(cache.constBegin()); + + for(; it != end; ++it) + if(generalCompare(item1, *it, context)) + return true; + } + + Q_ASSERT(false); + return false; +} + +Expression::Ptr GeneralComparison::compress(const StaticContext::Ptr &context) +{ + const Expression::Ptr me(PairContainer::compress(context)); + + if(me != this) + return me; + + if(ValueComparison::isCaseInsensitiveCompare(m_operand1, m_operand2)) + useCaseInsensitiveComparator(); + + return me; +} + +Expression::Ptr GeneralComparison::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + + const Expression::Ptr me(PairContainer::typeCheck(context, reqType)); + + const ItemType::Ptr t1(m_operand1->staticType()->itemType()); + const ItemType::Ptr t2(m_operand2->staticType()->itemType()); + + if(*CommonSequenceTypes::Empty == *t1 || + *CommonSequenceTypes::Empty == *t2) + { + return wrapLiteral(CommonValues::BooleanFalse, context, this); + } + + if(*BuiltinTypes::xsAnyAtomicType == *t1 || + *BuiltinTypes::xsAnyAtomicType == *t2) + return me; + + prepareComparison(fetchGeneralComparator(m_operand1, m_operand2, context)); + + if(!m_operand1->staticType()->cardinality().allowsMany() && + !m_operand2->staticType()->cardinality().allowsMany()) + { + /* Rewrite to a ValueComparison whose operands uses typing rules + * as for an general comparison(that's what's done above). */ + return rewrite(Expression::Ptr(new ValueComparison(m_operand1, + m_operator, + m_operand2))->typeCheck(context, reqType), + context); + } + else + return me; +} + +void GeneralComparison::updateType(ItemType::Ptr &type, + const Expression::Ptr &source) +{ + type = source->staticType()->itemType(); +} + +AtomicComparator::Ptr GeneralComparison::fetchGeneralComparator(Expression::Ptr &op1, + Expression::Ptr &op2, + const ReportContext::Ptr &context) const +{ + ItemType::Ptr t1(op1->staticType()->itemType()); + ItemType::Ptr t2(op2->staticType()->itemType()); + + /* a. "If one of the atomic values is an instance of xs:untypedAtomic and + * the other is an instance of a numeric type, then the xs:untypedAtomic + * value is cast to the type xs:double." */ + if(BuiltinTypes::numeric->xdtTypeMatches(t1) && + BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t2)) + { + op2 = Expression::Ptr(new UntypedAtomicConverter(op2, BuiltinTypes::xsDouble)); + + /* The types might have changed, reload. */ + updateType(t2, op2); + } + else if(BuiltinTypes::numeric->xdtTypeMatches(t2) && + BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t1)) + { + op1 = Expression::Ptr(new UntypedAtomicConverter(op1, BuiltinTypes::xsDouble)); + + /* The types might have changed, reload. */ + updateType(t1, op1); + } + /* "If XPath 1.0 compatibility mode is true, a general comparison is + * evaluated by applying the following rules, in order: + * 1. If either operand is a single atomic value that is an instance of + * xs:boolean, then the other operand is converted to xs:boolean by taking + * its effective boolean value." + * + * Notably, it's not conversion to boolean, it is EBV extraction. + */ + else if(m_isBackwardsCompat && BuiltinTypes::xsBoolean->xdtTypeMatches(t1)) + { + op2 = Expression::Ptr(new EBVExtractor(op2)); + updateType(t2, op2); + } + else if(m_isBackwardsCompat && BuiltinTypes::xsBoolean->xdtTypeMatches(t2)) + { + op1 = Expression::Ptr(new EBVExtractor(op1)); + updateType(t1, op1); + } + /* b. "If one of the atomic values is an instance of xs:untypedAtomic and + * the other is an instance of xs:untypedAtomic or xs:string, then the + * xs:untypedAtomic value (or values) is (are) cast to the type xs:string." + * + * c. "If one of the atomic values is an instance of xs:untypedAtomic and the + * other is not an instance of xs:string, xs:untypedAtomic, or any numeric + * type, then the xs:untypedAtomic value is cast to the dynamic type of the + * other value." */ + else if(BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t1) && + !BuiltinTypes::xsString->xdtTypeMatches(t2) && + !BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t2) && + !BuiltinTypes::xsAnyURI->xdtTypeMatches(t2)) + { + op1 = Expression::Ptr(new UntypedAtomicConverter(op1, t2)); + updateType(t1, op1); + } + else if(BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t2) && + !BuiltinTypes::xsString->xdtTypeMatches(t1) && + !BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t1) && + !BuiltinTypes::xsAnyURI->xdtTypeMatches(t1)) + { + op2 = Expression::Ptr(new UntypedAtomicConverter(op2, t1)); + updateType(t2, op2); + } + + /* d. "After performing the conversions described above, the atomic + * values are compared using one of the value comparison operators + * eq, ne, lt, le, gt, or ge, depending on whether the general comparison + * operator was =, !=, <, <=, >, or >=. The values have the required + * magnitude relationship if and only if the result of this value comparison + * is true." */ + + return fetchComparator(t1, t2, context); +} + +OptimizationPass::List GeneralComparison::optimizationPasses() const +{ + Q_ASSERT(!OptimizationPasses::comparisonPasses.isEmpty()); + return OptimizationPasses::comparisonPasses; +} + +SequenceType::List GeneralComparison::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ZeroOrMoreAtomicTypes); + result.append(CommonSequenceTypes::ZeroOrMoreAtomicTypes); + return result; +} + +SequenceType::Ptr GeneralComparison::staticType() const +{ + return CommonSequenceTypes::ExactlyOneBoolean; +} + +ExpressionVisitorResult::Ptr GeneralComparison::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +Expression::ID GeneralComparison::id() const +{ + return IDGeneralComparison; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qgeneralcomparison_p.h b/src/xmlpatterns/expr/qgeneralcomparison_p.h new file mode 100644 index 0000000..cc83e22 --- /dev/null +++ b/src/xmlpatterns/expr/qgeneralcomparison_p.h @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_GeneralComparison_H +#define Patternist_GeneralComparison_H + +#include "qatomiccomparator_p.h" +#include "qpaircontainer_p.h" +#include "qcomparisonplatform_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Implements XPath 2.0's general comparions, such as the = operator. + * + * ComparisonPlatform is inherited with @c protected scope because ComparisonPlatform + * must access members of GeneralComparison. + * + * @see XML Path Language + * (XPath) 2.0, 3.5.2 General Comparisons + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class GeneralComparison : public PairContainer, + public ComparisonPlatform + { + public: + GeneralComparison(const Expression::Ptr &op1, + const AtomicComparator::Operator op, + const Expression::Ptr &op2, + const bool isBackwardsCompat = false); + + virtual bool evaluateEBV(const DynamicContext::Ptr &) const; + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + virtual SequenceType::List expectedOperandTypes() const; + virtual SequenceType::Ptr staticType() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + + /** + * @returns always IDGeneralComparison + */ + virtual ID id() const; + + virtual QList > optimizationPasses() const; + + /** + * @returns the operator that this GeneralComparison is using. + */ + inline AtomicComparator::Operator operatorID() const + { + return m_operator; + } + + /** + * Overridden to optimize case-insensitive compares. + */ + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + + private: + static inline void updateType(ItemType::Ptr &type, + const Expression::Ptr &source); + AtomicComparator::Ptr fetchGeneralComparator(Expression::Ptr &op1, + Expression::Ptr &op2, + const ReportContext::Ptr &context) const; + bool generalCompare(const Item &op1, + const Item &op2, + const DynamicContext::Ptr &context) const; + + const AtomicComparator::Operator m_operator; + const bool m_isBackwardsCompat; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qgenericpredicate.cpp b/src/xmlpatterns/expr/qgenericpredicate.cpp new file mode 100644 index 0000000..624d17d --- /dev/null +++ b/src/xmlpatterns/expr/qgenericpredicate.cpp @@ -0,0 +1,218 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qabstractfloat_p.h" +#include "qboolean_p.h" +#include "qbuiltintypes_p.h" +#include "qcommonsequencetypes_p.h" +#include "qemptysequence_p.h" +#include "qfirstitempredicate_p.h" +#include "qgenericsequencetype_p.h" +#include "qitemmappingiterator_p.h" +#include "qliteral_p.h" +#include "qpatternistlocale_p.h" +#include "qtruthpredicate_p.h" + +#include "qgenericpredicate_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +GenericPredicate::GenericPredicate(const Expression::Ptr &sourceExpression, + const Expression::Ptr &predicate) : PairContainer(sourceExpression, + predicate) +{ +} + +Expression::Ptr GenericPredicate::create(const Expression::Ptr &sourceExpression, + const Expression::Ptr &predicateExpression, + const StaticContext::Ptr &context, + const QSourceLocation &location) +{ + Q_ASSERT(sourceExpression); + Q_ASSERT(predicateExpression); + Q_ASSERT(context); + const ItemType::Ptr type(predicateExpression->staticType()->itemType()); + + if(predicateExpression->is(IDIntegerValue) && + predicateExpression->as()->item().as()->toInteger() == 1) + { /* Handle [1] */ + return createFirstItem(sourceExpression); + } + else if(BuiltinTypes::numeric->xdtTypeMatches(type)) + { /* A numeric predicate, other than [1]. */ + /* TODO at somepoint we'll return a specialized expr here, NumericPredicate or so. + * Dependency analysis is a bit tricky, since the contained expression can depend on + * some loop component. */ + return Expression::Ptr(new GenericPredicate(sourceExpression, predicateExpression)); + } + else if(*CommonSequenceTypes::Empty == *type) + { + return EmptySequence::create(predicateExpression.data(), context); + } + else if(*BuiltinTypes::item == *type || + *BuiltinTypes::xsAnyAtomicType == *type) + { + /* The type couldn't be narrowed at compile time, so we use + * a generic predicate. This check is before the CommonSequenceTypes::EBV check, + * because the latter matches these types as well. */ + return Expression::Ptr(new GenericPredicate(sourceExpression, predicateExpression)); + } + else if(CommonSequenceTypes::EBV->itemType()->xdtTypeMatches(type)) + { + return Expression::Ptr(new TruthPredicate(sourceExpression, predicateExpression)); + } + else + { + context->error(QtXmlPatterns::tr("A value of type %1 cannot be a " + "predicate. A predicate must have " + "either a numeric type or an " + "Effective Boolean Value type.") + .arg(formatType(context->namePool(), + sourceExpression->staticType())), + ReportContext::FORG0006, location); + return Expression::Ptr(); /* Silence compiler warning. */ + } +} + +Expression::Ptr GenericPredicate::createFirstItem(const Expression::Ptr &sourceExpression) + +{ + return Expression::Ptr(new FirstItemPredicate(sourceExpression)); +} + +Item GenericPredicate::mapToItem(const Item &item, + const DynamicContext::Ptr &context) const +{ + const Item::Iterator::Ptr it(m_operand2->evaluateSequence(context)); + const Item pcateItem(it->next()); + + if(!pcateItem) + return Item(); /* The predicate evaluated to the empty sequence */ + else if(pcateItem.isNode()) + return item; + /* Ok, now it must be an AtomicValue */ + else if(BuiltinTypes::numeric->xdtTypeMatches(pcateItem.type())) + { /* It's a positional predicate. */ + if(it->next()) + { + context->error(QtXmlPatterns::tr("A positional predicate must " + "evaluate to a single numeric " + "value."), + ReportContext::FORG0006, this); + return Item(); + } + + if(Double::isEqual(static_cast(context->contextPosition()), + pcateItem.as()->toDouble())) + { + return item; + } + else + return Item(); + } + else if(Boolean::evaluateEBV(pcateItem, it, context)) /* It's a truth predicate. */ + return item; + else + return Item(); +} + +Item::Iterator::Ptr GenericPredicate::evaluateSequence(const DynamicContext::Ptr &context) const +{ + const Item::Iterator::Ptr focus(m_operand1->evaluateSequence(context)); + const DynamicContext::Ptr newContext(context->createFocus()); + newContext->setFocusIterator(focus); + + return makeItemMappingIterator(ConstPtr(this), + focus, + newContext); +} + +Item GenericPredicate::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item::Iterator::Ptr focus(m_operand1->evaluateSequence(context)); + const DynamicContext::Ptr newContext(context->createFocus()); + newContext->setFocusIterator(focus); + return mapToItem(focus->next(), newContext); +} + +SequenceType::List GenericPredicate::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ZeroOrMoreItems); + result.append(CommonSequenceTypes::ZeroOrMoreItems); + return result; +} + +SequenceType::Ptr GenericPredicate::staticType() const +{ + const SequenceType::Ptr type(m_operand1->staticType()); + return makeGenericSequenceType(type->itemType(), + type->cardinality() | Cardinality::zeroOrOne()); +} + +ExpressionVisitorResult::Ptr GenericPredicate::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +ItemType::Ptr GenericPredicate::newFocusType() const +{ + return m_operand1->staticType()->itemType(); +} + +Expression::Properties GenericPredicate::properties() const +{ + return CreatesFocusForLast; +} + +QString GenericPredicate::description() const +{ + return QLatin1String("predicate"); +} + +Expression::ID GenericPredicate::id() const +{ + return IDGenericPredicate; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qgenericpredicate_p.h b/src/xmlpatterns/expr/qgenericpredicate_p.h new file mode 100644 index 0000000..d48e208 --- /dev/null +++ b/src/xmlpatterns/expr/qgenericpredicate_p.h @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_GenericPredicate_H +#define Patternist_GenericPredicate_H + +#include "qpaircontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A predicate that can handle all kinds of predicates and + * is therefore not very efficient, but can cope with all the tricky scenarios. + * + * @see FirstItemPredicate + * @see TruthPredicate + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class GenericPredicate : public PairContainer + { + public: + + /** + * Creates a predicate expression that filters the items gained + * from evaluating @p sourceExpression through the filter @p predicateExpression. + * + * This function performs type analyzis on the passed expressions, and may + * return more specialized expressions depending on the analyzis. + * + * If @p predicateExpression is an invalid predicate, an error is issued + * via the @p context. + */ + static Expression::Ptr create(const Expression::Ptr &sourceExpression, + const Expression::Ptr &predicateExpression, + const StaticContext::Ptr &context, + const QSourceLocation &location); + + static Expression::Ptr createFirstItem(const Expression::Ptr &sourceExpression); + + /** + * Creates a source iterator which is passed to the ItemMappingIterator + * and the Focus. The ItemMappingIterator modifies it with + * its QAbstractXmlForwardIterator::next() calls, and since the Focus references the same QAbstractXmlForwardIterator, + * the focus is automatically moved. + */ + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + + /** + * Doesn't return the first item from calling evaluateSequence(), but does the mapping + * manually. This avoid allocating an ItemMappingIterator. + */ + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + + inline Item mapToItem(const Item &subject, + const DynamicContext::Ptr &) const; + + virtual SequenceType::List expectedOperandTypes() const; + virtual SequenceType::Ptr staticType() const; + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + virtual ID id() const; + + /** + * @returns always CreatesFocusForLast. + */ + virtual Properties properties() const; + + virtual QString description() const; + + protected: + + /** + * Creates a GenericPredicate which filters the items from the @p sourceExpression + * through @p predicate. + * + * This constructor is protected. The proper way to create predicates is via the static + * create() function. + */ + GenericPredicate(const Expression::Ptr &sourceExpression, + const Expression::Ptr &predicate); + + /** + * @returns the ItemType of the first operand's staticType(). + */ + virtual ItemType::Ptr newFocusType() const; + + private: + typedef QExplicitlySharedDataPointer ConstPtr; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qifthenclause.cpp b/src/xmlpatterns/expr/qifthenclause.cpp new file mode 100644 index 0000000..cd9cbc3 --- /dev/null +++ b/src/xmlpatterns/expr/qifthenclause.cpp @@ -0,0 +1,152 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonsequencetypes_p.h" +#include "qgenericsequencetype_p.h" +#include "qoptimizationpasses_p.h" + +#include "qifthenclause_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +IfThenClause::IfThenClause(const Expression::Ptr &test, + const Expression::Ptr &then, + const Expression::Ptr &el) : TripleContainer(test, then, el) +{ +} + +Item::Iterator::Ptr IfThenClause::evaluateSequence(const DynamicContext::Ptr &context) const +{ + return m_operand1->evaluateEBV(context) + ? m_operand2->evaluateSequence(context) + : m_operand3->evaluateSequence(context); +} + +Item IfThenClause::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + return m_operand1->evaluateEBV(context) + ? m_operand2->evaluateSingleton(context) + : m_operand3->evaluateSingleton(context); +} + +bool IfThenClause::evaluateEBV(const DynamicContext::Ptr &context) const +{ + return m_operand1->evaluateEBV(context) + ? m_operand2->evaluateEBV(context) + : m_operand3->evaluateEBV(context); +} + +void IfThenClause::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const +{ + if(m_operand1->evaluateEBV(context)) + m_operand2->evaluateToSequenceReceiver(context); + else + m_operand3->evaluateToSequenceReceiver(context); +} + +Expression::Ptr IfThenClause::compress(const StaticContext::Ptr &context) +{ + const Expression::Ptr me(TripleContainer::compress(context)); + + if(me != this) + return me; + + /* All operands mustn't be evaluated in order for const folding to + * be possible. Let's see how far we get. */ + + if(m_operand1->isEvaluated()) + { + if(m_operand1->evaluateEBV(context->dynamicContext())) + return m_operand2; + else + return m_operand3; + } + else + return me; +} + +QList > IfThenClause::optimizationPasses() const +{ + return OptimizationPasses::ifThenPasses; +} + +SequenceType::List IfThenClause::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::EBV); + result.append(CommonSequenceTypes::ZeroOrMoreItems); + result.append(CommonSequenceTypes::ZeroOrMoreItems); + return result; +} + +SequenceType::Ptr IfThenClause::staticType() const +{ + const SequenceType::Ptr t1(m_operand2->staticType()); + const SequenceType::Ptr t2(m_operand3->staticType()); + + return makeGenericSequenceType(t1->itemType() | t2->itemType(), + t1->cardinality() | t2->cardinality()); +} + +ExpressionVisitorResult::Ptr IfThenClause::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +Expression::ID IfThenClause::id() const +{ + return IDIfThenClause; +} + +/* +Expression::Properties IfThenClause::properties() const +{ + return m_operand1->properties() + | m_operand2->properties() + | m_operand3->properties() + & ( Expression::RequiresFocus + | Expression::IsEvaluated + | Expression::DisableElimination); +} +*/ +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qifthenclause_p.h b/src/xmlpatterns/expr/qifthenclause_p.h new file mode 100644 index 0000000..e24d5d0 --- /dev/null +++ b/src/xmlpatterns/expr/qifthenclause_p.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_IfThenClause_H +#define Patternist_IfThenClause_H + +#include "qtriplecontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements XPath 2.0's conditional expression if([expr]) then [expr] else [expr]. + * + * @see XML Path Language (XPath) 2.0, + * 3.8 Conditional Expressions + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class IfThenClause : public TripleContainer + { + public: + IfThenClause(const Expression::Ptr &test, + const Expression::Ptr &then, + const Expression::Ptr &el); + + virtual bool evaluateEBV(const DynamicContext::Ptr &context) const; + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const; + + virtual SequenceType::List expectedOperandTypes() const; + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + + virtual SequenceType::Ptr staticType() const; + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + /** + * @returns IDIfThenClause + */ + virtual ID id() const; + virtual QList > optimizationPasses() const; + //virtual Properties properties() const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qinstanceof.cpp b/src/xmlpatterns/expr/qinstanceof.cpp new file mode 100644 index 0000000..8e6e5ce --- /dev/null +++ b/src/xmlpatterns/expr/qinstanceof.cpp @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qboolean_p.h" +#include "qcommonsequencetypes_p.h" +#include "qcommonvalues_p.h" +#include "qliteral_p.h" + +#include "qinstanceof_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +InstanceOf::InstanceOf(const Expression::Ptr &operand, + const SequenceType::Ptr &tType) : SingleContainer(operand) + , m_targetType(tType) +{ + Q_ASSERT(m_targetType); +} + +bool InstanceOf::evaluateEBV(const DynamicContext::Ptr &context) const +{ + const Item::Iterator::Ptr it(m_operand->evaluateSequence(context)); + Item item(it->next()); + unsigned int count = 1; + + if(!item) + return m_targetType->cardinality().allowsEmpty(); + + do + { + if(!m_targetType->itemType()->itemMatches(item)) + return false; + + if(count == 2 && !m_targetType->cardinality().allowsMany()) + return false; + + item = it->next(); + ++count; + } while(item); + + return true; +} + +Expression::Ptr InstanceOf::compress(const StaticContext::Ptr &context) +{ + const Expression::Ptr me(SingleContainer::compress(context)); + + if(me != this || m_operand->has(DisableTypingDeduction)) + return me; + + const SequenceType::Ptr opType(m_operand->staticType()); + const ItemType::Ptr targetType(m_targetType->itemType()); + const ItemType::Ptr operandType(opType->itemType()); + + if(m_targetType->cardinality().isMatch(opType->cardinality())) + { + if(*operandType == *CommonSequenceTypes::Empty || targetType->xdtTypeMatches(operandType)) + return wrapLiteral(CommonValues::BooleanTrue, context, this); + else if(!operandType->xdtTypeMatches(targetType)) + return wrapLiteral(CommonValues::BooleanFalse, context, this); + } + /* Optimization: rule out the case where instance of will always fail. */ + + return me; +} + +SequenceType::Ptr InstanceOf::targetType() const +{ + return m_targetType; +} + +SequenceType::Ptr InstanceOf::staticType() const +{ + return CommonSequenceTypes::ExactlyOneBoolean; +} + +SequenceType::List InstanceOf::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ZeroOrMoreItems); + return result; +} + +ExpressionVisitorResult::Ptr InstanceOf::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qinstanceof_p.h b/src/xmlpatterns/expr/qinstanceof_p.h new file mode 100644 index 0000000..d3da026 --- /dev/null +++ b/src/xmlpatterns/expr/qinstanceof_p.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_InstanceOf_H +#define Patternist_InstanceOf_H + +#include "qsinglecontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Implements XPath 2.0's instance of expression. + * + * @see XML Path Language (XPath) 2.0, + * 3.10.1 Instance Of + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class Q_AUTOTEST_EXPORT InstanceOf : public SingleContainer + { + public: + + InstanceOf(const Expression::Ptr &operand, + const SequenceType::Ptr &targetType); + + virtual bool evaluateEBV(const DynamicContext::Ptr &) const; + + virtual SequenceType::List expectedOperandTypes() const; + virtual SequenceType::Ptr staticType() const; + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + + /** + * @returns the SequenceType that this instance of Expression + * is testing its operand against. + */ + SequenceType::Ptr targetType() const; + + private: + const SequenceType::Ptr m_targetType; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qletclause.cpp b/src/xmlpatterns/expr/qletclause.cpp new file mode 100644 index 0000000..d3e939b --- /dev/null +++ b/src/xmlpatterns/expr/qletclause.cpp @@ -0,0 +1,142 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qboolean_p.h" +#include "qcommonsequencetypes_p.h" +#include "qdynamiccontextstore_p.h" +#include "qliteral_p.h" + +#include "qletclause_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +LetClause::LetClause(const Expression::Ptr &operand1, + const Expression::Ptr &operand2, + const VariableDeclaration::Ptr &decl) : PairContainer(operand1, operand2) + , m_varDecl(decl) +{ + Q_ASSERT(m_varDecl); +} + +DynamicContext::Ptr LetClause::bindVariable(const DynamicContext::Ptr &context) const +{ + context->setExpressionVariable(m_varDecl->slot, Expression::Ptr(new DynamicContextStore(m_operand1, context))); + return context; +} + +Item::Iterator::Ptr LetClause::evaluateSequence(const DynamicContext::Ptr &context) const +{ + return m_operand2->evaluateSequence(bindVariable(context)); +} + +Item LetClause::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + return m_operand2->evaluateSingleton(bindVariable(context)); +} + +bool LetClause::evaluateEBV(const DynamicContext::Ptr &context) const +{ + return m_operand2->evaluateEBV(bindVariable(context)); +} + +void LetClause::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const +{ + m_operand2->evaluateToSequenceReceiver(bindVariable(context)); +} + +Expression::Ptr LetClause::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + /* Consider the following query: + * + * let $d := \ + * return $d//\*[let $i := @type + * return $d//\*[$i]] + * + * The node test @type is referenced from two different places, + * where each reference have a different focus. So, in the case of that the source + * uses the focus, we need to use a DynamicContextStore to ensure the variable + * is always evaluated with the correct focus, regardless of where it is referenced + * from. + * + * We miss out a lot of false positives. For instance, the case of where the focus + * is identical for everyone. One reason we cannot check this, is that Expression + * doesn't know about its parent. + */ + m_varDecl->canSourceRewrite = !m_operand1->deepProperties().testFlag(RequiresFocus); + + if(m_varDecl->canSourceRewrite) + return m_operand2->typeCheck(context, reqType); + else + return PairContainer::typeCheck(context, reqType); +} + +Expression::Properties LetClause::properties() const +{ + return m_varDecl->expression()->properties() & (Expression::RequiresFocus | Expression::IsEvaluated | Expression::DisableElimination); +} + +SequenceType::List LetClause::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ZeroOrMoreItems); + result.append(CommonSequenceTypes::ZeroOrMoreItems); + return result; +} + +SequenceType::Ptr LetClause::staticType() const +{ + return m_operand2->staticType(); +} + +ExpressionVisitorResult::Ptr LetClause::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +Expression::ID LetClause::id() const +{ + return IDLetClause; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qletclause_p.h b/src/xmlpatterns/expr/qletclause_p.h new file mode 100644 index 0000000..24a7bb1 --- /dev/null +++ b/src/xmlpatterns/expr/qletclause_p.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_LetClause_H +#define Patternist_LetClause_H + +#include "qpaircontainer_p.h" +#include "qvariabledeclaration_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Represents a let-clause, but is only used at compile + * time. + * + * LetClause is inserted into the AST tree for the single purpose of + * ensuring that the focus is correct for the binding expression. Once + * that is done, LetClause sometimes rewrites itself to its + * return expression, and the ExpressionVariableReference will + * handle the evaluation of the variable. + * + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class LetClause : public PairContainer + { + public: + LetClause(const Expression::Ptr &operand1, + const Expression::Ptr &operand2, + const VariableDeclaration::Ptr &decl); + + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + virtual bool evaluateEBV(const DynamicContext::Ptr &context) const; + virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const; + + virtual SequenceType::List expectedOperandTypes() const; + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + virtual SequenceType::Ptr staticType() const; + virtual Properties properties() const; + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + virtual ID id() const; + + private: + inline DynamicContext::Ptr bindVariable(const DynamicContext::Ptr &context) const; + + const VariableDeclaration::Ptr m_varDecl; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qliteral.cpp b/src/xmlpatterns/expr/qliteral.cpp new file mode 100644 index 0000000..ac68fe3 --- /dev/null +++ b/src/xmlpatterns/expr/qliteral.cpp @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qboolean_p.h" +#include "qbuiltintypes_p.h" +#include "qcommonsequencetypes_p.h" +#include "qgenericsequencetype_p.h" + +#include "qliteral_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Literal::Literal(const Item &i) : m_item(i) +{ + Q_ASSERT(m_item); + Q_ASSERT(m_item.isAtomicValue()); +} + +Item Literal::evaluateSingleton(const DynamicContext::Ptr &) const +{ + return m_item; +} + +bool Literal::evaluateEBV(const DynamicContext::Ptr &context) const +{ + return Boolean::evaluateEBV(m_item, context); +} + +void Literal::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const +{ + context->outputReceiver()->item(m_item); +} + +SequenceType::Ptr Literal::staticType() const +{ + return makeGenericSequenceType(m_item.type(), Cardinality::exactlyOne()); +} + +ExpressionVisitorResult::Ptr Literal::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +Expression::ID Literal::id() const +{ + Q_ASSERT(m_item); + Q_ASSERT(m_item.isAtomicValue()); + const ItemType::Ptr t(m_item.type()); + + if(BuiltinTypes::xsBoolean->xdtTypeMatches(t)) + return IDBooleanValue; + else if(BuiltinTypes::xsString->xdtTypeMatches(t) || + BuiltinTypes::xsAnyURI->xdtTypeMatches(t) || + BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t)) + { + return IDStringValue; + } + else if(BuiltinTypes::xsInteger->xdtTypeMatches(t)) + return IDIntegerValue; + else + return IDFloat; +} + +Expression::Properties Literal::properties() const +{ + return IsEvaluated; +} + +QString Literal::description() const +{ + return m_item.stringValue(); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qliteral_p.h b/src/xmlpatterns/expr/qliteral_p.h new file mode 100644 index 0000000..aec7d53 --- /dev/null +++ b/src/xmlpatterns/expr/qliteral_p.h @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_Literal_H +#define Patternist_Literal_H + +#include "qemptycontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Houses an AtomicValue, making it available as an Expression. + * + * This is not only literals that can be created via the XQuery syntax(strings and numbers), but + * all other atomic values, such as xs:date or xs:time. + * + * @see XQuery 1.0: An XML Query Language, + * 3.1.1 Literals + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class Literal : public EmptyContainer + { + public: + /** + * Creates a Literal that represents @p item. + * + * @param item must be non-null and cannot be a QXmlNodeModelIndex. + */ + Literal(const Item &item); + + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + virtual bool evaluateEBV(const DynamicContext::Ptr &context) const; + void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const; + + virtual SequenceType::Ptr staticType() const; + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + virtual ID id() const; + virtual QString description() const; + + /** + * @returns Expression::DisableElimination and Expression::IsEvaluated + */ + virtual Properties properties() const; + + /** + * Declaring the return value of this function a const reference, leads + * to crashes in patternistview, for a to me unknown reason. + */ + inline Item item() const + { + return m_item; + } + + private: + const Item m_item; + }; + + /** + * @short Creates a Literal that wraps @p item, and returns it. + * + * This simplifies code. Instead of writing: + * + * @code + * Expression::Ptr(new Literal(item)); + * @endcode + * + * One can write: + * + * @code + * wrapLiteral(item); + * @endcode + * + * This function is not declared static, because it breaks the build on + * at least aix-xlc-64. + * + * @relates Literal + */ + inline Expression::Ptr wrapLiteral(const Item &item, + const StaticContext::Ptr &context, + const SourceLocationReflection *const r) + { + Q_ASSERT(item); + + const Expression::Ptr retval(new Literal(item)); + context->addLocation(retval.data(), context->locationFor(r)); + + return retval; + } +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qliteralsequence.cpp b/src/xmlpatterns/expr/qliteralsequence.cpp new file mode 100644 index 0000000..dfd0fd6 --- /dev/null +++ b/src/xmlpatterns/expr/qliteralsequence.cpp @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" +#include "qcommonsequencetypes_p.h" +#include "qgenericsequencetype_p.h" + +#include "qliteralsequence_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +LiteralSequence::LiteralSequence(const Item::List &list) : m_list(list) +{ + Q_ASSERT(list.size() >= 2); +} + +Item::Iterator::Ptr LiteralSequence::evaluateSequence(const DynamicContext::Ptr &) const +{ + return makeListIterator(m_list); +} + +SequenceType::Ptr LiteralSequence::staticType() const +{ + const Item::List::const_iterator end(m_list.constEnd()); + Item::List::const_iterator it(m_list.constBegin()); + + /* Load the first item. */ + ItemType::Ptr t((*it).type()); + ++it; + + for(; end != it; ++it) + t |= (*it).type(); + + return makeGenericSequenceType(t, Cardinality::fromCount(m_list.size())); +} + +ExpressionVisitorResult::Ptr LiteralSequence::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +Expression::ID LiteralSequence::id() const +{ + return IDExpressionSequence; +} + +Expression::Properties LiteralSequence::properties() const +{ + return IsEvaluated; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qliteralsequence_p.h b/src/xmlpatterns/expr/qliteralsequence_p.h new file mode 100644 index 0000000..6699ce0 --- /dev/null +++ b/src/xmlpatterns/expr/qliteralsequence_p.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_LiteralSequence_H +#define Patternist_LiteralSequence_H + +#include "qemptycontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Houses a sequence of atomic values, making it available as an Expression. + * + * This is not only literals that can be created via the XQuery syntax(strings and numbers), but + * all other atomic values, such as xs:date or xs:time. It is not guaranteed + * that consecutive atomic values are represented in a LiteralSequence. + * + * @see XQuery 1.0: An XML Query Language, + * 3.1.1 Literals + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class LiteralSequence : public EmptyContainer + { + public: + /** + * Creates a LiteralSequence that represents @p item. + * + * @param list the list of item. No entry may be @c null. The list + * must at least be two entries large. + */ + LiteralSequence(const Item::List &list); + + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + virtual SequenceType::Ptr staticType() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + + virtual ID id() const; + + virtual Properties properties() const; + + private: + const Item::List m_list; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qnamespaceconstructor.cpp b/src/xmlpatterns/expr/qnamespaceconstructor.cpp new file mode 100644 index 0000000..c6838ee --- /dev/null +++ b/src/xmlpatterns/expr/qnamespaceconstructor.cpp @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonsequencetypes_p.h" + +#include "qnamespaceconstructor_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +NamespaceConstructor::NamespaceConstructor(const QXmlName nb) : m_binding(nb) +{ + Q_ASSERT(!m_binding.isNull()); +} + +void NamespaceConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const +{ + context->outputReceiver()->namespaceBinding(m_binding); +} + +SequenceType::Ptr NamespaceConstructor::staticType() const +{ + return CommonSequenceTypes::ExactlyOneAttribute; +} + +SequenceType::List NamespaceConstructor::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ExactlyOneString); + return result; +} + +Expression::Properties NamespaceConstructor::properties() const +{ + return DisableElimination | IsNodeConstructor; +} + +ExpressionVisitorResult::Ptr NamespaceConstructor::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +Expression::ID NamespaceConstructor::id() const +{ + return IDNamespaceConstructor; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qnamespaceconstructor_p.h b/src/xmlpatterns/expr/qnamespaceconstructor_p.h new file mode 100644 index 0000000..5b73d37 --- /dev/null +++ b/src/xmlpatterns/expr/qnamespaceconstructor_p.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_NamespaceConstructor_H +#define Patternist_NamespaceConstructor_H + +#include "qemptycontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Constructs a namespace on an element, and naturally only appears + * as a child of ElementConstructor. + * + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class NamespaceConstructor : public EmptyContainer + { + public: + NamespaceConstructor(const QXmlName nb); + + virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const; + + /** + * @returns a list containing one CommonSequenceTypes::ExactlyOneString instance. + */ + virtual SequenceType::List expectedOperandTypes() const; + + /** + * The static type is exactly one attribute node. It's unclear what + * affects the static type has, but specifying anything else could lead + * to complications wrt. node order, XQTY0024. Of course, it's not + * conceptually correct, since a namespace node isn't an attribute + * node. + */ + virtual SequenceType::Ptr staticType() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + virtual Expression::Properties properties() const; + + inline const QXmlName &namespaceBinding() const + { + return m_binding; + } + + virtual ID id() const; + private: + const QXmlName m_binding; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qncnameconstructor.cpp b/src/xmlpatterns/expr/qncnameconstructor.cpp new file mode 100644 index 0000000..b1d2739 --- /dev/null +++ b/src/xmlpatterns/expr/qncnameconstructor.cpp @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" +#include "qcommonsequencetypes_p.h" +#include "qatomicstring_p.h" + +#include "qncnameconstructor_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +NCNameConstructor::NCNameConstructor(const Expression::Ptr &source) : SingleContainer(source) +{ +} + +Item NCNameConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + Q_ASSERT(context); + /* Apply the whitespace facet for when casting to xs:NCName. */ + const QString lexNCName(m_operand->evaluateSingleton(context).stringValue().trimmed()); + + validateTargetName(lexNCName, + context, + this); + return AtomicString::fromValue(lexNCName); +} + +Expression::Ptr NCNameConstructor::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + if(BuiltinTypes::xsNCName->xdtTypeMatches(m_operand->staticType()->itemType())) + return m_operand->typeCheck(context, reqType); + else + return SingleContainer::typeCheck(context, reqType); +} + +SequenceType::Ptr NCNameConstructor::staticType() const +{ + return CommonSequenceTypes::ExactlyOneString; +} + +SequenceType::List NCNameConstructor::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ExactlyOneString); + return result; +} + +ExpressionVisitorResult::Ptr NCNameConstructor::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qncnameconstructor_p.h b/src/xmlpatterns/expr/qncnameconstructor_p.h new file mode 100644 index 0000000..02163c5 --- /dev/null +++ b/src/xmlpatterns/expr/qncnameconstructor_p.h @@ -0,0 +1,154 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_NCNameConstructor_H +#define Patternist_NCNameConstructor_H + +#include "qsinglecontainer_p.h" +#include "qpatternistlocale_p.h" +#include "private/qxmlutils_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Ensures the lexical space of the string value of the Item returned + * from its child Expression is an NCName. + * + * @note It doesn't actually construct an @c xs:NCName. It only ensures the lexical + * space is an @c NCName. The atomic value can be of any string type, such as @c xs:untypedAtomic + * of @c xs:string. + * + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class NCNameConstructor : public SingleContainer + { + public: + + NCNameConstructor(const Expression::Ptr &source); + + virtual Item evaluateSingleton(const DynamicContext::Ptr &) const; + + virtual SequenceType::List expectedOperandTypes() const; + + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + virtual SequenceType::Ptr staticType() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + + /** + * Validates @p lexicalNCName as a processing instruction's target + * name, and raise an error if it's not an @c NCName. + */ + template + static inline + void validateTargetName(const QString &lexicalNCName, + const TReportContext &context, + const SourceLocationReflection *const r); + private: + + /** + * This translation string is put here in order to avoid duplicate messages and + * hence reduce work for translators and increase consistency. + */ + static + const QString nameIsXML(const QString &lexTarget) + { + return QtXmlPatterns::tr("The target name in a processing instruction " + "cannot be %1 in any combination of upper " + "and lower case. Therefore, %2 is invalid.") + .arg(formatKeyword("xml"), formatKeyword(lexTarget)); + } + }; + + template + inline + void NCNameConstructor::validateTargetName(const QString &lexicalTarget, + const TReportContext &context, + const SourceLocationReflection *const r) + { + Q_ASSERT(context); + + if(QXmlUtils::isNCName(lexicalTarget)) + { + if(QString::compare(QLatin1String("xml"), lexicalTarget, Qt::CaseInsensitive) == 0) + context->error(nameIsXML(lexicalTarget), NameIsXML, r); + } + else + { + context->error(QtXmlPatterns::tr("%1 is not a valid target name in " + "a processing instruction. It " + "must be a %2 value, e.g. %3.") + .arg(formatKeyword(lexicalTarget)) + .arg(formatType(context->namePool(), + BuiltinTypes::xsNCName)) + .arg(formatKeyword("my-name.123")), + LexicallyInvalid, + r); + } + } +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qnodecomparison.cpp b/src/xmlpatterns/expr/qnodecomparison.cpp new file mode 100644 index 0000000..ba262fd --- /dev/null +++ b/src/xmlpatterns/expr/qnodecomparison.cpp @@ -0,0 +1,184 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonsequencetypes_p.h" +#include "qcommonvalues_p.h" +#include "qemptysequence_p.h" +#include "qinteger_p.h" +#include "qschemanumeric_p.h" +#include "qrangeiterator_p.h" + +#include "qnodecomparison_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +NodeComparison::NodeComparison(const Expression::Ptr &operand1, + const QXmlNodeModelIndex::DocumentOrder op, + const Expression::Ptr &operand2) + : PairContainer(operand1, operand2) + , m_op(op) +{ + Q_ASSERT(op == QXmlNodeModelIndex::Precedes || + op == QXmlNodeModelIndex::Follows || + op == QXmlNodeModelIndex::Is); +} + +Item NodeComparison::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + switch(evaluate(context)) + { + case True: + return CommonValues::BooleanTrue; + case False: + return CommonValues::BooleanFalse; + default: + return Item(); + } +} + +bool NodeComparison::evaluateEBV(const DynamicContext::Ptr &context) const +{ + switch(evaluate(context)) + { + case True: + return true; + default: + /* We include the empty sequence here. */ + return false; + } +} + +NodeComparison::Result NodeComparison::evaluate(const DynamicContext::Ptr &context) const +{ + const Item op1(m_operand1->evaluateSingleton(context)); + if(!op1) + return Empty; + + const Item op2(m_operand2->evaluateSingleton(context)); + if(!op2) + return Empty; + + /* We just returns an arbitrary value, since there's no order defined for nodes from different + * models, except for that the return value must be stable. */ + if(op1.asNode().model() != op2.asNode().model()) + return False; + + switch(m_op) + { + case QXmlNodeModelIndex::Is: + return op1.asNode().is(op2.asNode()) ? True : False; + case QXmlNodeModelIndex::Precedes: + return op1.asNode().compareOrder(op2.asNode()) == QXmlNodeModelIndex::Precedes ? True : False; + default: + { + Q_ASSERT(m_op == QXmlNodeModelIndex::Follows); + return op1.asNode().compareOrder(op2.asNode()) == QXmlNodeModelIndex::Follows ? True : False; + } + } +} + + +SequenceType::List NodeComparison::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ZeroOrOneNode); + result.append(CommonSequenceTypes::ZeroOrOneNode); + return result; +} + +Expression::Ptr NodeComparison::compress(const StaticContext::Ptr &context) +{ + const Expression::Ptr me(PairContainer::compress(context)); + + if(me != this) + /* We're already rewritten. */ + return me; + + if(m_operand1->staticType()->cardinality().isEmpty() || + m_operand2->staticType()->cardinality().isEmpty()) + { + // TODO issue a warning in the @p context saying that one of the operands + // were empty, and that the expression always result in the empty sequence + // (which never is the intent, right?). + return EmptySequence::create(this, context); + } + + return Expression::Ptr(this); +} + +QString NodeComparison::displayName(const QXmlNodeModelIndex::DocumentOrder op) +{ + switch(op) + { + case QXmlNodeModelIndex::Is: + return QLatin1String("is"); + case QXmlNodeModelIndex::Precedes: + return QLatin1String("<<"); + default: + { + Q_ASSERT(op == QXmlNodeModelIndex::Follows); + return QLatin1String(">>"); + } + } +} + +SequenceType::Ptr NodeComparison::staticType() const +{ + if(m_operand1->staticType()->cardinality().allowsEmpty() || + m_operand2->staticType()->cardinality().allowsEmpty()) + return CommonSequenceTypes::ZeroOrOneBoolean; + else + return CommonSequenceTypes::ExactlyOneBoolean; +} + +QXmlNodeModelIndex::DocumentOrder NodeComparison::operatorID() const +{ + return m_op; +} + +ExpressionVisitorResult::Ptr NodeComparison::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qnodecomparison_p.h b/src/xmlpatterns/expr/qnodecomparison_p.h new file mode 100644 index 0000000..86af0f6 --- /dev/null +++ b/src/xmlpatterns/expr/qnodecomparison_p.h @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_NodeComparison_H +#define Patternist_NodeComparison_H + +#include "qpaircontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Implements the node comparison operators \>\>, \<\<, and @c is. + * + * @see XML Path Language + * (XPath) 2.0, 3.5.3 QXmlNodeModelIndex Comparisons + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class Q_AUTOTEST_EXPORT NodeComparison : public PairContainer + { + public: + NodeComparison(const Expression::Ptr &operand1, + const QXmlNodeModelIndex::DocumentOrder op, + const Expression::Ptr &operand2); + + virtual Item evaluateSingleton(const DynamicContext::Ptr &) const; + virtual bool evaluateEBV(const DynamicContext::Ptr &) const; + + virtual SequenceType::List expectedOperandTypes() const; + + virtual QXmlNodeModelIndex::DocumentOrder operatorID() const; + /** + * If any operator is the empty sequence, the NodeComparison rewrites + * into that, since the empty sequence is always the result in that case. + */ + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + + /** + * @returns either CommonSequenceTypes::ZeroOrOneBoolean or + * CommonSequenceTypes::ExactlyOneBoolean depending on the static + * cardinality of its operands. + */ + virtual SequenceType::Ptr staticType() const; + + /** + * Determines the string representation for a node comparison operator. + * + * @returns + * - "<<" if @p op is Precedes + * - ">>" if @p op is Follows + * - "is" if @p op is Is + */ + static QString displayName(const QXmlNodeModelIndex::DocumentOrder op); + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + private: + enum Result + { + Empty, + True, + False + }; + inline Result evaluate(const DynamicContext::Ptr &context) const; + + const QXmlNodeModelIndex::DocumentOrder m_op; + + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qnodesort.cpp b/src/xmlpatterns/expr/qnodesort.cpp new file mode 100644 index 0000000..171fbc0 --- /dev/null +++ b/src/xmlpatterns/expr/qnodesort.cpp @@ -0,0 +1,142 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonsequencetypes_p.h" +#include "qdeduplicateiterator_p.h" +#include "qnodesort_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +NodeSortExpression::NodeSortExpression(const Expression::Ptr &op) : SingleContainer(op) +{ +} + +bool NodeSortExpression::lessThanUsingNodeModel(const Item &n1, + const Item &n2) +{ + Q_ASSERT(n1.isNode()); + Q_ASSERT(n2.isNode()); + + if(n1.asNode().model() == n2.asNode().model()) + return n1.asNode().compareOrder(n2.asNode()) == QXmlNodeModelIndex::Precedes; + else + { + /* The two nodes are from different trees. The sort order is implementation + * defined, but it must be stable. + * + * We do this by looking at the pointer difference. The value means nothing, + * but it is stable, and that's what we're looking for. */ + return n1.asNode().model() - n2.asNode().model() < 0; + } +} + +Item::Iterator::Ptr NodeSortExpression::evaluateSequence(const DynamicContext::Ptr &context) const +{ + Q_ASSERT_X(m_operand->staticType()->cardinality().allowsMany(), Q_FUNC_INFO, + "It makes no sense to sort a single node."); + + Item::List nodes(m_operand->evaluateSequence(context)->toList()); + + if(nodes.isEmpty()) + return CommonValues::emptyIterator; + else if(nodes.first().isAtomicValue()) + return makeListIterator(nodes); + else + { + qSort(nodes.begin(), nodes.end(), lessThanUsingNodeModel); + + return Item::Iterator::Ptr(new DeduplicateIterator(nodes)); + } +} + +Expression::Ptr NodeSortExpression::wrapAround(const Expression::Ptr &operand, + const StaticContext::Ptr &context) +{ + Q_ASSERT(operand); + Q_ASSERT(context); + + const Expression::Ptr sort(new NodeSortExpression(operand)); + context->wrapExpressionWith(operand.data(), sort); + return sort; +} + +Expression::Ptr NodeSortExpression::compress(const StaticContext::Ptr &context) +{ + const Expression::Ptr me(SingleContainer::compress(context)); + + /* It make no sense to sort & deduplicate a single node. */ + if(m_operand->staticType()->cardinality().allowsMany()) + return me; + else + return m_operand; +} + +SequenceType::Ptr NodeSortExpression::staticType() const +{ + return m_operand->staticType(); +} + +SequenceType::List NodeSortExpression::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ZeroOrMoreItems); + return result; +} + +ExpressionVisitorResult::Ptr +NodeSortExpression::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +Expression::Properties NodeSortExpression::properties() const +{ + /* The reason we disable elimination is that the assert for sorting a + * single node in evaluateSequence() triggers unless our compress() routine + * has been run. Anyhow, it's not that we would manage to write away anyway, + * since the node source in most(all?) cases prevents it. + */ + return AffectsOrderOnly | DisableElimination; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qnodesort_p.h b/src/xmlpatterns/expr/qnodesort_p.h new file mode 100644 index 0000000..850023b --- /dev/null +++ b/src/xmlpatterns/expr/qnodesort_p.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_NodeSortExpression_H +#define Patternist_NodeSortExpression_H + +#include "qsinglecontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short De-duplicates and sorts in document order the content that its + * operand returns. + * + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class NodeSortExpression : public SingleContainer + { + public: + NodeSortExpression(const Expression::Ptr &operand); + + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + virtual SequenceType::Ptr staticType() const; + virtual SequenceType::List expectedOperandTypes() const; + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + virtual Properties properties() const; + + /** + * Ensures that result delivered from @p operand, is in document order. + */ + static Expression::Ptr wrapAround(const Expression::Ptr &operand, + const StaticContext::Ptr &context); + + private: + static inline bool lessThanUsingNodeModel(const Item &n1, + const Item &n2); + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qoperandsiterator_p.h b/src/xmlpatterns/expr/qoperandsiterator_p.h new file mode 100644 index 0000000..9986ef2 --- /dev/null +++ b/src/xmlpatterns/expr/qoperandsiterator_p.h @@ -0,0 +1,193 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_OperandsIterator_H +#define Patternist_OperandsIterator_H + +#include +#include + +#include "qexpression_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A helper class that iterates a tree of Expression instances. It + * is not a sub-class of QAbstractXmlForwardIterator. + * + * The OperandsIterator delivers all Expression instances that are children at any + * depth of the Expression passed in the constructor. + * The order is delivered in a defined way, from left to right and depth + * first. + * + * @author Frans Englich + */ + class OperandsIterator + { + /** + * The second value, the int, is the current position in the first. + */ + typedef QPair Level; + + public: + enum TreatParent + { + ExcludeParent, + IncludeParent + }; + + /** + * if @p treatParent is @c IncludeParent, @p start is excluded. + * + * @p start must be a valid Expression. + */ + inline OperandsIterator(const Expression::Ptr &start, + const TreatParent treatParent) + { + Q_ASSERT(start); + if(treatParent == IncludeParent) + { + Expression::List l; + l.append(start); + m_exprs.push(qMakePair(l, -1)); + } + + m_exprs.push(qMakePair(start->operands(), -1)); + } + + /** + * @short Returns the current Expression and advances the iterator. + * + * If the end has been reached, a default constructed pointer is + * returned. + * + * We intentionally return by reference. + */ + inline Expression::Ptr next() + { + if(m_exprs.isEmpty()) + return Expression::Ptr(); + + Level &lvl = m_exprs.top(); + ++lvl.second; + + if(lvl.second == lvl.first.size()) + { + /* Resume iteration above us. */ + m_exprs.pop(); + + if(m_exprs.isEmpty()) + return Expression::Ptr(); + + while(true) + { + Level &previous = m_exprs.top(); + ++previous.second; + + if(previous.second < previous.first.count()) + { + const Expression::Ptr &op = previous.first.at(previous.second); + m_exprs.push(qMakePair(op->operands(), -1)); + return op; + } + else + { + // We have already reached the end of this level. + m_exprs.pop(); + if(m_exprs.isEmpty()) + return Expression::Ptr(); + } + } + } + else + { + const Expression::Ptr &op = lvl.first.at(lvl.second); + m_exprs.push(qMakePair(op->operands(), -1)); + return op; + } + } + + /** + * Advances this iterator by the current expression and its operands. + */ + Expression::Ptr skipOperands() + { + if(m_exprs.isEmpty()) + return Expression::Ptr(); + + Level &lvl = m_exprs.top(); + ++lvl.second; + + if(lvl.second == lvl.first.size()) + { + /* We've reached the end of this level, at least. */ + m_exprs.pop(); + } + + return next(); + } + + private: + Q_DISABLE_COPY(OperandsIterator) + + QStack m_exprs; + }; +} + + +QT_END_NAMESPACE +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qoptimizationpasses.cpp b/src/xmlpatterns/expr/qoptimizationpasses.cpp new file mode 100644 index 0000000..d970483 --- /dev/null +++ b/src/xmlpatterns/expr/qoptimizationpasses.cpp @@ -0,0 +1,182 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonsequencetypes_p.h" +#include "qoptimizerblocks_p.h" + +#include "qoptimizationpasses_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +OptimizationPass::List OptimizationPasses::comparisonPasses; +OptimizationPass::List OptimizationPasses::forPasses; +OptimizationPass::List OptimizationPasses::ifThenPasses; +OptimizationPass::List OptimizationPasses::notFN; + +void OptimizationPasses::Coordinator::init() +{ + static bool isInitialized = false; // STATIC DATA + + if(isInitialized) + return; + + isInitialized = true; + + /* Note, below is many of the building blocks re-used in several passes + * in order to reduce memory use. Thus, when changing one building block + * it potentially affects many passes. */ + + /* ****************************************************** */ + /* Rewrite "count() ge 1" into "exists()" */ + OptimizationPass::ExpressionMarker firstFirstChild; + firstFirstChild.append(0); + firstFirstChild.append(0); + + ExpressionIdentifier::List geOpIDs; + const ExpressionIdentifier::Ptr countFN(new ByIDIdentifier(Expression::IDCountFN)); + geOpIDs.append(countFN); + geOpIDs.append(ExpressionIdentifier::Ptr(new IntegerIdentifier(1))); + + QVector geMatcher; + geMatcher.append(Expression::IDValueComparison); + geMatcher.append(Expression::IDGeneralComparison); + + const ExpressionIdentifier::Ptr ge(new ComparisonIdentifier(geMatcher, + AtomicComparator::OperatorGreaterOrEqual)); + + const ExpressionCreator::Ptr existsFN(new ByIDCreator(Expression::IDExistsFN)); + const OptimizationPass::Ptr geToExists(new OptimizationPass(ge, geOpIDs, firstFirstChild, existsFN)); + comparisonPasses.append(geToExists); + /* ****************************************************** */ + + /* ****************************************************** */ + /* Rewrite "count() gt 0" into "exists()" */ + ExpressionIdentifier::List countAndIntZero; + countAndIntZero.append(countFN); + const ExpressionIdentifier::Ptr zeroInteger(new IntegerIdentifier(0)); + countAndIntZero.append(zeroInteger); + + const ExpressionIdentifier::Ptr gt(new ComparisonIdentifier(geMatcher, + AtomicComparator::OperatorGreaterThan)); + + const OptimizationPass::Ptr gtToExists(new OptimizationPass(gt, countAndIntZero, + firstFirstChild, existsFN)); + comparisonPasses.append(gtToExists); + /* ****************************************************** */ + + /* ****************************************************** */ + /* Rewrite "count() ne 0" into "exists()" */ + + const ExpressionIdentifier::Ptr ne(new ComparisonIdentifier(geMatcher, + AtomicComparator::OperatorNotEqual)); + const OptimizationPass::Ptr neToExists(new OptimizationPass(ne, countAndIntZero, firstFirstChild, + existsFN, + OptimizationPass::AnyOrder)); + comparisonPasses.append(neToExists); + /* ****************************************************** */ + + /* ****************************************************** */ + /* Rewrite "count() eq 0" into "empty()" */ + ExpressionIdentifier::List eqOpIDs; + eqOpIDs.append(countFN); + eqOpIDs.append(zeroInteger); + const ExpressionCreator::Ptr emptyFN(new ByIDCreator(Expression::IDEmptyFN)); + const ExpressionIdentifier::Ptr eq(new ComparisonIdentifier(geMatcher, + AtomicComparator::OperatorEqual)); + const OptimizationPass::Ptr eqToEmpty(new OptimizationPass(eq, eqOpIDs, firstFirstChild, + emptyFN, + OptimizationPass::AnyOrder)); + comparisonPasses.append(eqToEmpty); + + /* ****************************************************** */ + + /* ****************************************************** */ + /* Rewrite "for $var in return $var" into "" */ + ExpressionIdentifier::List forOps; + OptimizationPass::ExpressionMarker firstChild; + firstChild.append(0); + + forOps.append(ExpressionIdentifier::Ptr()); + forOps.append(ExpressionIdentifier::Ptr(new ByIDIdentifier(Expression::IDRangeVariableReference))); + const OptimizationPass::Ptr simplifyFor(new OptimizationPass(ExpressionIdentifier::Ptr(), forOps, + firstChild, ExpressionCreator::Ptr())); + forPasses.append(simplifyFor); + /* ****************************************************** */ + + /* ****************************************************** */ + /* Rewrite "if() then true() else false()" to "" */ + OptimizationPass::ExpressionMarker marker; + marker.append(0); + + ExpressionIdentifier::List opIDs; + opIDs.append(ExpressionIdentifier::Ptr(new BySequenceTypeIdentifier( + CommonSequenceTypes::ExactlyOneBoolean))); + opIDs.append(ExpressionIdentifier::Ptr(new BooleanIdentifier(true))); + opIDs.append(ExpressionIdentifier::Ptr(new BooleanIdentifier(false))); + + const OptimizationPass::Ptr pass(new OptimizationPass(ExpressionIdentifier::Ptr(), opIDs, marker)); + ifThenPasses.append(pass); + /* ****************************************************** */ + + /* ****************************************************** */ + /* Rewrite "not(exists(X))" into "empty(X)" */ + ExpressionIdentifier::List idExistsFN; + idExistsFN.append(ExpressionIdentifier::Ptr(new ByIDIdentifier(Expression::IDExistsFN))); + + notFN.append(OptimizationPass::Ptr(new OptimizationPass(ExpressionIdentifier::Ptr(), + idExistsFN, + firstFirstChild, + emptyFN))); + + /* Rewrite "not(empty(X))" into "exists(X)" */ + ExpressionIdentifier::List idEmptyFN; + idEmptyFN.append(ExpressionIdentifier::Ptr(new ByIDIdentifier(Expression::IDEmptyFN))); + + notFN.append(OptimizationPass::Ptr(new OptimizationPass(ExpressionIdentifier::Ptr(), + idEmptyFN, + firstFirstChild, + existsFN))); + /* ****************************************************** */ +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qoptimizationpasses_p.h b/src/xmlpatterns/expr/qoptimizationpasses_p.h new file mode 100644 index 0000000..6f10572 --- /dev/null +++ b/src/xmlpatterns/expr/qoptimizationpasses_p.h @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_OptimizationBlocks_H +#define Patternist_OptimizationBlocks_H + +#include "qatomiccomparator_p.h" +#include "qexpression_p.h" +#include "qoptimizerframework_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Contains a set of common OptimizerPass instances. + * + * @author Frans englich + * @ingroup Patternist_expressions + */ + namespace OptimizationPasses + { + /** + * A list of OptimizerPass instances that performs the + * following rewrites: + * + * - count([expr]) ne 0 into exists([expr]) + * - count([expr]) != 0 into exists([expr]) + * - 0 ne count([expr]) into exists([expr]) + * - 0 != count([expr]) into exists([expr]) + * - count([expr]) eq 0 into empty([expr]) + * - count([expr]) = 0 into empty([expr]) + * - 0 eq count([expr]) into empty([expr]) + * - 0 = count([expr]) into empty([expr]) + * - count([expr]) ge 1 into exists([expr]) + * - count([expr]) >= 1 into exists([expr]) + */ + extern OptimizationPass::List comparisonPasses; + + /** + * A list of OptimizerPass instances that performs the + * following rewrites: + * + * - for $var in [expr] return $var into [expr] + */ + extern OptimizationPass::List forPasses; + + /** + * A list of OptimizerPass instances that performs the + * following rewrites: + * + * - if([expr of type xs:boolean]) then true() else false() + * into [expr of type xs:boolean] + */ + extern OptimizationPass::List ifThenPasses; + + /** + * A list of OptimizerPass instances that performs the + * following rewrites: + * + * - fn:not(fn:exists([expr])) into fn:empty([expr]) + * - fn:not(fn:empty([expr])) into fn:exists([expr]) + */ + extern OptimizationPass::List notFN; + + /** + * Initializes the data members in the OptimizationPasses namespace. + * + * This class is not supposed to be instantiated, but to be used via its init() + * function. In fact, this class cannot be instantiated. + * + * @author Frans englich + */ + class Coordinator + { + public: + /** + * Initializes the members in the OptimizationPasses namespace. + */ + static void init(); + + private: + Q_DISABLE_COPY(Coordinator) + inline Coordinator(); + }; + } +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qoptimizerblocks.cpp b/src/xmlpatterns/expr/qoptimizerblocks.cpp new file mode 100644 index 0000000..511faae --- /dev/null +++ b/src/xmlpatterns/expr/qoptimizerblocks.cpp @@ -0,0 +1,179 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonnamespaces_p.h" + +#include "qcommonsequencetypes_p.h" +#include "qfunctionfactory_p.h" +#include "qgeneralcomparison_p.h" +#include "qliteral_p.h" +#include "qschemanumeric_p.h" +#include "qvaluecomparison_p.h" + +#include "qoptimizerblocks_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +ByIDIdentifier::ByIDIdentifier(const Expression::ID id) : m_id(id) +{ +} + +bool ByIDIdentifier::matches(const Expression::Ptr &expr) const +{ + return expr->is(m_id); +} + +ComparisonIdentifier::ComparisonIdentifier(const QVector hosts, + const AtomicComparator::Operator op) : m_hosts(hosts), + m_op(op) +{ +} + +bool ComparisonIdentifier::matches(const Expression::Ptr &e) const +{ + const Expression::ID eID = e->id(); + + if(eID == Expression::IDGeneralComparison) + { + if(m_hosts.contains(Expression::IDGeneralComparison)) + return e->as()->operatorID() == m_op; + else + return false; + } + else if(eID == Expression::IDValueComparison) + { + if(m_hosts.contains(Expression::IDValueComparison)) + return e->as()->operatorID() == m_op; + else + return false; + } + else + return false; +} + +BySequenceTypeIdentifier::BySequenceTypeIdentifier(const SequenceType::Ptr &seqType) : m_seqType(seqType) +{ + Q_ASSERT(seqType); +} + +bool BySequenceTypeIdentifier::matches(const Expression::Ptr &expr) const +{ + const SequenceType::Ptr t(expr->staticType()); + + return m_seqType->itemType()->xdtTypeMatches(t->itemType()) + && + m_seqType->cardinality().isMatch(t->cardinality()); +} + +IntegerIdentifier::IntegerIdentifier(const xsInteger num) : m_num(num) +{ +} + +bool IntegerIdentifier::matches(const Expression::Ptr &expr) const +{ + return expr->is(Expression::IDIntegerValue) && + expr->as()->item().as()->toInteger() == m_num; +} + +BooleanIdentifier::BooleanIdentifier(const bool value) : m_value(value) +{ +} + +bool BooleanIdentifier::matches(const Expression::Ptr &expr) const +{ + return expr->is(Expression::IDBooleanValue) && + expr->evaluateEBV(DynamicContext::Ptr()) == m_value; +} + +ByIDCreator::ByIDCreator(const Expression::ID id) : m_id(id) +{ + Q_ASSERT(id != Expression::IDIgnorableExpression); +} + +Expression::Ptr ByIDCreator::create(const Expression::List &operands, + const StaticContext::Ptr &context, + const SourceLocationReflection *const r) const +{ + return create(m_id, operands, context, r); +} + +Expression::Ptr ByIDCreator::create(const Expression::ID id, + const Expression::List &operands, + const StaticContext::Ptr &context, + const SourceLocationReflection *const r) +{ + Q_ASSERT(context); + + QXmlName::LocalNameCode fnName; + + switch(id) + { + case Expression::IDExistsFN: + { + fnName = StandardLocalNames::exists; + break; + } + case Expression::IDEmptyFN: + { + fnName = StandardLocalNames::empty; + break; + } + default: + { + Q_ASSERT_X(false, Q_FUNC_INFO, + "Cannot create an expression of requested type; m_id is wrong."); + return Expression::Ptr(); + } + } + + /* The reason we don't simply do 'new ExistsFN()' ourselves, is that all FunctionCall + * instances needs their FunctionSignature in order to function, and the FunctionFactories + * sets that. */ + const QXmlName qName(StandardNamespaces::fn, fnName); + + const Expression::Ptr result(context->functionSignatures()->createFunctionCall(qName, operands, context, r)); + context->wrapExpressionWith(r, result); + return result; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qoptimizerblocks_p.h b/src/xmlpatterns/expr/qoptimizerblocks_p.h new file mode 100644 index 0000000..575e07c --- /dev/null +++ b/src/xmlpatterns/expr/qoptimizerblocks_p.h @@ -0,0 +1,226 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_OptimizerBlocks_H +#define Patternist_OptimizerBlocks_H + +#include "qatomiccomparator_p.h" +#include "qexpression_p.h" +#include "qoptimizerframework_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Identifies Expression instances by their Expression::id(). + * + * @author Frans englich + * @ingroup Patternist_expressions + */ + class ByIDIdentifier : public ExpressionIdentifier + { + public: + ByIDIdentifier(const Expression::ID id); + virtual bool matches(const Expression::Ptr &expr) const; + private: + const Expression::ID m_id; + }; + + /** + * @short Identifies Expression instances based on their static type. + * + * BySequenceTypeIdentifier identifies Expression instances + * if their Expression::staticType() matches the requested one, + * regardless of whether the Expression is a particular one, such + * as AndExpression. + * + * For example, constructing a BySequenceTypeIdentifier while + * passing CommonSequenceTypes::EBV in its constructor will create + * a ExpressionIdentifier that returns @c true for a static type with + * item type xs:string, but returns @c false for a static type involving + * xs:date. + * + * @author Frans englich + * @ingroup Patternist_expressions + */ + class BySequenceTypeIdentifier : public ExpressionIdentifier + { + public: + BySequenceTypeIdentifier(const SequenceType::Ptr &seqType); + + /** + * @returns @c true, if the static type of @p expr is matches + * the SequenceType passed in the BySequenceTypeIdentifier() + * constructor, otherwise @c false. + */ + virtual bool matches(const Expression::Ptr &expr) const; + + private: + const SequenceType::Ptr m_seqType; + }; + + /** + * @short Determines whether an Expression is a value or general comparison or both, + * with a certain operator. + * + * @author Frans englich + * @ingroup Patternist_expressions + */ + class ComparisonIdentifier : public ExpressionIdentifier + { + public: + + /** + * @param comparatorHosts the possible parent that may have + * the operator. This may be Expression::IDGeneralComparison or + * Expression::IDValueComparison. The two values may also be OR'd, + * meaning any of them will do. + * + * @param op the operator that the comparator host must have. For example, + * if @p op is AtomicComparator::OperatorGreatorOrEqual this ComparisonIdentifier + * will match operator >= in the case of IDGeneralComparison and 'ge' in the + * case of IDValueComparison. + */ + ComparisonIdentifier(const QVector comparatorHosts, + const AtomicComparator::Operator op); + + /** + * @returns @c true, if @p expr is a ValueComparison with the operator + * passed in ComparisonIdentifier(). + */ + virtual bool matches(const Expression::Ptr &expr) const; + + private: + const QVector m_hosts; + const AtomicComparator::Operator m_op; + }; + + /** + * @short Matches numeric literals that are of type xs:integer and + * has a specific value. + * + * For example IntegerIdentifier(4) would match the former but + * not the latter operand in this expression: "4 + 5". + * + * @author Frans englich + * @ingroup Patternist_expressions + */ + class IntegerIdentifier : public ExpressionIdentifier + { + public: + IntegerIdentifier(const xsInteger num); + virtual bool matches(const Expression::Ptr &expr) const; + + private: + const xsInteger m_num; + }; + + /** + * @short Matches boolean literals. + * + * For example BooleanIdentifier(true) would match the former but + * not the latter operand in this expression: "true() + false()". + * + * @author Frans englich + * @ingroup Patternist_expressions + */ + class BooleanIdentifier : public ExpressionIdentifier + { + public: + BooleanIdentifier(const bool value); + virtual bool matches(const Expression::Ptr &expr) const; + + private: + const bool m_value; + }; + + /** + * @short Creates a particular Expression instance identified by an Expression::ID. + * + * For example, if ByIDCreator() is passed Expression::IDCountFN, create() + * will return CountFN instances. + * + * @author Frans englich + * @ingroup Patternist_expressions + */ + class ByIDCreator : public ExpressionCreator + { + public: + /** + * Creates a ByIDCreator that creates expressions + * of the type that @p id identifies. + */ + ByIDCreator(const Expression::ID id); + virtual Expression::Ptr create(const Expression::List &operands, + const StaticContext::Ptr &context, + const SourceLocationReflection *const r) const; + + /** + * Creates an expression by id @p id with the arguments @p operands. + */ + static Expression::Ptr create(const Expression::ID id, + const Expression::List &operands, + const StaticContext::Ptr &context, + const SourceLocationReflection *const r); + + private: + const Expression::ID m_id; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qoptimizerframework.cpp b/src/xmlpatterns/expr/qoptimizerframework.cpp new file mode 100644 index 0000000..c9e1991 --- /dev/null +++ b/src/xmlpatterns/expr/qoptimizerframework.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qoptimizerblocks_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +ExpressionIdentifier::~ExpressionIdentifier() +{ +} + +ExpressionCreator::~ExpressionCreator() +{ +} + +OptimizationPass::OptimizationPass(const ExpressionIdentifier::Ptr &startID, + const ExpressionIdentifier::List &opIDs, + const ExpressionMarker &sourceExpr, + const ExpressionCreator::Ptr &resultCtor, + const OperandsMatchMethod mMethod) : startIdentifier(startID), + operandIdentifiers(opIDs), + sourceExpression(sourceExpr), + resultCreator(resultCtor), + operandsMatchMethod(mMethod) +{ + Q_ASSERT_X(resultCtor || !sourceExpr.isEmpty(), Q_FUNC_INFO, + "Either resultCreator or sourceExpression must be set, otherwise there's " + "nothing to rewrite to."); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qoptimizerframework_p.h b/src/xmlpatterns/expr/qoptimizerframework_p.h new file mode 100644 index 0000000..a2c9373 --- /dev/null +++ b/src/xmlpatterns/expr/qoptimizerframework_p.h @@ -0,0 +1,294 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_OptimizerFramework_H +#define Patternist_OptimizerFramework_H + +#include + +#include "qexpression_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A factory for creating Expression instances. + * + * ExpressionIdentifier is one of the building block of Patternist's + * optimizer framework. An ExpressionIdentifier sub-class has + * the responsibility of creating the Expression that should be + * the result of the optimization. + * + * This class and sub-classes are never used on their own, + * but in cooperation with OptimizationPass. + * + * @author Frans englich + * @ingroup Patternist_expressions + */ + class ExpressionCreator : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer Ptr; + + /** + * For some reason this constructor cannot be synthesized. + */ + inline ExpressionCreator() + { + } + + virtual ~ExpressionCreator(); + /** + * Creates an expression that has @p operands as operands. + * + * The Expression that is returned is guaranteed, by the caller, + * to get a treatment identical to if the expression was created + * in an ordinary compilation(via the parser, and so forth). That is, + * Expression::typeCheck() and Expression::compress() stages will be + * carried out on the returned expression. + * + * @returns an Expression::Ptr that never is non @c null, valid pointer + */ + virtual Expression::Ptr create(const Expression::List &operands, + const StaticContext::Ptr &context, + const SourceLocationReflection *const) const = 0; + + private: + Q_DISABLE_COPY(ExpressionCreator) + }; + + /** + * @short Abstract base class for all classes that identify Expressions + * based on some criteria. + * + * ExpressionIdentifier is one of the building block of Patternist's + * optimizer framework. An ExpressionIdentifier sub-class has + * the responsibility of determining whether a particular Expression + * is the one an OptimizationPass should apply for. + * + * This class and sub-classes are never used on their own, + * but in cooperation with OptimizationPass. + * + * @author Frans englich + * @ingroup Patternist_expressions + */ + class ExpressionIdentifier : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer Ptr; + typedef QList List; + + /** + * For some reason this constructor cannot be synthesized. + */ + inline ExpressionIdentifier() + { + } + + virtual ~ExpressionIdentifier(); + /** + * @param expr the Expression to be tested. This is guranteed + * to always be a non @c null, valid pointer. + * + * @returns @c true if @p expr matches as according to this ExpressionIdentifier, + * otherwise @c false. + */ + virtual bool matches(const Expression::Ptr &expr) const = 0; + + private: + Q_DISABLE_COPY(ExpressionIdentifier) + }; + + /** + * @short Describes how a particular optimization pass should be carried out. + * + * OptimizationPass is essentially a declaration, which describes + * how an optimization pass in the form of an AST rewrite should be done, + * by describing what that should be rewritten into what how. + * + * Each OptimizationPass is applied to a "start" Expression. The Expression + * that qualifies as a start Expression for the OptimizationPass in question is + * determined by startIdentifier; if its ExpressionIdentifier::matches() function + * returns @c true, the optimizer continues to apply this OptimizationPass. + * + * After a start Expression has been found, it is verified if the operands matches + * as well by applying the ExpressionIdentifiers in operandIdentifiers to the + * start Expression's operands. Similarly, if the operands matches what + * operandIdentifiers requires, the optimizer continues to apply this OptimizationPass. + * + * At this stage, it has been concluded that the OptimizationPass validly applies, and + * what now remains is to carry out the actual rewrite. The Expression rewritten + * to is the one returned by ExpressionCreator::create(), when invoked via the resultCreator + * variable. + * + * How these components, startIdentifier, operandIdentifiers, sourceExpression, + * and resultCreator interacts with one another is described in more detail + * in the member documentation as well as the classes they are instances of. + * + * @author Frans englich + * @ingroup Patternist_expressions + */ + class OptimizationPass : public QSharedData + { + public: + typedef QExplicitlySharedDataPointer Ptr; + typedef QList List; + + enum OperandsMatchMethod + { + /** + * All operands must match in the same order the ExpressionMarkers do. + */ + Sequential = 1, + + /** + * Matches if all operands are matched, regardless of their order. This is + * useful when an OptimizationPass is matching an Expression that has two operands + * and that both of them can appear on the left or right hand as long as it is those + * two. + * + * This comparison method only works when two operands + * needs to be matched. + */ + AnyOrder + }; + + /** + * An ExpressionMarker identifies an operand Expression relatively + * the start Expression by that each integer identifies a step + * in a descending AST walk. For example an ExpressionMarker with + * only one entry that is 0(zero), identifies the first operand of the + * start Expression. An ExpressionMarker containing 1, 2 in that order + * identifies the third operand of the second operand of the start Expression. + */ + typedef QList ExpressionMarker; + + /** + * Creates an OptimizationPass and sets its public variables + * to the corresponding values passed in this constructor. + */ + OptimizationPass(const ExpressionIdentifier::Ptr &startID, + const ExpressionIdentifier::List &operandIDs, + const ExpressionMarker &sourceExpr, + const ExpressionCreator::Ptr &resultCtor = ExpressionCreator::Ptr(), + const OperandsMatchMethod matchMethod = Sequential); + + /** + * The ExpressionIdentifier that must the Expression this OptimizationPass concerns. + * + * If this variable is @c null, it means that the start Expression does + * not have to match any particular ExpressionIdentifier, but is fine as is. + * + * One might wonder what the purpose of this startIdentifier is, considering + * that what start Expression an OptimizationPass can at all apply to is + * naturally determined by what Expression::optimizationPasses() re-implementation that + * returns this OptimizationPass. The reason is that in some cases an OptimizationPass + * nevertheless doesn't apply. For example, optimizations applying to a ValueComparison + * might depend on what operator that is in use. + * + * May be @c null or point to an ExpressionIdentifier. + */ + const ExpressionIdentifier::Ptr startIdentifier; + + /** + * In order for an OptimizationPass to apply, the start Expression's + * operands must be matched with this list of ExpressionIdentifier instances. + * The first ExpressionIdentifier is applied to the first operand, the second + * ExpressionIdentifier to the second operand, and so forth until all operands + * have been iterated. + * + * Entries in this list may be @c null, and those signals that the corresponding + * operand is not constrained. For example, if the third ExpressionIdentifier in + * the list is @c null, it signals that the third operand may be anykind of expression. + * + * May be empty or contain an arbitrary amount of objects or @c null pointers. + */ + const ExpressionIdentifier::List operandIdentifiers; + + /** + * Identifies the expression that should be part of the new expression + * that this OptimizationPass rewrites to. If this list is empty, it + * means that the result is not derived from the existing tree, and + * that resultCreator will exclusively be used for creating the result + * Expression. + * + * How the ExpressionMarker identifies an Expression is document in + * its documentation. + * + * May be empty. + */ + const ExpressionMarker sourceExpression; + + /** + * This is the ExpressionCreator that will be used to create the + * Expression which is the result. ExpressionCreator::create() + * will be passed as operands the Expression that sourceExpression + * specify, if any. + * + * If this variable is @c null, the result Expression will be the one + * sourceExpression identifies. + */ + const ExpressionCreator::Ptr resultCreator; + + const OperandsMatchMethod operandsMatchMethod; + private: + Q_DISABLE_COPY(OptimizationPass) + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qorderby.cpp b/src/xmlpatterns/expr/qorderby.cpp new file mode 100644 index 0000000..b2fae5a --- /dev/null +++ b/src/xmlpatterns/expr/qorderby.cpp @@ -0,0 +1,261 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "qcommonsequencetypes_p.h" +#include "qnodebuilder_p.h" +#include "qschemanumeric_p.h" +#include "qpatternistlocale_p.h" +#include "qreturnorderby_p.h" +#include "qsorttuple_p.h" +#include "qsequencemappingiterator_p.h" + +#include "qorderby_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +OrderBy::OrderBy(const Stability stability, + const OrderSpec::Vector &aOrderSpecs, + const Expression::Ptr &op, + ReturnOrderBy *const returnOrderBy) : SingleContainer(op) + , m_stability(stability) + , m_orderSpecs(aOrderSpecs) + , m_returnOrderBy(returnOrderBy) +{ + Q_ASSERT(m_returnOrderBy); +} + +void OrderBy::OrderSpec::prepare(const Expression::Ptr &source, + const StaticContext::Ptr &context) +{ + m_expr = source; + const ItemType::Ptr t(source->staticType()->itemType()); + prepareComparison(fetchComparator(t, t, context)); +} + +/** + * @short Functor used by Qt's qSort() and qStableSort(). Used for FLWOR's + * order by expression. + * + * This must be in the global namespace, since it is specializing qLess(), which + * is in the global namespace. Hence it can't be in QPatternist. + */ +template<> +class qLess +{ +private: + + static inline bool isNaN(const Item &i) + { + return BuiltinTypes::xsDouble->xdtTypeMatches(i.type()) && + i.as()->isNaN(); + } + +public: + inline qLess(const OrderBy::OrderSpec::Vector &orderspecs, + const DynamicContext::Ptr &context) : m_orderSpecs(orderspecs) + , m_context(context) + { + Q_ASSERT(!m_orderSpecs.isEmpty()); + Q_ASSERT(context); + } + + inline bool operator()(const Item &item1, const Item &item2) const + { + const SortTuple *const s1 = item1.as(); + const SortTuple *const s2 = item2.as(); + + const Item::Vector &sortKeys1 = s1->sortKeys(); + const Item::Vector &sortKeys2 = s2->sortKeys(); + const int len = sortKeys1.count(); + Q_ASSERT(sortKeys1.count() == sortKeys2.count()); + + for(int i = 0; i < len; ++i) + { + const Item &i1 = sortKeys1.at(i); + const Item &i2 = sortKeys2.at(i); + const OrderBy::OrderSpec &orderSpec = m_orderSpecs.at(i); + + if(!i1) + { + if(i2 && !isNaN(i2)) + { + /* We got ((), item()). */ + return orderSpec.orderingEmptySequence == StaticContext::Least ? orderSpec.direction == OrderBy::OrderSpec::Ascending + : orderSpec.direction != OrderBy::OrderSpec::Ascending; + } + else + return false; + } + + if(!i2) + { + if(i1 && !isNaN(i1)) + /* We got (item(), ()). */ + return orderSpec.orderingEmptySequence == StaticContext::Greatest ? orderSpec.direction == OrderBy::OrderSpec::Ascending + : orderSpec.direction != OrderBy::OrderSpec::Ascending; + else + return false; + } + + Q_ASSERT(orderSpec.direction == OrderBy::OrderSpec::Ascending || + orderSpec.direction == OrderBy::OrderSpec::Descending); + const AtomicComparator::ComparisonResult result = orderSpec.detailedFlexibleCompare(i1, i2, m_context); + + switch(result) + { + case AtomicComparator::LessThan: + return orderSpec.direction == OrderBy::OrderSpec::Ascending; + case AtomicComparator::GreaterThan: + return orderSpec.direction != OrderBy::OrderSpec::Ascending; + case AtomicComparator::Equal: + continue; + case AtomicComparator::Incomparable: + Q_ASSERT_X(false, Q_FUNC_INFO, "This code path assume values are always comparable."); + } + } + + return false; + } + +private: + /* Yes, we store references here. */ + const OrderBy::OrderSpec::Vector & m_orderSpecs; + const DynamicContext::Ptr & m_context; +}; + +Item::Iterator::Ptr OrderBy::mapToSequence(const Item &i, + const DynamicContext::Ptr &) const +{ + return i.as()->value(); +} + +Item::Iterator::Ptr OrderBy::evaluateSequence(const DynamicContext::Ptr &context) const +{ + Item::List tuples(m_operand->evaluateSequence(context)->toList()); + + const qLess sorter(m_orderSpecs, context); + + Q_ASSERT(m_stability == StableOrder || m_stability == UnstableOrder); + + /* On one hand we could just disregard stability and always use qStableSort(), but maybe qSort() + * is a bit faster? */ + if(m_stability == StableOrder) + qStableSort(tuples.begin(), tuples.end(), sorter); + else + { + Q_ASSERT(m_stability == UnstableOrder); + qSort(tuples.begin(), tuples.end(), sorter); + } + + return makeSequenceMappingIterator(ConstPtr(this), + makeListIterator(tuples), + context); +} + +Expression::Ptr OrderBy::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + m_returnOrderBy->setStay(true); + + /* It's important we do the typeCheck() before calling OrderSpec::prepare(), since + * atomizers must first be inserted. */ + const Expression::Ptr me(SingleContainer::typeCheck(context, reqType)); + + const Expression::List ops(m_returnOrderBy->operands()); + const int len = ops.count(); + Q_ASSERT(ops.count() > 1); + Q_ASSERT(m_orderSpecs.count() == ops.count() - 1); + + for(int i = 1; i < len; ++i) + m_orderSpecs[i - 1].prepare(ops.at(i), context); + + return me; + + /* It's not meaningful to sort a single item or less, so rewrite ourselves + * away if that is the case. This is an optimization. */ + /* TODO: How do we remove ReturnOrderBy? + if(Cardinality::zeroOrOne().isMatch(m_operand->staticType()->cardinality())) + return m_operand->typeCheck(context, reqType); + else + return SingleContainer::typeCheck(context, reqType); + */ +} + +Expression::Properties OrderBy::properties() const +{ + return m_operand->properties() & DisableElimination; +} + +Expression::Ptr OrderBy::compress(const StaticContext::Ptr &context) +{ + /* If we only will produce one item, there's no point in sorting. */ + if(m_operand->staticType()->cardinality().allowsMany()) + return SingleContainer::compress(context); + else + { + m_returnOrderBy->setStay(false); + return m_operand->compress(context); + } +} + +SequenceType::Ptr OrderBy::staticType() const +{ + return m_operand->staticType(); +} + +SequenceType::List OrderBy::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ZeroOrMoreItems); + return result; +} + +ExpressionVisitorResult::Ptr +OrderBy::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qorderby_p.h b/src/xmlpatterns/expr/qorderby_p.h new file mode 100644 index 0000000..332702b --- /dev/null +++ b/src/xmlpatterns/expr/qorderby_p.h @@ -0,0 +1,183 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_OrderBy_H +#define Patternist_OrderBy_H + +#include "qatomiccomparator_p.h" +#include "qcomparisonplatform_p.h" +#include "qsinglecontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + class ReturnOrderBy; + + /** + * @short Performs the sorting by being a parent to ForClause. + * + * The child of the ForClause is a ReturnOrderBy expression, which collects + * the sort keys and values. + * + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class OrderBy : public SingleContainer + { + public: + enum Stability + { + StableOrder, + UnstableOrder + }; + + /** + * This class is value based. + */ + class OrderSpec : public ComparisonPlatform + { + public: + /** + * We want this guy to be public. + */ + using ComparisonPlatform::detailedFlexibleCompare; + + typedef QVector Vector; + + enum Direction + { + Ascending, + Descending + }; + + /** + * @short Default constructor, which is needed by QVector. + */ + inline OrderSpec() + { + } + + inline OrderSpec(const Direction dir, + const StaticContext::OrderingEmptySequence orderingEmpty) : direction(dir), + orderingEmptySequence(orderingEmpty) + { + } + + void prepare(const Expression::Ptr &source, + const StaticContext::Ptr &context); + + const SourceLocationReflection *actualReflection() const + { + return m_expr.data(); + } + + private: + Expression::Ptr m_expr; + + public: + /** + * We place these afterwards, such that m_expr gets aligned at the + * start of the address. + */ + Direction direction; + + StaticContext::OrderingEmptySequence orderingEmptySequence; + + inline AtomicComparator::Operator operatorID() const + { + return orderingEmptySequence == StaticContext::Least ? AtomicComparator::OperatorLessThanNaNLeast + : AtomicComparator::OperatorLessThanNaNGreatest; + } + + }; + + OrderBy(const Stability stability, + const OrderSpec::Vector &orderSpecs, + const Expression::Ptr &operand, + ReturnOrderBy *const returnOrderBy); + + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + virtual SequenceType::Ptr staticType() const; + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + virtual SequenceType::List expectedOperandTypes() const; + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + + inline Item::Iterator::Ptr mapToSequence(const Item &i, + const DynamicContext::Ptr &context) const; + virtual Properties properties() const; + + private: + /** + * Needed when calling makeSequenceMappingIterator(). + */ + typedef QExplicitlySharedDataPointer ConstPtr; + + const Stability m_stability; + OrderSpec::Vector m_orderSpecs; + ReturnOrderBy *const m_returnOrderBy; + }; + + /* TODO Q_DECLARE_TYPEINFO(OrderBy::OrderSpec, Q_MOVABLE_TYPE); Breaks, + * probably because it's nested. */ +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qorexpression.cpp b/src/xmlpatterns/expr/qorexpression.cpp new file mode 100644 index 0000000..c2bbe3c --- /dev/null +++ b/src/xmlpatterns/expr/qorexpression.cpp @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qboolean_p.h" +#include "qcommonvalues_p.h" +#include "qliteral_p.h" + +#include "qorexpression_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +OrExpression::OrExpression(const Expression::Ptr &operand1, + const Expression::Ptr &operand2) : AndExpression(operand1, operand2) +{ +} + +bool OrExpression::evaluateEBV(const DynamicContext::Ptr &context) const +{ + return m_operand1->evaluateEBV(context) || m_operand2->evaluateEBV(context); +} + +Expression::Ptr OrExpression::compress(const StaticContext::Ptr &context) +{ + const Expression::Ptr newMe(PairContainer::compress(context)); + + if(newMe != this) + return newMe; + + /* Both operands mustn't be evaluated in order to be able to compress. */ + if(m_operand1->isEvaluated() && m_operand1->evaluateEBV(context->dynamicContext())) + return wrapLiteral(CommonValues::BooleanTrue, context, this); + else if(m_operand2->isEvaluated() && m_operand2->evaluateEBV(context->dynamicContext())) + return wrapLiteral(CommonValues::BooleanTrue, context, this); + else + return Expression::Ptr(this); +} + +ExpressionVisitorResult::Ptr OrExpression::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qorexpression_p.h b/src/xmlpatterns/expr/qorexpression_p.h new file mode 100644 index 0000000..c86f654 --- /dev/null +++ b/src/xmlpatterns/expr/qorexpression_p.h @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_OrExpression_H +#define Patternist_OrExpression_H + +#include "qandexpression_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements XPath 2.0's logical expression @c or. + * + * @see XML Path Language + * (XPath) 2.0, 3.6 Logical Expressions + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class OrExpression : public AndExpression + { + public: + OrExpression(const Expression::Ptr &operand1, + const Expression::Ptr &operand2); + + virtual bool evaluateEBV(const DynamicContext::Ptr &context) const; + + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qpaircontainer.cpp b/src/xmlpatterns/expr/qpaircontainer.cpp new file mode 100644 index 0000000..7ca7b53 --- /dev/null +++ b/src/xmlpatterns/expr/qpaircontainer.cpp @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" + +#include "qpaircontainer_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +PairContainer::PairContainer(const Expression::Ptr &operand1, + const Expression::Ptr &operand2) : m_operand1(operand1), + m_operand2(operand2) +{ + Q_ASSERT(m_operand1); + Q_ASSERT(m_operand2); +} + +Expression::List PairContainer::operands() const +{ + Expression::List list; + list.append(m_operand1); + list.append(m_operand2); + return list; +} + +void PairContainer::setOperands(const Expression::List &ops) +{ + Q_ASSERT(ops.count() == 2); + m_operand1 = ops.first(); + m_operand2 = ops.last(); + Q_ASSERT(m_operand1); + Q_ASSERT(m_operand2); +} + +bool PairContainer::compressOperands(const StaticContext::Ptr &context) +{ + Q_ASSERT(m_operand1); + Q_ASSERT(m_operand2); + rewrite(m_operand1, m_operand1->compress(context), context); + rewrite(m_operand2, m_operand2->compress(context), context); + + return m_operand1->isEvaluated() && m_operand2->isEvaluated(); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qpaircontainer_p.h b/src/xmlpatterns/expr/qpaircontainer_p.h new file mode 100644 index 0000000..7acf7df --- /dev/null +++ b/src/xmlpatterns/expr/qpaircontainer_p.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_PairContainer_H +#define Patternist_PairContainer_H + +#include "qexpression_p.h" +#include "qatomictype_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Base class for expressions that has exactly two operands. + * + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class PairContainer : public Expression + { + public: + virtual Expression::List operands() const; + virtual void setOperands(const Expression::List &operands); + virtual bool compressOperands(const StaticContext::Ptr &); + + protected: + PairContainer(const Expression::Ptr &operand1, const Expression::Ptr &operand2); + + Expression::Ptr m_operand1; + Expression::Ptr m_operand2; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qparentnodeaxis.cpp b/src/xmlpatterns/expr/qparentnodeaxis.cpp new file mode 100644 index 0000000..b715782 --- /dev/null +++ b/src/xmlpatterns/expr/qparentnodeaxis.cpp @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" +#include "qcommonsequencetypes_p.h" + +#include "qparentnodeaxis_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Item ParentNodeAxis::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + return context->contextItem().asNode().iterate(QXmlNodeModelIndex::AxisParent)->next(); +} + +Expression::Properties ParentNodeAxis::properties() const +{ + return DisableElimination | RequiresContextItem; +} + +ExpressionVisitorResult::Ptr ParentNodeAxis::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +ItemType::Ptr ParentNodeAxis::expectedContextItemType() const +{ + return BuiltinTypes::node; +} + +SequenceType::Ptr ParentNodeAxis::staticType() const +{ + // Parentless node exists. + return CommonSequenceTypes::ZeroOrOneNode; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qparentnodeaxis_p.h b/src/xmlpatterns/expr/qparentnodeaxis_p.h new file mode 100644 index 0000000..ee5529f --- /dev/null +++ b/src/xmlpatterns/expr/qparentnodeaxis_p.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ParentNodeAxis_H +#define Patternist_ParentNodeAxis_H + +#include "qemptycontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Corresponds to the expression parent::node(). + * + * This AST node is now useless, due to refactorings. Prevously we had + * Item QAbstractXmlNodeModel::parent(), which didn't have the overhead of + * allocating an iterator for a single node. However, in order to stream + * line the API it is now gone and hence the node performs exactly the same + * as AxisStep. + * + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class ParentNodeAxis : public EmptyContainer + { + public: + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + + /** + * @returns always DisableElimination + */ + virtual Expression::Properties properties() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + + /** + * @returns always CommonSequenceTypes::ExactlyOneNode; + */ + virtual SequenceType::Ptr staticType() const; + + /** + * @returns always BuiltinTypes::node; + */ + virtual ItemType::Ptr expectedContextItemType() const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qpath.cpp b/src/xmlpatterns/expr/qpath.cpp new file mode 100644 index 0000000..73cf0d9 --- /dev/null +++ b/src/xmlpatterns/expr/qpath.cpp @@ -0,0 +1,271 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" +#include "qcommonsequencetypes_p.h" +#include "qgenericsequencetype_p.h" +#include "qnodesort_p.h" +#include "qpatternistlocale_p.h" +#include "qsequencemappingiterator_p.h" +#include "qtypechecker_p.h" + +#include "qpath_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +Path::Path(const Expression::Ptr &operand1, + const Expression::Ptr &operand2, + const Kind kind) : PairContainer(operand1, operand2) + , m_hasCreatedSorter(kind != RegularPath) + , m_isLast(false) + , m_checkXPTY0018(kind == RegularPath) + , m_kind(kind) +{ +} + +Item::Iterator::Ptr Path::mapToSequence(const Item &item, + const DynamicContext::Ptr &context) const +{ + /* item is the focus here. That is in /1, item is . However, + * we don't use it, since the context item is accessed through + * DynamicContext::focusIterator() and friends. */ + Q_ASSERT(item); + Q_UNUSED(item); /* Needed when compiling in release mode. */ + return m_operand2->evaluateSequence(context); +} + +Item::Iterator::Ptr Path::evaluateSequence(const DynamicContext::Ptr &context) const +{ + /* Note, we use the old context for m_operand1. */ + const Item::Iterator::Ptr source(m_operand1->evaluateSequence(context)); + + const DynamicContext::Ptr focus(context->createFocus()); + focus->setFocusIterator(source); + + const Item::Iterator::Ptr result(makeSequenceMappingIterator(ConstPtr(this), source, focus)); + + if(m_checkXPTY0018) + { + /* This is an expensive code path, but it should happen very rarely. */ + + enum FoundItem + { + FoundNone, + FoundNode, + FoundAtomicValue + } hasFound = FoundNone; + + Item::List whenChecked; + + Item next(result->next()); + + while(next) + { + const FoundItem found = next.isAtomicValue() ? FoundAtomicValue : FoundNode; + + if(hasFound != FoundNone && hasFound != found) + { + /* It's an atomic value and we've already found a node. Mixed content. */ + context->error(QtXmlPatterns::tr("The last step in a path must contain either nodes " + "or atomic values. It cannot be a mixture between the two."), + ReportContext::XPTY0018, this); + } + else + hasFound = found; + + whenChecked.append(next); + next = result->next(); + } + + return makeListIterator(whenChecked); + } + else + return result; +} + +Item Path::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + /* This function is called if both operands' cardinality is exactly-one. Therefore + * we manually go forward in the focus by calling next(). + * + * We don't check for XPTY0018, only in evaluateSequence(), since if we're guaranteed + * to evaluate to one item, we can only evaluate to one node or one atomic value. + */ + + /* Note, we use the old context for m_operand1. */ + const Item::Iterator::Ptr source(m_operand1->evaluateSequence(context)); + + const DynamicContext::Ptr focus(context->createFocus()); + focus->setFocusIterator(source); + + /* This test is needed because if the focus is empty, we don't want to(nor can't) evaluate + * the next step. */ + // TODO Why are we at all invoked then? + if(source->next()) + return m_operand2->evaluateSingleton(focus); + else + return Item(); +} + +void Path::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const +{ + /* Note, we use the old context for m_operand1. */ + const Item::Iterator::Ptr source(m_operand1->evaluateSequence(context)); + + const DynamicContext::Ptr focus(context->createFocus()); + focus->setFocusIterator(source); + + while(source->next()) + m_operand2->evaluateToSequenceReceiver(focus); +} + +Expression::Ptr Path::compress(const StaticContext::Ptr &context) +{ + const Expression::Ptr me(PairContainer::compress(context)); + + /* "./expr" is by now equal to "expr" since we've done + * focus/type checks, and a node sorter has been inserted. */ + if(m_operand1->is(IDContextItem)) + return m_operand2; + + /* We do this as late as we can, such that we pick up the most recent type + * from the operand. */ + if(m_isLast && m_kind != XSLTForEach && m_operand2->staticType()->itemType() == BuiltinTypes::item) + m_checkXPTY0018 = true; + + return me; +} + +Expression::Ptr Path::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + m_operand2->announceFocusType(newFocusType()); + + /* Here we apply the function conversion first, and with the error code + * that we want -- XPTY0019 instead of XPTY0004. Unfortunately + * PairContainer::typeCheck() will do the type check again, which is + * redundant in the case of when we're not XSLTForEach. + * + * If we're XSLTForEach, it means we're a synthetic "map" expression for + * implementing various XSL-T expressions, and hence don't have the + * constraint of XPTY0019. + * + * It's important that typeCheck() is run for the operands(of course), and the call to + * PairContainer::typeCheck() ensures that below, in the case that we're XSL-T code. + * + * The type we expect, CommonSequenceTypes::ZeroOrMoreNodes() needs to be in sync with + * what we return in expectedOperandTypes(). */ + if(m_kind != XSLTForEach) + { + m_operand1 = TypeChecker::applyFunctionConversion(m_operand1, + CommonSequenceTypes::ZeroOrMoreNodes, + context, + m_kind == ForApplyTemplate ? ReportContext::XTTE0520 + : ReportContext::XPTY0019); + } + + /* If our step ends with atomic values, we cannot sort. + * + * We must smack the NodeSortExpression ontop before calling typeCheck(), since the latter + * may insert an Atomizer, as possibly mandated by reqType. By doing it after, the Atomizer + * will be a parent to NodeSortExpression, as opposed to a child. + */ + if(!m_hasCreatedSorter) + { + m_hasCreatedSorter = true; + + return NodeSortExpression::wrapAround(Expression::Ptr(this), context)->typeCheck(context, reqType); + } + else + return PairContainer::typeCheck(context, reqType); +} + +SequenceType::List Path::expectedOperandTypes() const +{ + SequenceType::List result; + + /* This value needs to be in sync with what we pass to + * applyFunctionConversion() in typeCheck() above. + * + * We don't have the XPTY0019 restriction when we're synthetic XSL-T code. + */ + if(m_kind == XSLTForEach) + result.append(CommonSequenceTypes::ZeroOrMoreItems); + else + result.append(CommonSequenceTypes::ZeroOrMoreNodes); + + result.append(CommonSequenceTypes::ZeroOrMoreItems); + return result; +} + +SequenceType::Ptr Path::staticType() const +{ + const SequenceType::Ptr opType(m_operand2->staticType()); + + /* For each parent step, we evaluate the child step. So multiply the two + * cardinalities. */ + return makeGenericSequenceType(opType->itemType(), + m_operand1->staticType()->cardinality() * opType->cardinality()); +} + +ExpressionVisitorResult::Ptr Path::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +Expression::Properties Path::properties() const +{ + return CreatesFocusForLast | ((m_operand1->properties() | m_operand2->properties()) & (RequiresCurrentItem | DisableElimination)); +} + +ItemType::Ptr Path::newFocusType() const +{ + return m_operand1->staticType()->itemType(); +} + +Expression::ID Path::id() const +{ + return IDPath; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qpath_p.h b/src/xmlpatterns/expr/qpath_p.h new file mode 100644 index 0000000..e4dc365 --- /dev/null +++ b/src/xmlpatterns/expr/qpath_p.h @@ -0,0 +1,176 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_Path_H +#define Patternist_Path_H + +#include "qpaircontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Implements the path expression, containing two steps, such as in html/body. + * + * @see XQuery 1.0: An + * XML Query Language, 3.2 Path Expressions + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class Path : public PairContainer + { + public: + enum Kind + { + /** + * This Path is a plain old path expression as found in XPath. + * Sorting is performed, and atomics are disallowed as left + * operand. + */ + RegularPath = 1, + + /** + * This Path emulates an @c xsl:for-each instruction. This means no + * sorting of result, and atomics are allowed as left operand. + */ + XSLTForEach, + + /** + * This Path performs the iteration in an @c xsl:apply-templates + * instruction. This means sorting, and atomics are disallowed + * as left operand. + */ + ForApplyTemplate + }; + + Path(const Expression::Ptr &operand1, + const Expression::Ptr &operand2, + const Kind kind = RegularPath); + + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const; + inline Item::Iterator::Ptr mapToSequence(const Item &item, + const DynamicContext::Ptr &context) const; + + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + + virtual SequenceType::List expectedOperandTypes() const; + + /** + * @returns the static type of the last step where the cardinality is multiplied with + * the cardinality of the first step's cardinality. + */ + virtual SequenceType::Ptr staticType() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + + virtual Properties properties() const; + + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + + /** + * @returns the item type of the last step's static type. + */ + virtual ItemType::Ptr newFocusType() const; + + virtual ID id() const; + + inline void setLast(); + + inline Kind kind() const + { + return m_kind; + } + + private: + typedef QExplicitlySharedDataPointer ConstPtr; + + /** + * One might think this block exists for preventing multiple + * NodeSortExpressions to be created. However, that is not an issue, + * since NodeSortExpression optimizes this away anyway. + * + * The real reason is to avoid infinite recursion. When our typeCheck() + * forwards on the type check to the just created + * NodeSortExpression, it in turn calls typeCheck() on its child, which + * is this Path. Rince and repeat. + * + * We only create node sorts when we're a regular path expression, and + * not when standing in as a generic map expression. */ + bool m_hasCreatedSorter; + + /** + * Whether this path is the step. For instance, in a/b/c, the + * last path has @c c as the right operand. + */ + bool m_isLast; + + bool m_checkXPTY0018; + const Kind m_kind; + }; + + void Path::setLast() + { + m_isLast = true; + } +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qpositionalvariablereference.cpp b/src/xmlpatterns/expr/qpositionalvariablereference.cpp new file mode 100644 index 0000000..0b4f69b --- /dev/null +++ b/src/xmlpatterns/expr/qpositionalvariablereference.cpp @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonsequencetypes_p.h" +#include "qinteger_p.h" + +#include "qpositionalvariablereference_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +PositionalVariableReference::PositionalVariableReference(const VariableSlotID s) : VariableReference(s) +{ +} + +Item PositionalVariableReference::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + Q_ASSERT(context); + Q_ASSERT(context->positionIterator(slot())); + return Integer::fromValue(context->positionIterator(slot())->position()); +} + +bool PositionalVariableReference::evaluateEBV(const DynamicContext::Ptr &) const +{ + return true; +} + +SequenceType::Ptr PositionalVariableReference::staticType() const +{ + return CommonSequenceTypes::ExactlyOneInteger; +} + +Expression::Properties PositionalVariableReference::properties() const +{ + return DependsOnLocalVariable; +} + +ExpressionVisitorResult::Ptr + +PositionalVariableReference::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qpositionalvariablereference_p.h b/src/xmlpatterns/expr/qpositionalvariablereference_p.h new file mode 100644 index 0000000..9fe3cbd --- /dev/null +++ b/src/xmlpatterns/expr/qpositionalvariablereference_p.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_PositionVariableReference_H +#define Patternist_PositionVariableReference_H + +#include "qvariablereference_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A reference to an @c at variable, declared with the + * for-part in XQuery's FLWOR expression. + * + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class PositionalVariableReference : public VariableReference + { + public: + typedef QExplicitlySharedDataPointer Ptr; + PositionalVariableReference(const VariableSlotID slot); + + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + + /** + * Returns always @c true, since a positional variable is always one or more, and the + * Effective %Boolean Value for that range is always @c true. + * + * @returns always @c true + */ + virtual bool evaluateEBV(const DynamicContext::Ptr &context) const; + + /** + * @returns always CommonSequenceTypes::ExactlyOneInteger + */ + virtual SequenceType::Ptr staticType() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + virtual Properties properties() const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qprocessinginstructionconstructor.cpp b/src/xmlpatterns/expr/qprocessinginstructionconstructor.cpp new file mode 100644 index 0000000..d933ee0 --- /dev/null +++ b/src/xmlpatterns/expr/qprocessinginstructionconstructor.cpp @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonsequencetypes_p.h" +#include "qpatternistlocale_p.h" +#include "qnodebuilder_p.h" +#include "qqnamevalue_p.h" + +#include "qprocessinginstructionconstructor_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +ProcessingInstructionConstructor:: +ProcessingInstructionConstructor(const Expression::Ptr &op1, + const Expression::Ptr &op2) : PairContainer(op1, op2) +{ +} + +QString ProcessingInstructionConstructor::leftTrimmed(const QString &input) +{ + const int len = input.length(); + + for(int i = 0; i < len; ++i) + { + if(!input.at(i).isSpace()) + return input.mid(i); + } + + return QString(); /* input consists only of whitespace. All was trimmed. */ +} + +QString ProcessingInstructionConstructor::data(const DynamicContext::Ptr &context) const +{ + const Item name(m_operand1->evaluateSingleton(context)); + const Item dataArg(m_operand2->evaluateSingleton(context)); + + if(dataArg) + { + /* Perform trimming before validation, to increase speed. */ + const QString value(leftTrimmed(dataArg.stringValue())); + + if(value.contains(QLatin1String("?>"))) + { + context->error(QtXmlPatterns::tr("The data of a processing instruction cannot contain the string %1").arg(formatData("?>")), + ReportContext::XQDY0026, this); + return QString(); + } + else + return value; + } + else + return QString(); +} + +QXmlName ProcessingInstructionConstructor::evaluateTardata(const DynamicContext::Ptr &context) const +{ + const Item name(m_operand1->evaluateSingleton(context)); + return context->namePool()->allocateQName(QString(), name.stringValue()); +} + +Item ProcessingInstructionConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const NodeBuilder::Ptr nodeBuilder(context->nodeBuilder(QUrl())); + + nodeBuilder->processingInstruction(evaluateTardata(context), data(context)); + + const QAbstractXmlNodeModel::Ptr nm(nodeBuilder->builtDocument()); + context->addNodeModel(nm); + + return nm->root(QXmlNodeModelIndex()); +} + +void ProcessingInstructionConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const +{ + QAbstractXmlReceiver *const receiver = context->outputReceiver(); + + receiver->processingInstruction(evaluateTardata(context), data(context)); +} + +SequenceType::Ptr ProcessingInstructionConstructor::staticType() const +{ + return CommonSequenceTypes::ExactlyOneProcessingInstruction; +} + +SequenceType::List ProcessingInstructionConstructor::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ExactlyOneString); + result.append(CommonSequenceTypes::ZeroOrOneString); + return result; +} + +Expression::Properties ProcessingInstructionConstructor::properties() const +{ + return DisableElimination | IsNodeConstructor; +} + +ExpressionVisitorResult::Ptr +ProcessingInstructionConstructor::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qprocessinginstructionconstructor_p.h b/src/xmlpatterns/expr/qprocessinginstructionconstructor_p.h new file mode 100644 index 0000000..950ebc8 --- /dev/null +++ b/src/xmlpatterns/expr/qprocessinginstructionconstructor_p.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ProcessingInstructionConstructor_H +#define Patternist_ProcessingInstructionConstructor_H + +#include "qpaircontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Constructs an element node. This covers both computed and directly constructed + * element nodes. + * + * @see XQuery + * 1.0: An XML Query Language, 3.7 Constructors + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class ProcessingInstructionConstructor : public PairContainer + { + public: + ProcessingInstructionConstructor(const Expression::Ptr &operand1, + const Expression::Ptr &operand2); + + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const; + + virtual SequenceType::Ptr staticType() const; + + /** + * Both arguments must of type @c xs:string. It is assumes that the first argument's + * lexical space is @c xs:NCName. + */ + virtual SequenceType::List expectedOperandTypes() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + + virtual Properties properties() const; + private: + inline QXmlName evaluateTardata(const DynamicContext::Ptr &context) const; + /** + * Performs left-trimming only. + * + * @see QString::trimmed() + */ + static inline QString leftTrimmed(const QString &input); + + QString data(const DynamicContext::Ptr &context) const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qqnameconstructor.cpp b/src/xmlpatterns/expr/qqnameconstructor.cpp new file mode 100644 index 0000000..7925e2b --- /dev/null +++ b/src/xmlpatterns/expr/qqnameconstructor.cpp @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonsequencetypes_p.h" +#include "qpatternistlocale_p.h" +#include "qqnamevalue_p.h" + +#include "qqnameconstructor_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +QNameConstructor::QNameConstructor(const Expression::Ptr &source, + const NamespaceResolver::Ptr &nsResolver) : SingleContainer(source), + m_nsResolver(nsResolver) +{ + Q_ASSERT(m_nsResolver); +} + +Item QNameConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + Q_ASSERT(context); + const QString lexQName(m_operand->evaluateSingleton(context).stringValue()); + + const QXmlName expQName(expandQName(lexQName, + context, + m_nsResolver, + this)); + return toItem(QNameValue::fromValue(context->namePool(), expQName)); +} + +QXmlName::NamespaceCode QNameConstructor::namespaceForPrefix(const QXmlName::PrefixCode prefix, + const StaticContext::Ptr &context, + const SourceLocationReflection *const r) +{ + Q_ASSERT(context); + const QXmlName::NamespaceCode ns(context->namespaceBindings()->lookupNamespaceURI(prefix)); + + if(ns == NamespaceResolver::NoBinding) + { + context->error(QtXmlPatterns::tr("No namespace binding exists for the prefix %1") + .arg(formatKeyword(context->namePool()->stringForPrefix(prefix))), + ReportContext::XPST0081, + r); + return NamespaceResolver::NoBinding; + } + else + return ns; +} + +SequenceType::Ptr QNameConstructor::staticType() const +{ + return CommonSequenceTypes::ExactlyOneQName; +} + +SequenceType::List QNameConstructor::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ExactlyOneString); + return result; +} + +ExpressionVisitorResult::Ptr QNameConstructor::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +const SourceLocationReflection *QNameConstructor::actualReflection() const +{ + return m_operand.data(); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qqnameconstructor_p.h b/src/xmlpatterns/expr/qqnameconstructor_p.h new file mode 100644 index 0000000..4011870 --- /dev/null +++ b/src/xmlpatterns/expr/qqnameconstructor_p.h @@ -0,0 +1,182 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_QNameConstructor_H +#define Patternist_QNameConstructor_H + +#include "qsinglecontainer_p.h" +#include "qbuiltintypes_p.h" +#include "qpatternistlocale_p.h" +#include "qxpathhelper_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Creates an @c xs:QName value from a lexical QName using + * statically known namespace bindings. + * + * @see QQNameValue + * @see QXmlUtils + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class QNameConstructor : public SingleContainer + { + public: + + QNameConstructor(const Expression::Ptr &source, + const NamespaceResolver::Ptr &nsResolver); + + virtual Item evaluateSingleton(const DynamicContext::Ptr &) const; + + virtual SequenceType::List expectedOperandTypes() const; + + virtual SequenceType::Ptr staticType() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + + /** + * Expands @p lexicalQName, which is a lexical representation of a QName such as "x:body", into + * a QName using @p nsResolver to supply the namespace bindings. + * + * If @p lexicalQName is lexically invalid @p InvalidQName is raised via @p context, or if + * no namespace binding does not exists for a prefix(if any) in @p lexicalQName, @p NoBinding + * is raised via @p context. + * + * If @p asForAttribute is @c true, the name is considered to be for an + * attribute in some way, and @p lexicalQName will not pick up the + * default namespace if it doesn't have a prefix. + * + * @p nsResolver is parameterized meaning the function can be instantiated with either + * DynamicContext or StaticContext. + * + * @see QQNameValue + * @see QXmlUtils + */ + template + static + QXmlName expandQName(const QString &lexicalQName, + const TReportContext &context, + const NamespaceResolver::Ptr &nsResolver, + const SourceLocationReflection *const r, + const bool asForAttribute = false); + + /** + * Resolves the namespace prefix @p prefix to its namespace if it exists, or + * raised ReportContext::XPST0081 otherwise. + * + * @returns the namespace URI corresponding to @p prefix + */ + static QXmlName::NamespaceCode namespaceForPrefix(const QXmlName::PrefixCode prefix, + const StaticContext::Ptr &context, + const SourceLocationReflection *const r); + + virtual const SourceLocationReflection *actualReflection() const; + + private: + const NamespaceResolver::Ptr m_nsResolver; + }; + + template + QXmlName QNameConstructor::expandQName(const QString &lexicalQName, + const TReportContext &context, + const NamespaceResolver::Ptr &nsResolver, + const SourceLocationReflection *const r, + const bool asForAttribute) + { + Q_ASSERT(nsResolver); + Q_ASSERT(context); + + if(XPathHelper::isQName(lexicalQName)) + { + QString prefix; + QString local; + XPathHelper::splitQName(lexicalQName, prefix, local); + const QXmlName::NamespaceCode nsCode = asForAttribute && prefix.isEmpty() ? QXmlName::NamespaceCode(StandardNamespaces::empty) + : (nsResolver->lookupNamespaceURI(context->namePool()->allocatePrefix(prefix))); + + if(nsCode == NamespaceResolver::NoBinding) + { + context->error(QtXmlPatterns::tr("No namespace binding exists for " + "the prefix %1 in %2").arg(formatKeyword(prefix), + formatKeyword(lexicalQName)), + NoBinding, + r); + return QXmlName(); /* Silence compiler warning. */ + } + else + return context->namePool()->allocateQName(context->namePool()->stringForNamespace(nsCode), local, prefix); + } + else + { + context->error(QtXmlPatterns::tr("%1 is an invalid %2") + .arg(formatData(lexicalQName)) + .arg(formatType(context->namePool(), BuiltinTypes::xsQName)), + InvalidQName, + r); + return QXmlName(); /* Silence compiler warning. */ + } + } +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qquantifiedexpression.cpp b/src/xmlpatterns/expr/qquantifiedexpression.cpp new file mode 100644 index 0000000..a6c4d03 --- /dev/null +++ b/src/xmlpatterns/expr/qquantifiedexpression.cpp @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonsequencetypes_p.h" +#include "qgenericsequencetype_p.h" +#include "qitemmappingiterator_p.h" + +#include "qquantifiedexpression_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +QuantifiedExpression::QuantifiedExpression(const VariableSlotID varSlot, + const Operator quantifier, + const Expression::Ptr &inClause, + const Expression::Ptr &testExpression) + : PairContainer(inClause, testExpression), + m_varSlot(varSlot), + m_quantifier(quantifier) +{ + Q_ASSERT(quantifier == Some || quantifier == Every); +} + +Item QuantifiedExpression::mapToItem(const Item &item, + const DynamicContext::Ptr &context) const +{ + context->setRangeVariable(m_varSlot, item); + return item; +} + +bool QuantifiedExpression::evaluateEBV(const DynamicContext::Ptr &context) const +{ + const Item::Iterator::Ptr it(makeItemMappingIterator(ConstPtr(this), + m_operand1->evaluateSequence(context), + context)); + + Item item(it->next()); + + if(m_quantifier == Some) + { + while(item) + { + if(m_operand2->evaluateEBV(context)) + return true; + else + item = it->next(); + }; + + return false; + } + else + { + Q_ASSERT(m_quantifier == Every); + + while(item) + { + if(m_operand2->evaluateEBV(context)) + item = it->next(); + else + return false; + } + + return true; + } +} + +QString QuantifiedExpression::displayName(const Operator quantifier) +{ + if(quantifier == Some) + return QLatin1String("some"); + else + { + Q_ASSERT(quantifier == Every); + return QLatin1String("every"); + } +} + +SequenceType::Ptr QuantifiedExpression::staticType() const +{ + return CommonSequenceTypes::ExactlyOneBoolean; +} + +SequenceType::List QuantifiedExpression::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ZeroOrMoreItems); + result.append(CommonSequenceTypes::EBV); + return result; +} + +QuantifiedExpression::Operator QuantifiedExpression::operatorID() const +{ + return m_quantifier; +} + +ExpressionVisitorResult::Ptr QuantifiedExpression::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qquantifiedexpression_p.h b/src/xmlpatterns/expr/qquantifiedexpression_p.h new file mode 100644 index 0000000..0c65782 --- /dev/null +++ b/src/xmlpatterns/expr/qquantifiedexpression_p.h @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_QuantifiedExpression_H +#define Patternist_QuantifiedExpression_H + +#include "qpaircontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Implements XPath 2.0's quantification expressions @c some and @c every. + * + * @see XML Path Language + * (XPath) 2.0, 3.9 Quantified Expressions + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class Q_AUTOTEST_EXPORT QuantifiedExpression : public PairContainer + { + public: + enum Operator + { + Some = 1, + Every + }; + + QuantifiedExpression(const VariableSlotID varSlot, + const Operator quantifier, + const Expression::Ptr &inClause, + const Expression::Ptr &testExpression); + + virtual bool evaluateEBV(const DynamicContext::Ptr &context) const; + virtual SequenceType::Ptr staticType() const; + virtual SequenceType::List expectedOperandTypes() const; + + Operator operatorID() const; + + /** + * Determines the string representation for a quantification operator. + * + * @return "some" if @p quantifier is Some, or "every" if @p quantifier + * is Every + */ + static QString displayName(const Operator quantifier); + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + + inline Item mapToItem(const Item &item, const DynamicContext::Ptr &context) const; + + private: + typedef QExplicitlySharedDataPointer ConstPtr; + const VariableSlotID m_varSlot; + const Operator m_quantifier; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qrangeexpression.cpp b/src/xmlpatterns/expr/qrangeexpression.cpp new file mode 100644 index 0000000..b4d7e91 --- /dev/null +++ b/src/xmlpatterns/expr/qrangeexpression.cpp @@ -0,0 +1,170 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qbuiltintypes_p.h" +#include "qcommonsequencetypes_p.h" +#include "qcommonvalues_p.h" +#include "qgenericsequencetype_p.h" +#include "qinteger_p.h" +#include "qliteral_p.h" +#include "qrangeiterator_p.h" + +#include "qrangeexpression_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +RangeExpression::RangeExpression(const Expression::Ptr &operand1, + const Expression::Ptr &operand2) : PairContainer(operand1, operand2) +{ +} + +Item::Iterator::Ptr RangeExpression::evaluateSequence(const DynamicContext::Ptr &context) const +{ + const Item s(m_operand1->evaluateSingleton(context)); + + if(!s) + return CommonValues::emptyIterator; + + const Item e(m_operand2->evaluateSingleton(context)); + if(!e) + return CommonValues::emptyIterator; + + const xsInteger start = s.as()->toInteger(); + const xsInteger end = e.as()->toInteger(); + + if(start > end) + return CommonValues::emptyIterator; + else if(start == end) + return makeSingletonIterator(s); + else + return Item::Iterator::Ptr(new RangeIterator(start, RangeIterator::Forward, end)); +} + +Item RangeExpression::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + return m_operand1->evaluateSingleton(context); +} + +SequenceType::List RangeExpression::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ZeroOrOneInteger); + result.append(CommonSequenceTypes::ZeroOrOneInteger); + return result; +} + +SequenceType::Ptr RangeExpression::staticType() const +{ + /* This logic makes the Cardinality more specific. */ + Cardinality::Count from; + bool hasFrom; + + if(m_operand1->is(IDIntegerValue)) + { + from = m_operand1->as()->item().as()->toInteger(); + hasFrom = true; + } + else + { + hasFrom = false; + from = 0; + } + + /* We can't check whether to is -1 since maybe the user wrote -1. Hence + * hasTo is required. */ + bool hasTo; + Cardinality::Count to; + + if(m_operand2->is(IDIntegerValue)) + { + const xsInteger asInt = m_operand2->as()->item().as()->toInteger(); + to = asInt; + + if(to == asInt) + hasTo = true; + else + { + /* Cardinality::Count is not the same as type xsInteger. We had overflow. */ + to = -1; + hasTo = false; + } + } + else + { + to = -1; + hasTo = false; + } + + if(hasTo && hasFrom) + { + if(from > to) + { + /* The query is incorrectly written, we'll evaluate to the empty sequence. + * Just return what's correct. */ + return CommonSequenceTypes::ZeroOrMoreIntegers; + } + else + { + Cardinality::Count count = (to - from) + 1; /* + 1, since it's inclusive. */ + return makeGenericSequenceType(BuiltinTypes::xsInteger, Cardinality::fromExact(count)); + } + } + else + { + /* We can't do fromExact(from, -1) since the latter can evaluate to a value that actually is + * lower than from, although that unfortunately is very unlikely. */ + return CommonSequenceTypes::ZeroOrMoreIntegers; + } +} + +Expression::Properties RangeExpression::properties() const +{ + return Expression::DisableElimination; +} + +ExpressionVisitorResult::Ptr RangeExpression::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qrangeexpression_p.h b/src/xmlpatterns/expr/qrangeexpression_p.h new file mode 100644 index 0000000..94756d7 --- /dev/null +++ b/src/xmlpatterns/expr/qrangeexpression_p.h @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_RangeExpression_H +#define Patternist_RangeExpression_H + +#include "qpaircontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Implements XPath 2.0's @c to expression. + * + * Despite its name, RangeExpression is not related to RangeVariableDeclaration. + * + * @see XML Path Language + * (XPath) 2.0, 3.3.1 Constructing Sequences + * @see RangeIterator + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class RangeExpression : public PairContainer + { + public: + RangeExpression(const Expression::Ptr &operand1, const Expression::Ptr &operand2); + + virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &) const; + /** + * It's likely that this function gets called if staticType() inferred + * the cardinality to an exact number. In that case, we know that the + * first arguments is the same as the second argument. + */ + virtual Item evaluateSingleton(const DynamicContext::Ptr &) const; + + virtual SequenceType::List expectedOperandTypes() const; + + /** + * @returns always CommonSequenceTypes::ZeroOrMoreIntegers + */ + virtual SequenceType::Ptr staticType() const; + + /** + * Disables compression for optimization reasons. For example, the + * expression "1 to 1000" would consume thousand allocated instances + * of Integer, and RangeIterator is well suited for dynamic evaluation. + * + * @returns Expression::DisableElimination + */ + virtual Expression::Properties properties() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qrangevariablereference.cpp b/src/xmlpatterns/expr/qrangevariablereference.cpp new file mode 100644 index 0000000..e4d6c7e --- /dev/null +++ b/src/xmlpatterns/expr/qrangevariablereference.cpp @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qboolean_p.h" +#include "qgenericsequencetype_p.h" + +#include "qrangevariablereference_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +RangeVariableReference::RangeVariableReference(const Expression::Ptr &source, + const VariableSlotID slotP) : VariableReference(slotP), + m_sourceExpression(source) +{ + Q_ASSERT(source); +} + +bool RangeVariableReference::evaluateEBV(const DynamicContext::Ptr &context) const +{ + Q_ASSERT_X(context->rangeVariable(slot()), Q_FUNC_INFO, "The range variable must be set."); + return Boolean::evaluateEBV(context->rangeVariable(slot()), context); +} + +Item RangeVariableReference::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + Q_ASSERT_X(context->rangeVariable(slot()), Q_FUNC_INFO, "The range variable must be set."); + return context->rangeVariable(slot()); +} + +SequenceType::Ptr RangeVariableReference::staticType() const +{ + return makeGenericSequenceType(m_sourceExpression->staticType()->itemType(), + Cardinality::exactlyOne()); +} + +Expression::ID RangeVariableReference::id() const +{ + return IDRangeVariableReference; +} + +ExpressionVisitorResult::Ptr +RangeVariableReference::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +Expression::Properties RangeVariableReference::properties() const +{ + return DependsOnLocalVariable; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qrangevariablereference_p.h b/src/xmlpatterns/expr/qrangevariablereference_p.h new file mode 100644 index 0000000..1246937 --- /dev/null +++ b/src/xmlpatterns/expr/qrangevariablereference_p.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_RangeVariableReference_H +#define Patternist_RangeVariableReference_H + +#include "qvariablereference_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A reference to a variable declared with @c for or a quantification + * expression, but not for instance a @c let binding. + * + * A range variable always represents a single item, while an other + * expression provides the binding and iteration. A @c for expression is + * a good example. + * + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class RangeVariableReference : public VariableReference + { + public: + RangeVariableReference(const Expression::Ptr &sourceExpression, + const VariableSlotID slot); + + virtual bool evaluateEBV(const DynamicContext::Ptr &context) const; + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + virtual SequenceType::Ptr staticType() const; + + /** + * @returns IDRangeVariableReference + */ + virtual ID id() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + virtual Properties properties() const; + private: + const Expression::Ptr m_sourceExpression; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qreturnorderby.cpp b/src/xmlpatterns/expr/qreturnorderby.cpp new file mode 100644 index 0000000..c530971 --- /dev/null +++ b/src/xmlpatterns/expr/qreturnorderby.cpp @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonsequencetypes_p.h" +#include "qexpressionsequence_p.h" +#include "qsorttuple_p.h" + +#include "qreturnorderby_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +ReturnOrderBy::ReturnOrderBy(const OrderBy::Stability aStability, + const OrderBy::OrderSpec::Vector &oSpecs, + const Expression::List &ops) : UnlimitedContainer(ops) + , m_stability(aStability) + , m_orderSpecs(oSpecs) + , m_flyAway(true) +{ + Q_ASSERT_X(m_operands.size() >= 2, Q_FUNC_INFO, + "ReturnOrderBy must have the return expression, and at least one sort key."); + Q_ASSERT(m_orderSpecs.size() == ops.size() - 1); +} + +Item ReturnOrderBy::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + Q_ASSERT(m_operands.size() > 1); + const Item::Iterator::Ptr value(makeListIterator(m_operands.first()->evaluateSequence(context)->toList())); + Item::Vector sortKeys; + + /* We're skipping the first operand. */ + const int len = m_operands.size() - 1; + sortKeys.resize(len); + + for(int i = 1; i <= len; ++i) + sortKeys[i - 1] = m_operands.at(i)->evaluateSingleton(context); + + return Item(new SortTuple(value, sortKeys)); +} + +bool ReturnOrderBy::evaluateEBV(const DynamicContext::Ptr &context) const +{ + // TODO This is temporary code. + return m_operands.first()->evaluateEBV(context); +} + +Expression::Ptr ReturnOrderBy::compress(const StaticContext::Ptr &context) +{ + /* We first did this in typeCheck(), but that broke due to that type checks were + * missed, which other pieces relied on. */ + if(m_flyAway) + { + /* We only want the return expression, not the sort keys. */ + return m_operands.first()->compress(context); + } + else + { + /* We don't need the members, so don't keep a reference to them. */ + m_orderSpecs.clear(); + + return UnlimitedContainer::compress(context); + } +} + +Expression::Properties ReturnOrderBy::properties() const +{ + /* For some unknown reason this is necessary for XQTS test case orderBy18. */ + return DisableElimination; +} + +ExpressionVisitorResult::Ptr ReturnOrderBy::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +SequenceType::Ptr ReturnOrderBy::staticType() const +{ + return m_operands.first()->staticType(); +} + +SequenceType::List ReturnOrderBy::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ZeroOrMoreItems); + result.append(CommonSequenceTypes::ZeroOrOneAtomicType); + return result; +} + +Expression::ID ReturnOrderBy::id() const +{ + return IDReturnOrderBy; +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qreturnorderby_p.h b/src/xmlpatterns/expr/qreturnorderby_p.h new file mode 100644 index 0000000..6a51717 --- /dev/null +++ b/src/xmlpatterns/expr/qreturnorderby_p.h @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_ReturnOrderBy_H +#define Patternist_ReturnOrderBy_H + +#include "qorderby_p.h" +#include "qunlimitedcontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Together with OrderBy, it implements XQuery 1.0's order by expression. + * + * ReturnOrderBy evaluates the sort keys and values, and hands it over to + * OrderBy, which is an AST ancestor, using SortTuples. + * + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class ReturnOrderBy : public UnlimitedContainer + { + public: + /** + * In @p operands the first item is the return expression, and the + * rest, which is at least one, are the sort keys. + */ + ReturnOrderBy(const OrderBy::Stability stability, + const OrderBy::OrderSpec::Vector &oSpecs, + const Expression::List &operands); + + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + virtual bool evaluateEBV(const DynamicContext::Ptr &context) const; + virtual SequenceType::Ptr staticType() const; + virtual SequenceType::List expectedOperandTypes() const; + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + virtual ID id() const; + + inline OrderBy::OrderSpec::Vector orderSpecs() const + { + return m_orderSpecs; + } + + inline OrderBy::Stability stability() const + { + return m_stability; + } + + /** + * In the case of that we don't have a for-expression beloning us, but + * only a let clause, this ReturnOrderBy breaks if it stays in the AST. + * So, by default we assume that we should write ourselves away, unless + * this function is called. The associated ForClause will call it + * during typeCheck(), if it exists. + */ + inline void setStay(const bool a) + { + m_flyAway = !a; + } + + virtual Properties properties() const; + private: + /** + * This variable is unfortunately only used at compile time. However, + * it's tricky to get rid of it due to how QueryTransformParser would + * have to be adapted. + */ + const OrderBy::Stability m_stability; + + OrderBy::OrderSpec::Vector m_orderSpecs; + + /** + * @see stay() + */ + bool m_flyAway; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qsimplecontentconstructor.cpp b/src/xmlpatterns/expr/qsimplecontentconstructor.cpp new file mode 100644 index 0000000..e98d988 --- /dev/null +++ b/src/xmlpatterns/expr/qsimplecontentconstructor.cpp @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonsequencetypes_p.h" +#include "qatomicstring_p.h" + +#include "qsimplecontentconstructor_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +SimpleContentConstructor::SimpleContentConstructor(const Expression::Ptr &operand) : SingleContainer(operand) +{ +} + +Item SimpleContentConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const +{ + const Item::Iterator::Ptr it(m_operand->evaluateSequence(context)); + Item next(it->next()); + QString result; + + if(next) + { + result = next.stringValue(); + next = it->next(); + } + else + return Item(); + + while(next) + { + result += QLatin1Char(' '); + result += next.stringValue(); + next = it->next(); + } + + return AtomicString::fromValue(result); +} + +Expression::Ptr SimpleContentConstructor::compress(const StaticContext::Ptr &context) +{ + const Expression::Ptr me(SingleContainer::compress(context)); + + if(me.data() == this) + { + /* Optimization: if we will evaluate to a single string, we're not + * necessary. */ + if(CommonSequenceTypes::ExactlyOneString->matches(m_operand->staticType())) + return m_operand; + } + + return me; +} + +SequenceType::List SimpleContentConstructor::expectedOperandTypes() const +{ + SequenceType::List result; + result.append(CommonSequenceTypes::ZeroOrMoreAtomicTypes); + return result; +} + +SequenceType::Ptr SimpleContentConstructor::staticType() const +{ + if(m_operand->staticType()->cardinality().allowsEmpty()) + return CommonSequenceTypes::ZeroOrOneString; + else + return CommonSequenceTypes::ExactlyOneString; +} + +ExpressionVisitorResult::Ptr SimpleContentConstructor::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qsimplecontentconstructor_p.h b/src/xmlpatterns/expr/qsimplecontentconstructor_p.h new file mode 100644 index 0000000..bb80b4a --- /dev/null +++ b/src/xmlpatterns/expr/qsimplecontentconstructor_p.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_SimpleContentConstructor_H +#define Patternist_SimpleContentConstructor_H + +#include "qsinglecontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + + /** + * @short Constructs simple content as specified for attributes in direct + * element constructors in XQuery. + * + * @note Sometimes you want XSLTSimpleContentConstructor. + * + * @see XSLTSimpleContentConstructor + * @see XQuery 1.0: + * An XML Query Language, 3.7.1.1 Attributes + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class SimpleContentConstructor : public SingleContainer + { + public: + SimpleContentConstructor(const Expression::Ptr &operand); + + virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; + + virtual Expression::Ptr compress(const StaticContext::Ptr &context); + + virtual SequenceType::List expectedOperandTypes() const; + virtual SequenceType::Ptr staticType() const; + + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qsinglecontainer.cpp b/src/xmlpatterns/expr/qsinglecontainer.cpp new file mode 100644 index 0000000..cd280f3 --- /dev/null +++ b/src/xmlpatterns/expr/qsinglecontainer.cpp @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + + +#include "qsinglecontainer_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +SingleContainer::SingleContainer(const Expression::Ptr &operand) : m_operand(operand) +{ + Q_ASSERT(operand); +} + +Expression::List SingleContainer::operands() const +{ + Expression::List list; + list.append(m_operand); + return list; +} + +void SingleContainer::setOperands(const Expression::List &ops) +{ + Q_ASSERT(ops.count() == 1); + m_operand = ops.first(); +} + +bool SingleContainer::compressOperands(const StaticContext::Ptr &context) +{ + rewrite(m_operand, m_operand->compress(context), context); + + return m_operand->isEvaluated(); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qsinglecontainer_p.h b/src/xmlpatterns/expr/qsinglecontainer_p.h new file mode 100644 index 0000000..a55e891 --- /dev/null +++ b/src/xmlpatterns/expr/qsinglecontainer_p.h @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_SingleContainer_H +#define Patternist_SingleContainer_H + +#include "qexpression_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Base class for expressions that has exactly one operand. + * + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class SingleContainer : public Expression + { + public: + virtual Expression::List operands() const; + + virtual void setOperands(const Expression::List &operands); + virtual bool compressOperands(const StaticContext::Ptr &); + + protected: + SingleContainer(const Expression::Ptr &operand); + + Expression::Ptr m_operand; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qsourcelocationreflection.cpp b/src/xmlpatterns/expr/qsourcelocationreflection.cpp new file mode 100644 index 0000000..d24b030 --- /dev/null +++ b/src/xmlpatterns/expr/qsourcelocationreflection.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsourcelocation.h" + +#include "qsourcelocationreflection_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +QSourceLocation SourceLocationReflection::sourceLocation() const +{ + return QSourceLocation(); +} + +const SourceLocationReflection *DelegatingSourceLocationReflection::actualReflection() const +{ + return m_r->actualReflection(); +} + +QString DelegatingSourceLocationReflection::description() const +{ + return m_r->description(); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qsourcelocationreflection_p.h b/src/xmlpatterns/expr/qsourcelocationreflection_p.h new file mode 100644 index 0000000..d85c10c --- /dev/null +++ b/src/xmlpatterns/expr/qsourcelocationreflection_p.h @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_SourceLocationReflection_H +#define Patternist_SourceLocationReflection_H + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QString; + +namespace QPatternist +{ + /** + * @short Base class for all instances that represents something + * at a certain location. + * + * SourceLocationReflection does not provide the source location itself, + * the address to an instance is the mark for it, that in turn can be used + * for looking up the source location where that mapping is provided. + * + * However, this SourceLocationReflection is not itself the mark. The real + * mark is retrieved by calling actualReflection(). This mechanism + * allows a SourceLocationReflection sub-class to delegate, or be an alias, + * for another source location mark. + * + * If sourceLocation() returns a non-null object, it will be used instead + * of looking up via actualReflection(). + * + * @author Frans Englich + * @ingroup Patternist_expressions + */ + class Q_AUTOTEST_EXPORT SourceLocationReflection + { + public: + inline SourceLocationReflection() + { + } + + virtual ~SourceLocationReflection() + { + } + + virtual const SourceLocationReflection *actualReflection() const = 0; + + /** + * A description of what represents the source code location, for + * human consumption. Must be translated, as appropriate. + */ + virtual QString description() const + { + return QString(); + } + + virtual QSourceLocation sourceLocation() const; + + private: + Q_DISABLE_COPY(SourceLocationReflection) + }; + + class DelegatingSourceLocationReflection : public SourceLocationReflection + { + public: + inline DelegatingSourceLocationReflection(const SourceLocationReflection *const r) : m_r(r) + { + Q_ASSERT(r); + } + + virtual const SourceLocationReflection *actualReflection() const; + virtual QString description() const; + + private: + const SourceLocationReflection *const m_r; + }; + +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qstaticbaseuristore.cpp b/src/xmlpatterns/expr/qstaticbaseuristore.cpp new file mode 100644 index 0000000..41b2d02 --- /dev/null +++ b/src/xmlpatterns/expr/qstaticbaseuristore.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonsequencetypes_p.h" +#include "qstaticbaseuricontext_p.h" + +#include "qstaticbaseuristore_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +StaticBaseURIStore::StaticBaseURIStore(const QUrl &baseURI, + const Expression::Ptr &operand) : SingleContainer(operand) + , m_baseURI(baseURI) +{ +} + +Expression::Ptr StaticBaseURIStore::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + const StaticContext::Ptr newContext(new StaticBaseURIContext(context->baseURI().resolved(m_baseURI), + context)); + return m_operand->typeCheck(newContext, reqType); +} + +SequenceType::Ptr StaticBaseURIStore::staticType() const +{ + return m_operand->staticType(); +} + +SequenceType::List StaticBaseURIStore::expectedOperandTypes() const +{ + SequenceType::List ops; + ops.append(CommonSequenceTypes::ZeroOrMoreItems); + return ops; +} + +ExpressionVisitorResult::Ptr StaticBaseURIStore::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qstaticbaseuristore_p.h b/src/xmlpatterns/expr/qstaticbaseuristore_p.h new file mode 100644 index 0000000..1347eab --- /dev/null +++ b/src/xmlpatterns/expr/qstaticbaseuristore_p.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_StaticBaseURIStore_H +#define Patternist_StaticBaseURIStore_H + +#include "qsinglecontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A compile time only AST node that changes the static base URI, + * used when @c xml:base attributes appears. + * + * @see StaticBaseURIContext + * @author Frans Englich + * @ingroup Patternist_expressions + * @since 4.5 + */ + class StaticBaseURIStore : public SingleContainer + { + public: + /** + * @p baseURI must be valid, not empty, and either relative or + * absolute. + */ + StaticBaseURIStore(const QUrl &baseURI, + const Expression::Ptr &operand); + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + virtual SequenceType::Ptr staticType() const; + virtual SequenceType::List expectedOperandTypes() const; + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + + private: + const QUrl m_baseURI; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qstaticcompatibilitystore.cpp b/src/xmlpatterns/expr/qstaticcompatibilitystore.cpp new file mode 100644 index 0000000..1131955 --- /dev/null +++ b/src/xmlpatterns/expr/qstaticcompatibilitystore.cpp @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcommonsequencetypes_p.h" +#include "qstaticcompatibilitycontext_p.h" + +#include "qstaticcompatibilitystore_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +StaticCompatibilityStore::StaticCompatibilityStore(const Expression::Ptr &operand) : SingleContainer(operand) +{ +} + +Expression::Ptr StaticCompatibilityStore::typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType) +{ + const StaticContext::Ptr newContext(new StaticCompatibilityContext(context)); + return m_operand->typeCheck(newContext, reqType); +} + +SequenceType::Ptr StaticCompatibilityStore::staticType() const +{ + return m_operand->staticType(); +} + +SequenceType::List StaticCompatibilityStore::expectedOperandTypes() const +{ + SequenceType::List ops; + ops.append(CommonSequenceTypes::ZeroOrMoreItems); + return ops; +} + +ExpressionVisitorResult::Ptr StaticCompatibilityStore::accept(const ExpressionVisitor::Ptr &visitor) const +{ + return visitor->visit(this); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qstaticcompatibilitystore_p.h b/src/xmlpatterns/expr/qstaticcompatibilitystore_p.h new file mode 100644 index 0000000..981a177 --- /dev/null +++ b/src/xmlpatterns/expr/qstaticcompatibilitystore_p.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_StaticCompatibilityStore_H +#define Patternist_StaticCompatibilityStore_H + +#include "qsinglecontainer_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short A compile time only AST node that changes the backwareds compatibility mode. + * Used for XSL-T 2.0's backwards compatibility mode. + * + * @see StaticCompatibilityContext + * @author Frans Englich + * @ingroup Patternist_expressions + * @since 4.5 + */ + class StaticCompatibilityStore : public SingleContainer + { + public: + /** + * @p baseURI must be valid, not empty, and either relative or + * absolute. + */ + StaticCompatibilityStore(const Expression::Ptr &operand); + virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, + const SequenceType::Ptr &reqType); + virtual SequenceType::Ptr staticType() const; + virtual SequenceType::List expectedOperandTypes() const; + virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const; + }; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/xmlpatterns/expr/qtemplate.cpp b/src/xmlpatterns/expr/qtemplate.cpp new file mode 100644 index 0000000..79afab6 --- /dev/null +++ b/src/xmlpatterns/expr/qtemplate.cpp @@ -0,0 +1,232 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdynamiccontextstore_p.h" +#include "qpatternistlocale_p.h" + +#include "qtemplate_p.h" + +QT_BEGIN_NAMESPACE + +using namespace QPatternist; + +const SourceLocationReflection* Template::actualReflection() const +{ + return this; +} + +DynamicContext::TemplateParameterHash Template::parametersAsHash() const +{ + DynamicContext::TemplateParameterHash retval; + const int len = templateParameters.count(); + + for(int i = 0; i < len; ++i) + { + const VariableDeclaration::Ptr &at = templateParameters.at(i); + retval.insert(at->name, at->expression()); + } + + return retval; +} + +void Template::raiseXTSE0680(const ReportContext::Ptr &context, + const QXmlName &name, + const SourceLocationReflection *const reflection) +{ + context->error(QtXmlPatterns::tr("The parameter %1 is passed, but no corresponding %2 exists.") + .arg(formatKeyword(context->namePool(), name), + formatKeyword(QLatin1String("xsl:param"))), + ReportContext::XTSE0680, + reflection); +} + +DynamicContext::Ptr Template::createContext(const TemplateInvoker *const invoker, + const DynamicContext::Ptr &context, + const bool isCallTemplate) const +{ + Q_ASSERT(invoker); + Q_ASSERT(context); + + /* We have: + * - xsl:params in the target template (if any) which may provide + * default values. + * - xsl:with-params in the caller (if any) which provides values. + * + * We need to, for each parameter: + * - If the called template provides no default value and the caller + * has no value, it's an error + * - If the called template has a default value and the caller provides + * none, it should be used + * - In any case the caller provides a value, it needs to be used. + * + * Problems to look out for: + * + * - Each xsl:param is in scope for the subsequent xsl:params. Hence, + * the evaluation of one xsl:param can depend on another xsl:param, + * and so on + * - The focus for xsl:params is different from the focus for + * the xsl:with-params + * - The xsl:with-params are not in scope for the xsl:params. + */ + + WithParam::Hash withParams(invoker->withParams()); + + /** + * Parameters or not, we must in any case create a new stack frame + * for the template invocation since otherwise we will trash our existing + * variables. Hence it's as with calling user functions. + * + * This is especially reproducible with recursive functions. + */ + DynamicContext::Ptr newStack(context->createStack()); + + /* We have no parameters, and we have no further error checking to + * do in the case of not being xsl:apply-templates, so we need to do nothing. */ + if(templateParameters.isEmpty() && (!isCallTemplate || withParams.isEmpty())) + return newStack; + + const DynamicContext::TemplateParameterHash hashedParams(parametersAsHash()); + DynamicContext::TemplateParameterHash sewnTogether(hashedParams); + + const DynamicContext::TemplateParameterHash::iterator end(sewnTogether.end()); + + for(DynamicContext::TemplateParameterHash::iterator it(sewnTogether.begin()); + it != end; + ++it) + { + Expression::Ptr ¶m = it.value(); + + WithParam::Ptr &withParam = withParams[it.key()]; + + if(withParam) + param = Expression::Ptr(new DynamicContextStore(withParam->sourceExpression(), context)); + else if(!param) + { + /* Ops, no xsl:with-param and no default value to cover up for it. + */ + context->error(QtXmlPatterns::tr("The parameter %1 is required, but no corresponding %2 is supplied.") + .arg(formatKeyword(context->namePool(), it.key()), + formatKeyword(QLatin1String("xsl:with-param"))), + ReportContext::XTSE0690, + this); + } + } + + if(isCallTemplate) + { + /* Find xsl:with-param that has no corresponding xsl:param. */ + /* Optimization: candidate for threading? */ + + const WithParam::Hash::const_iterator end(withParams.constEnd()); + + for(WithParam::Hash::const_iterator it(withParams.constBegin()); it != end; ++it) + { + if(!hashedParams.contains(it.key())) + raiseXTSE0680(context, it.key(), this); + } + + } + + newStack->templateParameterStore() = sewnTogether; + return newStack; +} + +void Template::compileParameters(const StaticContext::Ptr &context) +{ + Q_ASSERT(context); + + const int len = templateParameters.count(); + + for(int i = 0; i < len; ++i) + { + const VariableDeclaration::Ptr &at = templateParameters.at(i); + + /* If our value is required, we don't have a default value. */ + if(at->expression()) + { + // TODO why do we pass in its own type here? + at->setExpression(at->expression()->typeCheck(context, at->expression()->staticType())); + + at->setExpression(at->expression()->compress(context)); + } + } +} + +Expression::Properties Template::properties() const +{ + return Expression::DisableElimination; /* We're having issues with recursion detection, so this path currently loops infintely. */ + + Expression::Properties collect(body->properties()); + + VariableDeclaration::List::const_iterator end(templateParameters.constEnd()); + + for(VariableDeclaration::List::const_iterator it(templateParameters.constBegin()); + it != end; + ++it) + { + if((*it)->expression()) + collect |= (*it)->expression()->properties(); + } + + // TODO simplify. + return collect & (Expression::RequiresFocus | Expression::IsEvaluated | Expression::DisableElimination); +} + +Expression::Properties Template::dependencies() const +{ + return Expression::DisableElimination; /* We're having issues with recursion detection, so this path currently loops infintely. */ + + Expression::Properties collect(body->dependencies()); + + VariableDeclaration::List::const_iterator end(templateParameters.constEnd()); + + for(VariableDeclaration::List::const_iterator it(templateParameters.constBegin()); + it != end; + ++it) + { + if((*it)->expression()) + collect |= (*it)->expression()->dependencies(); + } + + return collect & (Expression::RequiresFocus | Expression::IsEvaluated | Expression::DisableElimination); +} + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/expr/qtemplate_p.h b/src/xmlpatterns/expr/qtemplate_p.h new file mode 100644 index 0000000..cf00850 --- /dev/null +++ b/src/xmlpatterns/expr/qtemplate_p.h @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtXmlPatterns module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. + +#ifndef Patternist_Template_H +#define Patternist_Template_H + +#include +#include + +#include "qdynamiccontext_p.h" +#include "qexpression_p.h" +#include "qsourcelocationreflection_p.h" +#include "qtemplateinvoker_p.h" +#include "qvariabledeclaration_p.h" + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +namespace QPatternist +{ + /** + * @short Contains data related to a template. + * + * A Template is associated with a mode, by being housed + * inside a TemplateMode instance. + * + * Template has role very similar to UserFunction. + * + * @see TemplateMode + * @see TemplatePattern + * @see UserFunction + * @author Frans Englich + * @ingroup Patternist_expressions + * @since 4.5 + */ + class Template : public QSharedData + , public SourceLocationReflection + + { + public: + typedef QExplicitlySharedDataPointer