xref: /trunk/main/xml2cmp/source/x2cclass/xml_cdff.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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