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 #include "xml_cdff.hxx"
25 
26 #include <string.h>
27 #include <tools/stream.hxx>
28 #include "xml_cdim.hxx"
29 #include <ctype.h>
30 
31 
32 typedef ComponentDescriptionImpl::ValueList CdiValueList;
33 
34 class dyn_buffer
35 {
36   public:
dyn_buffer()37 						dyn_buffer() 					: s(0) {}
~dyn_buffer()38 						~dyn_buffer()                   { if (s) delete [] s; }
39 						operator const char *() const 	{ return s; }
operator ->()40 	char *              operator->()                    { return s; }
operator [](INT32 ix)41 	char &              operator[](
42 							INT32 ix )                  { return s[ix]; }
SetSize(INT32 i_size)43 	void               	SetSize(
44 							INT32 i_size )              { if (s) delete [] s; s = new char [i_size]; }
45   private:
46 	char * s;
47 };
48 
49 
50 inline BOOL
LoadXmlFile(dyn_buffer & o_rBuffer,const UniString & i_sXmlFilePath)51 LoadXmlFile( dyn_buffer & 		o_rBuffer,
52 			 const UniString &	i_sXmlFilePath )
53 {
54 	BOOL ret = TRUE;
55 	SvFileStream aXmlFile;
56 
57 	aXmlFile.Open(i_sXmlFilePath, STREAM_READ);
58 	if (aXmlFile.GetErrorCode() != FSYS_ERR_OK)
59 		ret = FALSE;
60 	if (ret)
61 	{
62 		aXmlFile.Seek(STREAM_SEEK_TO_END);
63 		INT32 nBufferSize = aXmlFile.Tell();
64 		o_rBuffer.SetSize(nBufferSize + 1);
65 		o_rBuffer[nBufferSize] = '\0';
66 		aXmlFile.Seek(0);
67 		if (aXmlFile.Read(o_rBuffer.operator->(), nBufferSize) == 0)
68 			ret = FALSE;
69 	}
70 
71 	aXmlFile.Close();
72 	return ret;
73 }
74 
75 
76 
CompDescrsFromAnXmlFile()77 CompDescrsFromAnXmlFile::CompDescrsFromAnXmlFile()
78 	:	dpDescriptions(new std::vector< ComponentDescriptionImpl* >),
79 		eStatus(not_yet_parsed)
80 {
81 	dpDescriptions->reserve(3);
82 }
83 
~CompDescrsFromAnXmlFile()84 CompDescrsFromAnXmlFile::~CompDescrsFromAnXmlFile()
85 {
86 	Empty();
87 	delete dpDescriptions;
88 }
89 
90 
91 BOOL
Parse(const UniString & i_sXmlFilePath)92 CompDescrsFromAnXmlFile::Parse( const UniString & i_sXmlFilePath )
93 {
94 	dyn_buffer  	dpBuffer;
95 
96 	if (! LoadXmlFile(dpBuffer,i_sXmlFilePath) )
97 	{
98 		eStatus = cant_read_file;
99 		return FALSE;
100 	}
101 
102 	const char * 	pTokenStart = 0;
103 	const char *    pBufferPosition = dpBuffer;
104 	INT32           nTokenLength = 0;
105 	BOOL			bWithinElement = FALSE;
106 
107 	CdiValueList *	pCurTagData = 0;
108 	ByteString      sStatusValue;	// Used only if a <Status ...> tag is found.
109 
110 
111 	for ( ComponentDescriptionImpl::ParseUntilStartOfDescription(pBufferPosition);
112 		  pBufferPosition != 0;
113 		  ComponentDescriptionImpl::ParseUntilStartOfDescription(pBufferPosition) )
114 	{
115 		ComponentDescriptionImpl * pCurCD = 0;
116 		pCurCD = new ComponentDescriptionImpl;
117 		dpDescriptions->push_back(pCurCD);
118 
119 		for ( ; *pBufferPosition != '\0' && pCurCD != 0; )
120 		{
121 			switch (*pBufferPosition)
122 			{
123 				case '<' :
124 						if (! bWithinElement)
125 						{
126 							pCurTagData = pCurCD->GetBeginTag(sStatusValue, pBufferPosition);
127 							if (pCurTagData != 0)
128 							{
129 								if (sStatusValue.Len () == 0)
130 								{
131 									// Start new token:
132 									pTokenStart = pBufferPosition;
133 									nTokenLength = 0;
134 									bWithinElement = TRUE;;
135 								}
136 								else
137 								{
138 									// Status tag is already parsed:
139 									pCurTagData->push_back(sStatusValue);
140 								}	// endif (sStatusValue.Length () == 0)
141 							}
142 							else if ( ComponentDescriptionImpl::CheckEndOfDescription(pBufferPosition) )
143 							{
144 								pBufferPosition += ComponentDescriptionImpl::DescriptionEndTagSize();
145 								pCurCD = 0;
146 							}
147 							else
148 							{
149 								eStatus = inconsistent_file;
150 								return FALSE;
151 							}	// endif (pCurTagData != 0) elseif() else
152 						}
153 						else if ( pCurTagData->MatchesEndTag(pBufferPosition) )
154 						{
155 							// Finish token:
156 							pBufferPosition += pCurTagData->EndTagLength();
157 							bWithinElement = FALSE;
158 
159 								// Remove leading and trailing spaces:
160 							while ( isspace(*pTokenStart) )
161 							{
162 							   pTokenStart++;
163 							   nTokenLength--;
164 							}
165 							while ( nTokenLength > 0
166 									&& isspace(pTokenStart[nTokenLength-1]) )
167 							{
168 								nTokenLength--;
169 							}
170 								// Add token to tag values list.
171 							pCurTagData->push_back(ByteString(pTokenStart,nTokenLength));
172 						}
173 						else
174 						{
175 							nTokenLength++;
176 							++pBufferPosition;
177 						}	// endif (!bWithinElement) else if () else
178 					   break;
179 				default:
180 						if (bWithinElement)
181 						{
182 							++nTokenLength;
183 						}
184 						++pBufferPosition;
185 			}	// end switch
186 		} 	// end for
187 
188 		if (bWithinElement)
189 		{
190 			eStatus = inconsistent_file;
191 			return FALSE;
192 		}
193 	} // end for
194 
195 	return TRUE;
196 }
197 
198 INT32
NrOfDescriptions() const199 CompDescrsFromAnXmlFile::NrOfDescriptions() const
200 {
201 	return dpDescriptions->size();
202 }
203 
204 const ComponentDescription &
operator [](INT32 i_nIndex) const205 CompDescrsFromAnXmlFile::operator[](INT32 i_nIndex) const
206 {
207 	static const ComponentDescriptionImpl aNullDescr_;
208 	return 0 <= i_nIndex && i_nIndex < dpDescriptions->size()
209 				?	*(*dpDescriptions)[i_nIndex]
210 				:   aNullDescr_;
211 }
212 
213 void
Empty()214 CompDescrsFromAnXmlFile::Empty()
215 {
216 	for ( std::vector< ComponentDescriptionImpl* >::iterator aIter = dpDescriptions->begin();
217 		  aIter != dpDescriptions->end();
218 		  ++aIter )
219 	{
220 		delete *aIter;
221 	}
222 	dpDescriptions->erase( dpDescriptions->begin(),
223 						   dpDescriptions->end() );
224 }
225 
226 
227 
228