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