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 */
CContentReader(const std::string & DocumentName,LocaleSet_t const & DocumentLocale)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 
CContentReader(void * stream,LocaleSet_t const & DocumentLocale,zlib_filefunc_def * fa)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 
~CContentReader(void)83 CContentReader::~CContentReader( void )
84 {
85 }
86 
87 /***********************   helper functions  ***********************/
88 
89 /** choose an appropriate tag reader
90 */
91 
chooseTagReader(const std::wstring & tag_name,const XmlTagAttributes_t & XmlAttributes)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 */
getCurrentContentStyle(void)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 */
addChunk(LocaleSet_t const & Locale,Content_t const & Content)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 
getLocale(const StyleName_t Style)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 
start_element(const std::wstring &,const std::wstring & local_name,const XmlTagAttributes_t & attributes)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 
end_element(const std::wstring &,const std::wstring & local_name)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 
characters(const std::wstring & character)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