summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@suse.cz>2011-11-21 17:32:09 +0100
committerLuboš Luňák <l.lunak@suse.cz>2011-11-24 18:43:58 +0100
commit4d5ca442d89ee36e7b1abb622e9f3d85b36e0d0c (patch)
tree5498db37fe943bdeb9def518425b0b7c661f42b8
parentf8f1ccbaf942adf9a6b16b13a9cddb1b96a6774b (diff)
streamline and document the API for mathml xml stream reading
-rw-r--r--oox/inc/oox/mathml/importutils.hxx65
-rw-r--r--oox/source/mathml/importutils.cxx47
-rw-r--r--starmath/source/ooxmlimport.cxx91
-rw-r--r--starmath/source/ooxmlimport.hxx12
4 files changed, 119 insertions, 96 deletions
diff --git a/oox/inc/oox/mathml/importutils.hxx b/oox/inc/oox/mathml/importutils.hxx
index 01baf981eb1f..f7c353da9887 100644
--- a/oox/inc/oox/mathml/importutils.hxx
+++ b/oox/inc/oox/mathml/importutils.hxx
@@ -50,24 +50,60 @@ const int TAG_CLOSING = 1 << 30;
#define OPENING( token ) ( TAG_OPENING | token )
#define CLOSING( token ) ( TAG_CLOSING | token )
+/**
+ Class for storing a stream of xml tokens.
+
+ A part of an XML file can be parsed and stored in this stream, from which it can be read
+ as if parsed linearly. The purpose of this class is to allow simpler handling of XML
+ files, unlike the usual LO way of using callbacks, context handlers and similar needlesly
+ complicated stuff (YMMV).
+
+ @since 3.5.0
+*/
class OOX_DLLPUBLIC XmlStream
{
public:
XmlStream();
- bool nextIsEnd() const;
- int peekNextToken() const;
- int getNextToken();
- oox::AttributeList getAttributes();
- rtl::OUString getCharacters();
+ /**
+ Structure representing a tag, including its attributes and content text immediatelly following it.
+ */
+ struct Tag
+ {
+ Tag( int token = XML_TOKEN_INVALID,
+ const com::sun::star::uno::Reference< com::sun::star::xml::sax::XFastAttributeList >& attributes = com::sun::star::uno::Reference< com::sun::star::xml::sax::XFastAttributeList >(),
+ const rtl::OUString& text = rtl::OUString());
+ int token; ///< tag type, or XML_TOKEN_INVALID
+ AttributeList attributes;
+ rtl::OUString text;
+ };
+ /**
+ @return true if current position is at the end of the XML stream
+ */
+ bool atEnd() const;
+ /**
+ @return data about the current tag
+ */
+ Tag currentTag() const;
+ /**
+ @return the token for the current tag
+ */
+ int currentToken() const;
+ /**
+ Moves position to the next tag.
+ */
+ void moveToNextTag();
protected:
- // TODO one list containing all 3?
- std::vector< int > tokens;
- std::vector< oox::AttributeList > attributes;
- std::vector< rtl::OUString > characters;
- int pos;
+ std::vector< Tag > tags;
+ unsigned int pos;
};
-// use this to create the data and then cast to the base class for reading
+/**
+ This class is used for creating XmlStream.
+
+ Simply use this class and then pass it as XmlStream to the consumer.
+
+ @since 3.5.0
+*/
class OOX_DLLPUBLIC XmlStreamBuilder
: public XmlStream
{
@@ -79,6 +115,13 @@ public:
void appendCharacters( const rtl::OUString& characters );
};
+inline XmlStream::Tag::Tag( int t, const com::sun::star::uno::Reference< com::sun::star::xml::sax::XFastAttributeList >& a, const rtl::OUString& txt )
+: token( t )
+, attributes( a )
+, text( txt )
+{
+}
+
} // namespace
} // namespace
diff --git a/oox/source/mathml/importutils.cxx b/oox/source/mathml/importutils.cxx
index 1381724ec407..95f81c802e83 100644
--- a/oox/source/mathml/importutils.cxx
+++ b/oox/source/mathml/importutils.cxx
@@ -41,62 +41,51 @@ namespace formulaimport
{
XmlStream::XmlStream()
-: pos( -1 )
+: pos( 0 )
{
// make sure our extra bit does not conflict with values used by oox
assert( TAG_OPENING > ( 1024 << NMSP_SHIFT ));
}
-bool XmlStream::nextIsEnd() const
+bool XmlStream::atEnd() const
{
- return pos + 1 >= int( tokens.size());
+ return pos >= tags.size();
}
-int XmlStream::getNextToken()
+XmlStream::Tag XmlStream::currentTag() const
{
- ++pos;
- if( pos < int( tokens.size()))
- return tokens[ pos ];
- return XML_TOKEN_INVALID;
+ if( pos >= tags.size())
+ return Tag();
+ return tags[ pos ];
}
-int XmlStream::peekNextToken() const
+int XmlStream::currentToken() const
{
- if( pos - 1 < int( tokens.size()))
- return tokens[ pos + 1 ];
- return XML_TOKEN_INVALID;
+ if( pos >= tags.size())
+ return XML_TOKEN_INVALID;
+ return tags[ pos ].token;
}
-AttributeList XmlStream::getAttributes()
+void XmlStream::moveToNextTag()
{
- assert( pos < int( attributes.size()));
- return attributes[ pos ];
-}
-
-rtl::OUString XmlStream::getCharacters()
-{
- assert( pos < int( characters.size()));
- return characters[ pos ];
+ if( pos < tags.size())
+ ++pos;
}
void XmlStreamBuilder::appendOpeningTag( int token, const uno::Reference< xml::sax::XFastAttributeList >& attrs )
{
- tokens.push_back( OPENING( token ));
- attributes.push_back( AttributeList( attrs ));
- characters.push_back( rtl::OUString());
+ tags.push_back( Tag( OPENING( token ), attrs ));
}
void XmlStreamBuilder::appendClosingTag( int token )
{
- tokens.push_back( CLOSING( token ));
- attributes.push_back( AttributeList( uno::Reference< xml::sax::XFastAttributeList >()));
- characters.push_back( rtl::OUString());
+ tags.push_back( Tag( CLOSING( token )));
}
void XmlStreamBuilder::appendCharacters( const rtl::OUString& chars )
{
- assert( !characters.empty());
- characters.back() = chars;
+ assert( !tags.empty());
+ tags.back().text = chars;
}
} // namespace
diff --git a/starmath/source/ooxmlimport.cxx b/starmath/source/ooxmlimport.cxx
index dc53cc72996d..16f887ca6c15 100644
--- a/starmath/source/ooxmlimport.cxx
+++ b/starmath/source/ooxmlimport.cxx
@@ -70,17 +70,16 @@ OUString SmOoxmlImport::handleStream()
{
checkOpeningTag( M_TOKEN( oMath ));
OUString ret;
- bool out = false;
- while( !out && !stream.nextIsEnd())
+ while( !stream.atEnd())
{
- switch( stream.peekNextToken())
+ XmlStream::Tag tag = stream.currentTag();
+ if( tag.token == CLOSING( M_TOKEN( oMath )))
+ break;
+ switch( tag.token )
{
case OPENING( M_TOKEN( f )):
ret += STR( " " ) + handleF();
break;
- case CLOSING( M_TOKEN( oMath )):
- out = true;
- break;
default:
handleUnexpectedTag();
break;
@@ -94,7 +93,7 @@ OUString SmOoxmlImport::handleStream()
OUString SmOoxmlImport::handleF()
{
checkOpeningTag( M_TOKEN( f ));
- if( stream.peekNextToken() == OPENING_TAG( M_TOKEN( fPr )))
+ if( stream.currentToken() == OPENING_TAG( M_TOKEN( fPr )))
{
// TODO
}
@@ -119,18 +118,18 @@ OUString SmOoxmlImport::readR()
// checkClosingTag( OOX_TOKEN( doc, rPr ));
// TODO can there be more t's ?
- checkOpeningTag( M_TOKEN( t ));
- OUString text = stream.getCharacters();
- if( !stream.getAttributes().getBool( OOX_TOKEN( xml, space ), false ))
+ XmlStream::Tag rtag = checkOpeningTag( M_TOKEN( t ));
+ OUString text = rtag.text;
+ if( !rtag.attributes.getBool( OOX_TOKEN( xml, space ), false ))
text = text.trim();
checkClosingTag( M_TOKEN( t ));
checkClosingTag( M_TOKEN( r ));
return text;
}
-void SmOoxmlImport::checkOpeningTag( int token )
+XmlStream::Tag SmOoxmlImport::checkOpeningTag( int token )
{
- checkTag( OPENING( token ), "opening" );
+ return checkTag( OPENING( token ), "opening" );
}
void SmOoxmlImport::checkClosingTag( int token )
@@ -138,80 +137,69 @@ void SmOoxmlImport::checkClosingTag( int token )
checkTag( CLOSING( token ), "closing" );
}
-void SmOoxmlImport::checkTag( int token, const char* txt )
+XmlStream::Tag SmOoxmlImport::checkTag( int token, const char* txt )
{
- if( stream.peekNextToken() == token )
- {
- stream.getNextToken(); // read it
- return; // ok
- }
- if( recoverAndFindTag( token ))
+ // either it's the following tag, or find it
+ if( stream.currentToken() == token || recoverAndFindTag( token ))
{
- stream.getNextToken(); // read it
- return; // ok, skipped some tokens
+ XmlStream::Tag ret = stream.currentTag();
+ stream.moveToNextTag();
+ return ret; // ok
}
fprintf( stderr, "Expected %s tag %d not found.\n", txt, token );
+ return XmlStream::Tag();
}
bool SmOoxmlImport::recoverAndFindTag( int token )
{
int depth = 0;
- for(;;)
+ for(;
+ !stream.atEnd();
+ stream.moveToNextTag())
{
if( depth > 0 ) // we're inside a nested element, skip those
{
- int next = stream.getNextToken();
- if( next == OPENING( next ))
+ if( stream.currentToken() == OPENING( stream.currentToken()))
{
- fprintf( stderr, "Skipping opening tag %d\n", next );
+ fprintf( stderr, "Skipping opening tag %d\n", stream.currentToken());
++depth;
}
- else if( next == CLOSING( next ))
+ else if( stream.currentToken() == CLOSING( stream.currentToken()))
{ // TODO debug output without the OPENING/CLOSING bits set
- fprintf( stderr, "Skipping closing tag %d\n", next );
+ fprintf( stderr, "Skipping closing tag %d\n", stream.currentToken());
--depth;
}
- else if( next == XML_TOKEN_INVALID ) // end of stream
- {
- fprintf( stderr, "Unexpected end of stream reached.\n" );
- return false;
- }
else
{
- fprintf( stderr, "Malformed token %d\n", next );
+ fprintf( stderr, "Malformed token %d\n", stream.currentToken());
abort();
}
continue;
}
- int next = stream.peekNextToken();
- if( next == CLOSING( next ))
+ if( stream.currentToken() == CLOSING( stream.currentToken()))
return false; // that would be leaving current element, so not found
- if( next == token )
+ if( stream.currentToken() == token )
return true; // ok, found
- if( next == OPENING( next ))
+ if( stream.currentToken() == OPENING( stream.currentToken()))
{
- fprintf( stderr, "Skipping opening tag %d\n", next );
- stream.getNextToken();
+ fprintf( stderr, "Skipping opening tag %d\n", stream.currentToken());
++depth;
}
- else if( next == XML_TOKEN_INVALID )
- {
- fprintf( stderr, "Unexpected end of stream reached.\n" );
- return false;
- }
else
abort();
}
+ fprintf( stderr, "Unexpected end of stream reached.\n" );
+ return false;
}
void SmOoxmlImport::skipElement( int token )
{
int closing = ( token & ~TAG_OPENING ) | TAG_CLOSING; // make it a closing tag
- assert( stream.peekNextToken() == OPENING( token ));
+ assert( stream.currentToken() == OPENING( token ));
// just find the matching closing tag
if( recoverAndFindTag( closing ))
{
- stream.getNextToken(); // read it
+ stream.moveToNextTag(); // and skip it too
return;
}
fprintf( stderr, "Expected end of element %d not found.\n", token );
@@ -219,15 +207,14 @@ void SmOoxmlImport::skipElement( int token )
void SmOoxmlImport::handleUnexpectedTag()
{
- int next = stream.peekNextToken();
- if( next == XML_TOKEN_INVALID )
- return; // end of stream
- if( next == CLOSING( next ))
+ if( stream.atEnd())
+ return;
+ if( stream.currentToken() == CLOSING( stream.currentToken()))
{
- stream.getNextToken(); // just skip it
+ stream.moveToNextTag(); // just skip it
return;
}
- skipElement( stream.peekNextToken());
+ skipElement( stream.currentToken()); // otherwise skip the entire element
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/ooxmlimport.hxx b/starmath/source/ooxmlimport.hxx
index 1eebc8180120..043b44a19ec2 100644
--- a/starmath/source/ooxmlimport.hxx
+++ b/starmath/source/ooxmlimport.hxx
@@ -47,19 +47,23 @@ private:
rtl::OUString handleF();
rtl::OUString readR();
/**
- Checks that the next token is the given opening tag, if not, writes out a warning
+ Checks that the current tag is the given opening token, if not, writes out a warning
and tries to recover (skips tags until found or until the current element would end).
+ In both cases the position is moved to the next tag.
+ @return the matching found opening tag, or empty tag
*/
- void checkOpeningTag( int token );
+ oox::formulaimport::XmlStream::Tag checkOpeningTag( int token );
/**
- Checks that the next token is the given opening tag, if not, writes out a warning
+ Checks that the current tag is the given opening token, if not, writes out a warning
and tries to recover (skips tags until found or until the current element would end).
+ In both cases the position is moved to the next tag.
*/
void checkClosingTag( int token );
// helper for the two above
- void checkTag( int token, const char* txt );
+ oox::formulaimport::XmlStream::Tag checkTag( int token, const char* txt );
/**
Tries to find the given token, until either found (returns true) or end of current element.
+ Position in the stream is set to make the tag current.
*/
bool recoverAndFindTag( int token );
/**