1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_shell.hxx" 26 #include "internal/contentreader.hxx" 27 #include "dummytag.hxx" 28 #include "simpletag.hxx" 29 #include "autostyletag.hxx" 30 31 #include "assert.h" 32 33 /** constructor. 34 */ 35 CContentReader::CContentReader( const std::string& DocumentName, LocaleSet_t const & DocumentLocale ): 36 CBaseReader( DocumentName ) 37 { 38 try 39 { 40 m_DefaultLocale = DocumentLocale; 41 Initialize( DOC_CONTENT_NAME ); 42 } 43 catch(xml_parser_exception& 44 #if OSL_DEBUG_LEVEL > 0 45 ex 46 #endif 47 ) 48 { 49 ENSURE(false, ex.what()); 50 } 51 catch(...) 52 { 53 ENSURE(false, "Unknown error"); 54 } 55 } 56 57 CContentReader::CContentReader( void* stream, LocaleSet_t const & DocumentLocale, zlib_filefunc_def* fa ) : 58 CBaseReader( stream, fa ) 59 { 60 try 61 { 62 m_DefaultLocale = DocumentLocale; 63 Initialize( DOC_CONTENT_NAME ); 64 } 65 catch(xml_parser_exception& 66 #if OSL_DEBUG_LEVEL > 0 67 ex 68 #endif 69 ) 70 { 71 ENSURE(false, ex.what()); 72 } 73 catch(...) 74 { 75 ENSURE(false, "Unknown error"); 76 } 77 } 78 79 80 /** destructor. 81 */ 82 83 CContentReader::~CContentReader( void ) 84 { 85 } 86 87 /*********************** helper functions ***********************/ 88 89 /** choose an appropriate tag reader 90 */ 91 92 ITag* CContentReader::chooseTagReader( const std::wstring& tag_name, const XmlTagAttributes_t& XmlAttributes ) 93 { 94 if (( tag_name == CONTENT_TEXT_A )||( tag_name == CONTENT_TEXT_P )|| 95 ( tag_name == CONTENT_TEXT_SPAN ) ||( tag_name == CONTENT_TEXT_H )|| 96 ( tag_name == CONTENT_TEXT_SEQUENCE ) ||( tag_name == CONTENT_TEXT_BOOKMARK_REF )|| 97 ( tag_name == CONTENT_TEXT_INDEX_TITLE_TEMPLATE ) ) 98 return new CSimpleTag(XmlAttributes); 99 else if ( tag_name == CONTENT_STYLE_STYLE ) 100 { 101 // if style:style | style:name is exist,, fill the style field, otherwise do nothing; 102 if ( XmlAttributes.find(CONTENT_STYLE_STYLE_NAME) != XmlAttributes.end()) 103 return new CAutoStyleTag(XmlAttributes); 104 else 105 return new CDummyTag(); 106 } 107 else if ( ( tag_name == CONTENT_STYLE_PROPERTIES ) || ( tag_name == CONTENT_TEXT_STYLE_PROPERTIES ) ) 108 { 109 assert( !m_TagBuilderStack.empty() ); 110 111 //here we presume that if CONTENT_STYLE_PROPERTIES tag is present, it just follow CONTENT_STYLE_STYLE; 112 ITag* pTagBuilder = m_TagBuilderStack.top(); 113 pTagBuilder->addAttributes( XmlAttributes ); 114 115 return new CDummyTag(); 116 } 117 else 118 return new CDummyTag(); 119 } 120 121 /** get style of the current content. 122 */ 123 ::std::wstring CContentReader::getCurrentContentStyle( void ) 124 { 125 assert( !m_TagBuilderStack.empty() ); 126 ITag* pTagBuilder = m_TagBuilderStack.top(); 127 128 return ( pTagBuilder->getTagAttribute(CONTENT_TEXT_STYLENAME) ); 129 } 130 131 /** add chunk into Chunk Buffer. 132 */ 133 void CContentReader::addChunk( LocaleSet_t const & Locale, Content_t const & Content ) 134 { 135 if ( Content == EMPTY_STRING ) 136 return; 137 138 if ( ( ( m_ChunkBuffer.empty() ) || ( m_ChunkBuffer.back().first != Locale ) ) && 139 ( ( Content != SPACE ) && ( Content != LF ) ) ) 140 { 141 // if met a new locale, add a blank new chunk; 142 Chunk_t Chunk; 143 Chunk.first = Locale; 144 Chunk.second = EMPTY_STRING; 145 m_ChunkBuffer.push_back( Chunk ); 146 } 147 148 if ( !m_ChunkBuffer.empty() ) 149 m_ChunkBuffer.back().second += Content; 150 } 151 152 /** get a style's locale field. 153 */ 154 155 LocaleSet_t const & CContentReader::getLocale( const StyleName_t Style ) 156 { 157 if ( m_StyleMap.empty() ) 158 return m_DefaultLocale; 159 160 StyleLocaleMap_t :: const_iterator style_Iter; 161 162 if ( ( style_Iter = m_StyleMap.find( Style ) ) == m_StyleMap.end( ) ) 163 return m_DefaultLocale; 164 else 165 return style_Iter->second; 166 167 } 168 169 /*********************** event handler functions ***********************/ 170 171 //------------------------------ 172 // start_element occurs when a tag is start 173 //------------------------------ 174 175 void CContentReader::start_element( 176 const std::wstring& /*raw_name*/, 177 const std::wstring& local_name, 178 const XmlTagAttributes_t& attributes) 179 { 180 //get appropriate Xml Tag Builder using MetaInfoBuilderFactory; 181 ITag* pTagBuilder = chooseTagReader( local_name,attributes ); 182 assert( pTagBuilder != NULL ); 183 pTagBuilder->startTag( ); 184 m_TagBuilderStack.push( pTagBuilder ); 185 186 } 187 188 //------------------------------ 189 // end_element occurs when a tag is closed 190 //------------------------------ 191 192 void CContentReader::end_element(const std::wstring& /*raw_name*/, const std::wstring& local_name) 193 { 194 assert( !m_TagBuilderStack.empty() ); 195 ITag* pTagBuilder = m_TagBuilderStack.top(); 196 197 if ( local_name == CONTENT_STYLE_STYLE ) 198 { 199 StyleLocalePair_t StyleLocalePair = static_cast<CAutoStyleTag * >( pTagBuilder)->getStyleLocalePair(); 200 if ( ( static_cast<CAutoStyleTag * >( pTagBuilder)->isFull() ) && ( StyleLocalePair.second != m_DefaultLocale ) ) 201 m_StyleMap.insert( StyleLocalePair ); 202 } 203 if (( local_name == CONTENT_TEXT_A )||( local_name == CONTENT_TEXT_SPAN ) || 204 ( local_name == CONTENT_TEXT_SEQUENCE )||( local_name == CONTENT_TEXT_BOOKMARK_REF )) 205 addChunk( getLocale( getCurrentContentStyle() ), ::std::wstring( SPACE ) ); 206 if ((( local_name == CONTENT_TEXT_P )||( local_name == CONTENT_TEXT_H ) || 207 ( local_name == CONTENT_TEXT_INDEX_TITLE_TEMPLATE ) )&& 208 ( EMPTY_STRING != pTagBuilder->getTagContent( ) ) ) 209 addChunk( getLocale( getCurrentContentStyle() ), ::std::wstring( LF ) ); 210 211 m_TagBuilderStack.pop(); 212 pTagBuilder->endTag(); 213 delete pTagBuilder; 214 215 } 216 217 //------------------------------ 218 // characters occurs when receiving characters 219 //------------------------------ 220 221 void CContentReader::characters( const std::wstring& character ) 222 { 223 if ( character.length() > 0 && !HasOnlySpaces( character ) ) 224 { 225 addChunk( getLocale( getCurrentContentStyle() ), ::std::wstring( character ) ); 226 227 ITag* pTagBuilder = m_TagBuilderStack.top(); 228 pTagBuilder->addCharacters( character ); 229 } 230 } 231 232