LCOV - code coverage report
Current view: top level - include/oox/mathml - importutils.hxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 10 10 100.0 %
Date: 2014-04-11 Functions: 15 15 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  */
       9             : #ifndef INCLUDED_OOX_MATHML_IMPORTUTILS_HXX
      10             : #define INCLUDED_OOX_MATHML_IMPORTUTILS_HXX
      11             : 
      12             : #include <com/sun/star/xml/sax/XFastAttributeList.hpp>
      13             : #include <oox/token/tokens.hxx>
      14             : #include <map>
      15             : #include <vector>
      16             : 
      17             : #include <oox/dllapi.h>
      18             : 
      19             : namespace oox
      20             : {
      21             : 
      22             : namespace formulaimport
      23             : {
      24             : 
      25             : // used to differentiate between tags that opening or closing
      26             : const int TAG_OPENING = 1 << 29;
      27             : const int TAG_CLOSING = 1 << 30;
      28             : 
      29             : // you probably want to #define these to something shorter in the .cxx file,
      30             : // but they must be done as macros, otherwise they wouldn't be usable for case values,
      31             : // and macros cannot be namespaced
      32             : #define XML_STREAM_OPENING( token ) ( TAG_OPENING | token )
      33             : #define XML_STREAM_CLOSING( token ) ( TAG_CLOSING | token )
      34             : 
      35             : /**
      36             :  Class for storing a stream of xml tokens.
      37             : 
      38             :  A part of an XML file can be parsed and stored in this stream, from which it can be read
      39             :  as if parsed linearly. The purpose of this class is to allow simpler handling of XML
      40             :  files, unlike the usual LO way of using callbacks, context handlers and similar needlesly
      41             :  complicated stuff (YMMV).
      42             : 
      43             :  The advantages of this approach is easy to read and debug code (as it is just functions
      44             :  reading tokens one by one and calling other functions, compared to having to use callbacks
      45             :  and temporary storage). The disadvantage is that the XML structure needs to be handled
      46             :  manually by the code.
      47             : 
      48             :  Note that tag identifiers are simply int values and the API does not care besides matching
      49             :  their values to XML stream contents and requiring that the values are not as high as TAG_OPENING.
      50             :  Be prepared for the fact that some of the functions may throw exceptions if the input
      51             :  stream does not match the required token (TBD).
      52             : 
      53             :  The API tries to make the common idioms as simple as possible, see the following examples.
      54             : 
      55             :  Parse <tagone attr="value"><tagtwo>text</tagtwo></tagone> , where tagtwo is optional:
      56             :  @code
      57             : XmlStream::Tag tagoneTag = stream.ensureOpeningTag( tagone );
      58             : if( attributeTag.hasAttribute( attr ))
      59             :     ... = attributeTag.attribute( attr, defaultValueOfTheRightType );
      60             : if( XmlStream::Tag tagtwoTag = stream.checkOpeningTag( tagtwo ))
      61             : {
      62             :     ... = tagtwoTag.text;
      63             :     stream.ensureClosingTag( tagtwo );
      64             : }
      65             : stream.ensureClosingTag( tagone );
      66             :  @endcode
      67             : 
      68             :  Parse an element that may contain several sub-elements of different types in random order:
      69             :  @code
      70             : stream.ensureOpeningTag( element );
      71             : while( !stream.atEnd() && stream.currentToken() != CLOSING( element ))
      72             :     {
      73             :     switch( stream.currentToken())
      74             :     {
      75             :         case OPENING( subelement1 ):
      76             :             handleSubElement1();
      77             :             break;
      78             :         case OPENING( subelement2 ):
      79             :             ... process subelement2;
      80             :             break;
      81             :         default:
      82             :             stream.handleUnexpectedTag();
      83             :             break;
      84             :     }
      85             : stream.ensureClosingTag( element );
      86             :  @endcode
      87             : 
      88             :  If there may not be a zero number of sub-elements, use a helper bool variable or use a do-while loop.
      89             : 
      90             :  Parse an element that may contain an unknown number of sub-elements of the same type:
      91             :  @code
      92             : stream.ensureOpeningTag( element );
      93             : while( !stream.atEnd() && stream.findTag( OPENING( subelement )))
      94             :     {
      95             :     handleSubelement();
      96             :     }
      97             : stream.ensureClosingTag( element );
      98             :  @endcode
      99             : 
     100             :  If there may not be a zero number of sub-elements, use a helper bool variable or use a do-while loop.
     101             : 
     102             :  @since 3.5
     103             : */
     104         653 : class OOX_DLLPUBLIC XmlStream
     105             : {
     106             : public:
     107             :     XmlStream();
     108             :     /**
     109             :      Structure representing a list of attributes.
     110             :     */
     111             :     // One could theoretically use oox::AttributeList, but that complains if the passed reference is empty,
     112             :     // which would be complicated to avoid here. Also, parsers apparently reuse the same instance of XFastAttributeList,
     113             :     // which means using oox::AttributeList would make them all point to the one instance.
     114      193072 :     struct OOX_DLLPUBLIC AttributeList
     115             :     {
     116             :         bool hasAttribute( int token ) const;
     117             :         OUString& operator[] (int token);
     118             :         OUString attribute( int token, const OUString& def = OUString()) const;
     119             :         bool attribute( int token, bool def ) const;
     120             :         sal_Unicode attribute( int token, sal_Unicode def ) const;
     121             :         // when adding more attribute() overloads, add also to XmlStream itself
     122             :     protected:
     123             :         std::map< int, OUString > attrs;
     124             :     };
     125             :     /**
     126             :      Structure representing a tag, including its attributes and content text immediatelly following it.
     127             :     */
     128      140260 :     struct OOX_DLLPUBLIC Tag
     129             :     {
     130             :         Tag( int token = XML_TOKEN_INVALID,
     131             :             const com::sun::star::uno::Reference< com::sun::star::xml::sax::XFastAttributeList >& attributes = com::sun::star::uno::Reference< com::sun::star::xml::sax::XFastAttributeList >(),
     132             :             const OUString& text = OUString());
     133             :         Tag( int token,
     134             :             const AttributeList& attribs);
     135             :         int token; ///< tag type, or XML_TOKEN_INVALID
     136             :         AttributeList attributes;
     137             :         OUString text;
     138             :         /**
     139             :          This function returns value of the given attribute, or the passed default value if not found.
     140             :          The type of the default value selects the return type (OUString here).
     141             :         */
     142             :         OUString attribute( int token, const OUString& def = OUString()) const;
     143             :         /**
     144             :          @overload
     145             :         */
     146             :         bool attribute( int token, bool def ) const;
     147             :         /**
     148             :          @overload
     149             :         */
     150             :         sal_Unicode attribute( int token, sal_Unicode def ) const;
     151             :         // when adding more attribute() overloads, add also to XmlStream::AttributeList and inline below
     152             :         /**
     153             :          Converts to true if the tag has a valid token, false otherwise. Allows simple
     154             :          usage in if(), for example 'if( XmlStream::Tag foo = stream.checkOpeningTag( footoken ))'.
     155             :         */
     156             :         operator bool() const;
     157             :     };
     158             :     /**
     159             :      @return true if current position is at the end of the XML stream
     160             :     */
     161             :     bool atEnd() const;
     162             :     /**
     163             :      @return data about the current tag
     164             :     */
     165             :     Tag currentTag() const;
     166             :     /**
     167             :      @return the token for the current tag
     168             :     */
     169             :     int currentToken() const;
     170             :     /**
     171             :      Moves position to the next tag.
     172             :     */
     173             :     void moveToNextTag();
     174             :     /**
     175             :      Ensures that an opening tag with the given token is read. If the current tag does not match,
     176             :      writes out a warning and tries to recover by skipping tags until found (or until the current element would end).
     177             :      If found, the position in the stream is afterwards moved to the next tag.
     178             :      @return the matching found opening tag, or empty tag if not found
     179             :     */
     180             :     Tag ensureOpeningTag( int token );
     181             :     /**
     182             :      Tries to find an opening tag with the given token. Works similarly like ensureOpeningTag(),
     183             :      but if a matching tag is not found, the position in the stream is not altered. The primary
     184             :      use of this function is to check for optional elements.
     185             :      @return the matching found opening tag, or empty tag if not found
     186             :     */
     187             :     Tag checkOpeningTag( int token );
     188             :     /**
     189             :      Ensures that a closing tag with the given token is read. Like ensureOpeningTag(),
     190             :      if not, writes out a warning and tries to recover by skiping tags until found (or until the current element would end).
     191             :      If found, the position in the stream is afterwards moved to the next tag.
     192             :     */
     193             :     void ensureClosingTag( int token );
     194             :     /**
     195             :      Tries to find the given token, until either found (returns true) or end of current element.
     196             :      Position in the stream is set to make the tag current (i.e. it will be the next one read).
     197             :     */
     198             :     bool findTag( int token );
     199             :     /**
     200             :      Handle the current (unexpected) tag.
     201             :     */
     202             :     void handleUnexpectedTag();
     203             : protected:
     204             :     Tag checkTag( int token, bool optional );
     205             :     bool findTagInternal( int token, bool silent );
     206             :     void skipElementInternal( int token, bool silent );
     207             :     std::vector< Tag > tags;
     208             :     unsigned int pos;
     209             : };
     210             : 
     211             : /**
     212             :  This class is used for creating XmlStream.
     213             : 
     214             :  Simply use this class and then pass it as XmlStream to the consumer.
     215             : 
     216             :  @since 3.5.0
     217             : */
     218        1233 : class OOX_DLLPUBLIC XmlStreamBuilder
     219             : : public XmlStream
     220             : {
     221             : public:
     222             :     void appendOpeningTag( int token,
     223             :         const com::sun::star::uno::Reference< com::sun::star::xml::sax::XFastAttributeList >& attributes = com::sun::star::uno::Reference< com::sun::star::xml::sax::XFastAttributeList >());
     224             :     void appendOpeningTag( int token,
     225             :         const AttributeList& attribs );
     226             :     void appendClosingTag( int token );
     227             :     // appends the characters after the last appended token
     228             :     void appendCharacters( const OUString& characters );
     229             : };
     230             : 
     231             : inline
     232        1746 : OUString XmlStream::Tag::attribute( int t, const OUString& def ) const
     233             : {
     234        1746 :     return attributes.attribute( t, def );
     235             : }
     236             : 
     237             : inline
     238          72 : bool XmlStream::Tag::attribute( int t, bool def ) const
     239             : {
     240          72 :     return attributes.attribute( t, def );
     241             : }
     242             : 
     243             : inline
     244         127 : sal_Unicode XmlStream::Tag::attribute( int t, sal_Unicode def ) const
     245             : {
     246         127 :     return attributes.attribute( t, def );
     247             : }
     248             : 
     249             : } // namespace
     250             : } // namespace
     251             : 
     252             : #endif
     253             : 
     254             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10