| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| #include "xml_cdff.hxx" |
| |
| #include <string.h> |
| #include <tools/stream.hxx> |
| #include "xml_cdim.hxx" |
| #include <ctype.h> |
| |
| |
| typedef ComponentDescriptionImpl::ValueList CdiValueList; |
| |
| class dyn_buffer |
| { |
| public: |
| dyn_buffer() : s(0) {} |
| ~dyn_buffer() { if (s) delete [] s; } |
| operator const char *() const { return s; } |
| char * operator->() { return s; } |
| char & operator[]( |
| INT32 ix ) { return s[ix]; } |
| void SetSize( |
| INT32 i_size ) { if (s) delete [] s; s = new char [i_size]; } |
| private: |
| char * s; |
| }; |
| |
| |
| inline BOOL |
| LoadXmlFile( dyn_buffer & o_rBuffer, |
| const UniString & i_sXmlFilePath ) |
| { |
| BOOL ret = TRUE; |
| SvFileStream aXmlFile; |
| |
| aXmlFile.Open(i_sXmlFilePath, STREAM_READ); |
| if (aXmlFile.GetErrorCode() != FSYS_ERR_OK) |
| ret = FALSE; |
| if (ret) |
| { |
| aXmlFile.Seek(STREAM_SEEK_TO_END); |
| INT32 nBufferSize = aXmlFile.Tell(); |
| o_rBuffer.SetSize(nBufferSize + 1); |
| o_rBuffer[nBufferSize] = '\0'; |
| aXmlFile.Seek(0); |
| if (aXmlFile.Read(o_rBuffer.operator->(), nBufferSize) == 0) |
| ret = FALSE; |
| } |
| |
| aXmlFile.Close(); |
| return ret; |
| } |
| |
| |
| |
| CompDescrsFromAnXmlFile::CompDescrsFromAnXmlFile() |
| : dpDescriptions(new std::vector< ComponentDescriptionImpl* >), |
| eStatus(not_yet_parsed) |
| { |
| dpDescriptions->reserve(3); |
| } |
| |
| CompDescrsFromAnXmlFile::~CompDescrsFromAnXmlFile() |
| { |
| Empty(); |
| delete dpDescriptions; |
| } |
| |
| |
| BOOL |
| CompDescrsFromAnXmlFile::Parse( const UniString & i_sXmlFilePath ) |
| { |
| dyn_buffer dpBuffer; |
| |
| if (! LoadXmlFile(dpBuffer,i_sXmlFilePath) ) |
| { |
| eStatus = cant_read_file; |
| return FALSE; |
| } |
| |
| const char * pTokenStart = 0; |
| const char * pBufferPosition = dpBuffer; |
| INT32 nTokenLength = 0; |
| BOOL bWithinElement = FALSE; |
| |
| CdiValueList * pCurTagData = 0; |
| ByteString sStatusValue; // Used only if a <Status ...> tag is found. |
| |
| |
| for ( ComponentDescriptionImpl::ParseUntilStartOfDescription(pBufferPosition); |
| pBufferPosition != 0; |
| ComponentDescriptionImpl::ParseUntilStartOfDescription(pBufferPosition) ) |
| { |
| ComponentDescriptionImpl * pCurCD = 0; |
| pCurCD = new ComponentDescriptionImpl; |
| dpDescriptions->push_back(pCurCD); |
| |
| for ( ; *pBufferPosition != '\0' && pCurCD != 0; ) |
| { |
| switch (*pBufferPosition) |
| { |
| case '<' : |
| if (! bWithinElement) |
| { |
| pCurTagData = pCurCD->GetBeginTag(sStatusValue, pBufferPosition); |
| if (pCurTagData != 0) |
| { |
| if (sStatusValue.Len () == 0) |
| { |
| // Start new token: |
| pTokenStart = pBufferPosition; |
| nTokenLength = 0; |
| bWithinElement = TRUE;; |
| } |
| else |
| { |
| // Status tag is already parsed: |
| pCurTagData->push_back(sStatusValue); |
| } // endif (sStatusValue.Length () == 0) |
| } |
| else if ( ComponentDescriptionImpl::CheckEndOfDescription(pBufferPosition) ) |
| { |
| pBufferPosition += ComponentDescriptionImpl::DescriptionEndTagSize(); |
| pCurCD = 0; |
| } |
| else |
| { |
| eStatus = inconsistent_file; |
| return FALSE; |
| } // endif (pCurTagData != 0) elseif() else |
| } |
| else if ( pCurTagData->MatchesEndTag(pBufferPosition) ) |
| { |
| // Finish token: |
| pBufferPosition += pCurTagData->EndTagLength(); |
| bWithinElement = FALSE; |
| |
| // Remove leading and trailing spaces: |
| while ( isspace(*pTokenStart) ) |
| { |
| pTokenStart++; |
| nTokenLength--; |
| } |
| while ( nTokenLength > 0 |
| && isspace(pTokenStart[nTokenLength-1]) ) |
| { |
| nTokenLength--; |
| } |
| // Add token to tag values list. |
| pCurTagData->push_back(ByteString(pTokenStart,nTokenLength)); |
| } |
| else |
| { |
| nTokenLength++; |
| ++pBufferPosition; |
| } // endif (!bWithinElement) else if () else |
| break; |
| default: |
| if (bWithinElement) |
| { |
| ++nTokenLength; |
| } |
| ++pBufferPosition; |
| } // end switch |
| } // end for |
| |
| if (bWithinElement) |
| { |
| eStatus = inconsistent_file; |
| return FALSE; |
| } |
| } // end for |
| |
| return TRUE; |
| } |
| |
| INT32 |
| CompDescrsFromAnXmlFile::NrOfDescriptions() const |
| { |
| return dpDescriptions->size(); |
| } |
| |
| const ComponentDescription & |
| CompDescrsFromAnXmlFile::operator[](INT32 i_nIndex) const |
| { |
| static const ComponentDescriptionImpl aNullDescr_; |
| return 0 <= i_nIndex && i_nIndex < dpDescriptions->size() |
| ? *(*dpDescriptions)[i_nIndex] |
| : aNullDescr_; |
| } |
| |
| void |
| CompDescrsFromAnXmlFile::Empty() |
| { |
| for ( std::vector< ComponentDescriptionImpl* >::iterator aIter = dpDescriptions->begin(); |
| aIter != dpDescriptions->end(); |
| ++aIter ) |
| { |
| delete *aIter; |
| } |
| dpDescriptions->erase( dpDescriptions->begin(), |
| dpDescriptions->end() ); |
| } |
| |
| |
| |