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: 37 dyn_buffer() : s(0) {} 38 ~dyn_buffer() { if (s) delete [] s; } 39 operator const char *() const { return s; } 40 char * operator->() { return s; } 41 char & operator[]( 42 INT32 ix ) { return s[ix]; } 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 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 77 CompDescrsFromAnXmlFile::CompDescrsFromAnXmlFile() 78 : dpDescriptions(new std::vector< ComponentDescriptionImpl* >), 79 eStatus(not_yet_parsed) 80 { 81 dpDescriptions->reserve(3); 82 } 83 84 CompDescrsFromAnXmlFile::~CompDescrsFromAnXmlFile() 85 { 86 Empty(); 87 delete dpDescriptions; 88 } 89 90 91 BOOL 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 199 CompDescrsFromAnXmlFile::NrOfDescriptions() const 200 { 201 return dpDescriptions->size(); 202 } 203 204 const ComponentDescription & 205 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 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