xref: /AOO41X/main/xml2cmp/source/x2cclass/xml_cdff.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #include "xml_cdff.hxx"
29 
30 #include <string.h>
31 #include <tools/stream.hxx>
32 #include "xml_cdim.hxx"
33 #include <ctype.h>
34 
35 
36 typedef ComponentDescriptionImpl::ValueList CdiValueList;
37 
38 class dyn_buffer
39 {
40   public:
41 						dyn_buffer() 					: s(0) {}
42 						~dyn_buffer()                   { if (s) delete [] s; }
43 						operator const char *() const 	{ return s; }
44 	char *              operator->()                    { return s; }
45 	char &              operator[](
46 							INT32 ix )                  { return s[ix]; }
47 	void               	SetSize(
48 							INT32 i_size )              { if (s) delete [] s; s = new char [i_size]; }
49   private:
50 	char * s;
51 };
52 
53 
54 inline BOOL
55 LoadXmlFile( dyn_buffer & 		o_rBuffer,
56 			 const UniString &	i_sXmlFilePath )
57 {
58 	BOOL ret = TRUE;
59 	SvFileStream aXmlFile;
60 
61 	aXmlFile.Open(i_sXmlFilePath, STREAM_READ);
62 	if (aXmlFile.GetErrorCode() != FSYS_ERR_OK)
63 		ret = FALSE;
64 	if (ret)
65 	{
66 		aXmlFile.Seek(STREAM_SEEK_TO_END);
67 		INT32 nBufferSize = aXmlFile.Tell();
68 		o_rBuffer.SetSize(nBufferSize + 1);
69 		o_rBuffer[nBufferSize] = '\0';
70 		aXmlFile.Seek(0);
71 		if (aXmlFile.Read(o_rBuffer.operator->(), nBufferSize) == 0)
72 			ret = FALSE;
73 	}
74 
75 	aXmlFile.Close();
76 	return ret;
77 }
78 
79 
80 
81 CompDescrsFromAnXmlFile::CompDescrsFromAnXmlFile()
82 	:	dpDescriptions(new std::vector< ComponentDescriptionImpl* >),
83 		eStatus(not_yet_parsed)
84 {
85 	dpDescriptions->reserve(3);
86 }
87 
88 CompDescrsFromAnXmlFile::~CompDescrsFromAnXmlFile()
89 {
90 	Empty();
91 	delete dpDescriptions;
92 }
93 
94 
95 BOOL
96 CompDescrsFromAnXmlFile::Parse( const UniString & i_sXmlFilePath )
97 {
98 	dyn_buffer  	dpBuffer;
99 
100 	if (! LoadXmlFile(dpBuffer,i_sXmlFilePath) )
101 	{
102 		eStatus = cant_read_file;
103 		return FALSE;
104 	}
105 
106 	const char * 	pTokenStart = 0;
107 	const char *    pBufferPosition = dpBuffer;
108 	INT32           nTokenLength = 0;
109 	BOOL			bWithinElement = FALSE;
110 
111 	CdiValueList *	pCurTagData = 0;
112 	ByteString      sStatusValue;	// Used only if a <Status ...> tag is found.
113 
114 
115 	for ( ComponentDescriptionImpl::ParseUntilStartOfDescription(pBufferPosition);
116 		  pBufferPosition != 0;
117 		  ComponentDescriptionImpl::ParseUntilStartOfDescription(pBufferPosition) )
118 	{
119 		ComponentDescriptionImpl * pCurCD = 0;
120 		pCurCD = new ComponentDescriptionImpl;
121 		dpDescriptions->push_back(pCurCD);
122 
123 		for ( ; *pBufferPosition != '\0' && pCurCD != 0; )
124 		{
125 			switch (*pBufferPosition)
126 			{
127 				case '<' :
128 						if (! bWithinElement)
129 						{
130 							pCurTagData = pCurCD->GetBeginTag(sStatusValue, pBufferPosition);
131 							if (pCurTagData != 0)
132 							{
133 								if (sStatusValue.Len () == 0)
134 								{
135 									// Start new token:
136 									pTokenStart = pBufferPosition;
137 									nTokenLength = 0;
138 									bWithinElement = TRUE;;
139 								}
140 								else
141 								{
142 									// Status tag is already parsed:
143 									pCurTagData->push_back(sStatusValue);
144 								}	// endif (sStatusValue.Length () == 0)
145 							}
146 							else if ( ComponentDescriptionImpl::CheckEndOfDescription(pBufferPosition) )
147 							{
148 								pBufferPosition += ComponentDescriptionImpl::DescriptionEndTagSize();
149 								pCurCD = 0;
150 							}
151 							else
152 							{
153 								eStatus = inconsistent_file;
154 								return FALSE;
155 							}	// endif (pCurTagData != 0) elseif() else
156 						}
157 						else if ( pCurTagData->MatchesEndTag(pBufferPosition) )
158 						{
159 							// Finish token:
160 							pBufferPosition += pCurTagData->EndTagLength();
161 							bWithinElement = FALSE;
162 
163 								// Remove leading and trailing spaces:
164 							while ( isspace(*pTokenStart) )
165 							{
166 							   pTokenStart++;
167 							   nTokenLength--;
168 							}
169 							while ( nTokenLength > 0
170 									&& isspace(pTokenStart[nTokenLength-1]) )
171 							{
172 								nTokenLength--;
173 							}
174 								// Add token to tag values list.
175 							pCurTagData->push_back(ByteString(pTokenStart,nTokenLength));
176 						}
177 						else
178 						{
179 							nTokenLength++;
180 							++pBufferPosition;
181 						}	// endif (!bWithinElement) else if () else
182 					   break;
183 				default:
184 						if (bWithinElement)
185 						{
186 							++nTokenLength;
187 						}
188 						++pBufferPosition;
189 			}	// end switch
190 		} 	// end for
191 
192 		if (bWithinElement)
193 		{
194 			eStatus = inconsistent_file;
195 			return FALSE;
196 		}
197 	} // end for
198 
199 	return TRUE;
200 }
201 
202 INT32
203 CompDescrsFromAnXmlFile::NrOfDescriptions() const
204 {
205 	return dpDescriptions->size();
206 }
207 
208 const ComponentDescription &
209 CompDescrsFromAnXmlFile::operator[](INT32 i_nIndex) const
210 {
211 	static const ComponentDescriptionImpl aNullDescr_;
212 	return 0 <= i_nIndex && i_nIndex < dpDescriptions->size()
213 				?	*(*dpDescriptions)[i_nIndex]
214 				:   aNullDescr_;
215 }
216 
217 void
218 CompDescrsFromAnXmlFile::Empty()
219 {
220 	for ( std::vector< ComponentDescriptionImpl* >::iterator aIter = dpDescriptions->begin();
221 		  aIter != dpDescriptions->end();
222 		  ++aIter )
223 	{
224 		delete *aIter;
225 	}
226 	dpDescriptions->erase( dpDescriptions->begin(),
227 						   dpDescriptions->end() );
228 }
229 
230 
231 
232