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