diff options
author | Daniel Wilhelm <daniel@wili.li> | 2014-04-18 17:01:29 +0200 |
---|---|---|
committer | Daniel Wilhelm <daniel@wili.li> | 2014-04-18 17:01:29 +0200 |
commit | 9a2a524f1e311853d08050be2dcdddc09ac7759a (patch) | |
tree | d8e4a24169fce88c2d89931d58514889a0bcb0ea /library | |
parent | 2.3 (diff) | |
download | FreeFileSync-9a2a524f1e311853d08050be2dcdddc09ac7759a.tar.gz FreeFileSync-9a2a524f1e311853d08050be2dcdddc09ac7759a.tar.bz2 FreeFileSync-9a2a524f1e311853d08050be2dcdddc09ac7759a.zip |
3.0
Diffstat (limited to 'library')
-rw-r--r-- | library/CustomGrid.cpp | 152 | ||||
-rw-r--r-- | library/CustomGrid.h | 20 | ||||
-rw-r--r-- | library/SyncDB.ico | bin | 0 -> 82726 bytes | |||
-rw-r--r-- | library/errorLogging.h | 58 | ||||
-rw-r--r-- | library/filter.cpp | 124 | ||||
-rw-r--r-- | library/filter.h | 49 | ||||
-rw-r--r-- | library/iconBuffer.cpp | 28 | ||||
-rw-r--r-- | library/iconBuffer.h | 36 | ||||
-rw-r--r-- | library/multithreading.cpp | 18 | ||||
-rw-r--r-- | library/processXml.cpp | 184 | ||||
-rw-r--r-- | library/processXml.h | 313 | ||||
-rw-r--r-- | library/resources.cpp | 7 | ||||
-rw-r--r-- | library/resources.h | 2 | ||||
-rw-r--r-- | library/statistics.cpp | 22 | ||||
-rw-r--r-- | library/tinyxml/tinystr.cpp | 116 | ||||
-rw-r--r-- | library/tinyxml/tinystr.h | 319 | ||||
-rw-r--r-- | library/tinyxml/tinyxml.cpp | 1942 | ||||
-rw-r--r-- | library/tinyxml/tinyxml.h | 1802 | ||||
-rw-r--r-- | library/tinyxml/tinyxmlerror.cpp | 53 | ||||
-rw-r--r-- | library/tinyxml/tinyxmlparser.cpp | 1660 |
20 files changed, 529 insertions, 6376 deletions
diff --git a/library/CustomGrid.cpp b/library/CustomGrid.cpp index e2384526..fdb26eb5 100644 --- a/library/CustomGrid.cpp +++ b/library/CustomGrid.cpp @@ -2,7 +2,9 @@ #include "../shared/systemConstants.h" #include "resources.h" #include <wx/dc.h> -#include "../algorithm.h" +//#include "../algorithm.h" +#include "../ui/util.h" +#include "../shared/stringConv.h" #include "resources.h" #include <typeinfo> #include "../ui/gridView.h" @@ -44,18 +46,18 @@ class CustomGridTable : public wxGridTableBase { public: CustomGridTable(int initialRows = 0, int initialCols = 0) : //note: initialRows/initialCols MUST match with GetNumberRows()/GetNumberCols() at initialization!!! - wxGridTableBase(), - COLOR_BLUE( 80, 110, 255), - COLOR_GREY( 212, 208, 200), - COLOR_CMP_RED( 249, 163, 165), - COLOR_CMP_BLUE( 144, 232, 246), - COLOR_CMP_GREEN( 147, 253, 159), - COLOR_SYNC_BLUE( 201, 203, 247), - COLOR_SYNC_GREEN(197, 248, 190), - COLOR_YELLOW( 247, 252, 62), - gridDataView(NULL), - lastNrRows(initialRows), - lastNrCols(initialCols) {} + wxGridTableBase(), + COLOR_BLUE( 80, 110, 255), + COLOR_GREY( 212, 208, 200), + COLOR_CMP_RED( 249, 163, 165), + COLOR_CMP_BLUE( 144, 232, 246), + COLOR_CMP_GREEN( 147, 253, 159), + COLOR_SYNC_BLUE( 201, 203, 247), + COLOR_SYNC_GREEN(197, 248, 190), + COLOR_YELLOW( 247, 252, 62), + gridDataView(NULL), + lastNrRows(initialRows), + lastNrCols(initialCols) {} virtual ~CustomGridTable() {} @@ -256,13 +258,13 @@ protected: switch (getTypeAtPos(col)) { case xmlAccess::FULL_PATH: - return dirObj->getFullName<side>().c_str(); + return zToWx(dirObj->getFullName<side>()); case xmlAccess::FILENAME: return wxEmptyString; case xmlAccess::REL_PATH: - return dirObj->getRelativeName<side>().c_str(); + return zToWx(dirObj->getRelativeName<side>()); case xmlAccess::DIRECTORY: - return dirObj->getBaseDirPf<side>().c_str(); + return zToWx(dirObj->getBaseDirPf<side>()); case xmlAccess::SIZE: //file size return _("<Directory>"); case xmlAccess::DATE: //date @@ -277,13 +279,13 @@ protected: switch (getTypeAtPos(col)) { case xmlAccess::FULL_PATH: - return fileObj->getFullName<side>().BeforeLast(globalFunctions::FILE_NAME_SEPARATOR).c_str(); + return zToWx(fileObj->getFullName<side>().BeforeLast(globalFunctions::FILE_NAME_SEPARATOR)); case xmlAccess::FILENAME: //filename - return fileObj->getShortName<side>().c_str(); + return zToWx(fileObj->getShortName<side>()); case xmlAccess::REL_PATH: //relative path - return fileObj->getParentRelativeName<side>().c_str(); + return zToWx(fileObj->getParentRelativeName()); case xmlAccess::DIRECTORY: - return fileObj->getBaseDirPf<side>().c_str(); + return zToWx(fileObj->getBaseDirPf<side>()); case xmlAccess::SIZE: //file size return FreeFileSync::includeNumberSeparator(fileObj->getFileSize<side>().ToString()); case xmlAccess::DATE: //date @@ -305,7 +307,7 @@ private: if (fsObj) { //mark filtered rows - if (!fsObj->selectedForSynchronization) + if (!fsObj->isActive()) return COLOR_BLUE; //mark directories else if (dynamic_cast<const DirMapping*>(fsObj) != NULL) @@ -364,8 +366,8 @@ class CustomGridTableMiddle : public CustomGridTable public: //middle grid is created (first wxWidgets internal call to GetNumberCols()) with one column CustomGridTableMiddle() : - CustomGridTable(0, GetNumberCols()), //attention: static binding to virtual GetNumberCols() in a Constructor! - syncPreviewActive(false) {} + CustomGridTable(0, GetNumberCols()), //attention: static binding to virtual GetNumberCols() in a Constructor! + syncPreviewActive(false) {} virtual int GetNumberCols() { @@ -383,7 +385,7 @@ public: if (fsObj) { if (syncPreviewActive) //synchronization preview - return getSymbol(getSyncOperation(*fsObj)); + return getSymbol(fsObj->getSyncOperation()); else return getSymbol(fsObj->getCategory()); } @@ -407,22 +409,25 @@ private: if (fsObj) { //mark filtered rows - if (!fsObj->selectedForSynchronization) + if (!fsObj->isActive()) return COLOR_BLUE; if (syncPreviewActive) //synchronization preview { - switch (fsObj->syncDir) + switch (fsObj->getSyncOperation()) //evaluate comparison result and sync direction { - case SYNC_DIR_LEFT: + case SO_CREATE_NEW_LEFT: + case SO_DELETE_LEFT: + case SO_OVERWRITE_LEFT: return COLOR_SYNC_BLUE; - case SYNC_DIR_RIGHT: + case SO_CREATE_NEW_RIGHT: + case SO_DELETE_RIGHT: + case SO_OVERWRITE_RIGHT: return COLOR_SYNC_GREEN; - case SYNC_DIR_NONE: - if (fsObj->getCategory() == FILE_CONFLICT) - return COLOR_YELLOW; - else - return *wxWHITE; + case SO_UNRESOLVED_CONFLICT: + return COLOR_YELLOW; + case SO_DO_NOTHING: + return *wxWHITE; } } else //comparison results view @@ -461,12 +466,12 @@ CustomGrid::CustomGrid(wxWindow *parent, const wxSize& size, long style, const wxString& name) : - wxGrid(parent, id, pos, size, style, name), - m_gridLeft(NULL), - m_gridMiddle(NULL), - m_gridRight(NULL), - isLeading(false), - m_marker(-1, ASCENDING) + wxGrid(parent, id, pos, size, style, name), + m_gridLeft(NULL), + m_gridMiddle(NULL), + m_gridRight(NULL), + isLeading(false), + m_marker(-1, ASCENDING) { //set color of selections wxColour darkBlue(40, 35, 140); @@ -535,7 +540,8 @@ void CustomGrid::DoPrepareDC(wxDC& dc) inline void moveCursorWhileSelecting(const int anchor, const int oldPos, const int newPos, wxGrid* grid) -{ //note: all positions are valid in this context! +{ + //note: all positions are valid in this context! grid->SetGridCursor( newPos, grid->GetGridCursorCol()); grid->MakeCellVisible(newPos, grid->GetGridCursorCol()); @@ -921,8 +927,8 @@ class GridCellRenderer : public wxGridCellStringRenderer { public: GridCellRenderer(CustomGridRim::LoadSuccess& loadIconSuccess, const CustomGridTableRim* gridDataTable) : - m_loadIconSuccess(loadIconSuccess), - m_gridDataTable(gridDataTable) {} + m_loadIconSuccess(loadIconSuccess), + m_gridDataTable(gridDataTable) {} virtual void Draw(wxGrid& grid, @@ -1038,9 +1044,9 @@ CustomGridRim::CustomGridRim(wxWindow *parent, const wxSize& size, long style, const wxString& name) : - CustomGrid(parent, id, pos, size, style, name) + CustomGrid(parent, id, pos, size, style, name) #ifdef FFS_WIN - , fileIconsAreEnabled(false) + , fileIconsAreEnabled(false) #endif {} @@ -1126,7 +1132,8 @@ void CustomGridRim::setColumnAttributes(const xmlAccess::ColumnAttributes& attr) columnSettings.clear(); if (attr.size() == 0) - { //default settings: + { + //default settings: columnSettings = getDefaultColumnAttributes(); } else @@ -1215,7 +1222,8 @@ wxString CustomGridRim::getTypeName(xmlAccess::ColumnTypes colType) CustomGridTableRim* CustomGridRim::getGridDataTable() -{ //let the non-const call the const version: see Meyers Effective C++ +{ + //let the non-const call the const version: see Meyers Effective C++ return const_cast<CustomGridTableRim*>(static_cast<const CustomGridRim*>(this)->getGridDataTable()); } @@ -1314,9 +1322,9 @@ void CustomGridRim::getIconsToBeLoaded(std::vector<Zstring>& newLoad) //loads al //update file icons periodically: use SINGLE instance to coordinate left and right grid at once IconUpdater::IconUpdater(CustomGridLeft* leftGrid, CustomGridRight* rightGrid) : - m_leftGrid(leftGrid), - m_rightGrid(rightGrid), - m_timer(new wxTimer) //connect timer event for async. icon loading + m_leftGrid(leftGrid), + m_rightGrid(rightGrid), + m_timer(new wxTimer) //connect timer event for async. icon loading { m_timer->Connect(wxEVT_TIMER, wxEventHandler(IconUpdater::loadIconsAsynchronously), NULL, this); m_timer->Start(50); //timer interval in ms @@ -1349,8 +1357,8 @@ CustomGridLeft::CustomGridLeft(wxWindow *parent, const wxSize& size, long style, const wxString& name) : - CustomGridRim(parent, id, pos, size, style, name), - gridDataTable(NULL) {} + CustomGridRim(parent, id, pos, size, style, name), + gridDataTable(NULL) {} bool CustomGridLeft::CreateGrid(int numRows, int numCols, wxGrid::wxGridSelectionModes selmode) @@ -1396,8 +1404,8 @@ CustomGridRight::CustomGridRight(wxWindow *parent, const wxSize& size, long style, const wxString& name) : - CustomGridRim(parent, id, pos, size, style, name), - gridDataTable(NULL) {} + CustomGridRim(parent, id, pos, size, style, name), + gridDataTable(NULL) {} bool CustomGridRight::CreateGrid(int numRows, int numCols, wxGrid::wxGridSelectionModes selmode) @@ -1471,13 +1479,13 @@ CustomGridMiddle::CustomGridMiddle(wxWindow *parent, const wxSize& size, long style, const wxString& name) : - CustomGrid(parent, id, pos, size, style, name), - selectionRowBegin(-1), - selectionPos(BLOCKPOS_CHECK_BOX), - highlightedRow(-1), - highlightedPos(BLOCKPOS_CHECK_BOX), - gridDataTable(NULL), - toolTip(new CustomTooltip) + CustomGrid(parent, id, pos, size, style, name), + selectionRowBegin(-1), + selectionPos(BLOCKPOS_CHECK_BOX), + highlightedRow(-1), + highlightedPos(BLOCKPOS_CHECK_BOX), + gridDataTable(NULL), + toolTip(new CustomTooltip) { //connect events for dynamic selection of sync direction GetGridWindow()->Connect(wxEVT_MOTION, wxMouseEventHandler(CustomGridMiddle::OnMouseMovement), NULL, this); @@ -1564,7 +1572,7 @@ void CustomGridMiddle::showToolTip(int rowNumber, wxPoint pos) if (gridDataTable->syncPreviewIsActive()) //synchronization preview { - const SyncOperation syncOp = getSyncOperation(*fsObj); + const SyncOperation syncOp = fsObj->getSyncOperation(); switch (syncOp) { case SO_CREATE_NEW_LEFT: @@ -1589,7 +1597,7 @@ void CustomGridMiddle::showToolTip(int rowNumber, wxPoint pos) toolTip->show(getDescription(syncOp), pos, GlobalResources::getInstance().bitmapSyncDirNoneAct); break; case SO_UNRESOLVED_CONFLICT: - toolTip->show(fsObj->getConflictDescription(), pos, GlobalResources::getInstance().bitmapConflictAct); + toolTip->show(fsObj->getSyncOpConflict(), pos, GlobalResources::getInstance().bitmapConflictAct); break; }; } @@ -1617,7 +1625,7 @@ void CustomGridMiddle::showToolTip(int rowNumber, wxPoint pos) toolTip->show(getDescription(cmpRes), pos, GlobalResources::getInstance().bitmapEqualAct); break; case FILE_CONFLICT: - toolTip->show(fsObj->getConflictDescription(), pos, GlobalResources::getInstance().bitmapConflictAct); + toolTip->show(fsObj->getCatConflict(), pos, GlobalResources::getInstance().bitmapConflictAct); break; } } @@ -1761,13 +1769,13 @@ void GridCellRendererMiddle::Draw(wxGrid& grid, //HIGHLIGHTNING: if (rowIsHighlighted && m_gridMiddle->highlightedPos == CustomGridMiddle::BLOCKPOS_CHECK_BOX) { - if (fsObj->selectedForSynchronization) + if (fsObj->isActive()) dc.DrawLabel(wxEmptyString, *GlobalResources::getInstance().bitmapCheckBoxTrueFocus, rectShrinked, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); else dc.DrawLabel(wxEmptyString, *GlobalResources::getInstance().bitmapCheckBoxFalseFocus, rectShrinked, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); } //default - else if (fsObj->selectedForSynchronization) + else if (fsObj->isActive()) dc.DrawLabel(wxEmptyString, *GlobalResources::getInstance().bitmapCheckBoxTrue, rectShrinked, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); else dc.DrawLabel(wxEmptyString, *GlobalResources::getInstance().bitmapCheckBoxFalse, rectShrinked, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); @@ -1789,18 +1797,18 @@ void GridCellRendererMiddle::Draw(wxGrid& grid, case CustomGridMiddle::BLOCKPOS_CHECK_BOX: break; case CustomGridMiddle::BLOCKPOS_LEFT: - dc.DrawLabel(wxEmptyString, getSyncOpImage(fsObj->getCategory(), true, SYNC_DIR_LEFT), rectShrinked, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + dc.DrawLabel(wxEmptyString, getSyncOpImage(fsObj->testSyncOperation(true, SYNC_DIR_LEFT)), rectShrinked, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); break; case CustomGridMiddle::BLOCKPOS_MIDDLE: - dc.DrawLabel(wxEmptyString, getSyncOpImage(fsObj->getCategory(), true, SYNC_DIR_NONE), rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL); + dc.DrawLabel(wxEmptyString, getSyncOpImage(fsObj->testSyncOperation(true, SYNC_DIR_NONE)), rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL); break; case CustomGridMiddle::BLOCKPOS_RIGHT: - dc.DrawLabel(wxEmptyString, getSyncOpImage(fsObj->getCategory(), true, SYNC_DIR_RIGHT), rectShrinked, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL); + dc.DrawLabel(wxEmptyString, getSyncOpImage(fsObj->testSyncOperation(true, SYNC_DIR_RIGHT)), rectShrinked, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL); break; } else //default { - const wxBitmap& syncOpIcon = getSyncOpImage(fsObj->getCategory(), fsObj->selectedForSynchronization, fsObj->syncDir); + const wxBitmap& syncOpIcon = getSyncOpImage(fsObj->getSyncOperation()); dc.DrawLabel(wxEmptyString, syncOpIcon, rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL); } } @@ -1865,11 +1873,9 @@ void CustomGridMiddle::DrawColLabel(wxDC& dc, int col) } -const wxBitmap& FreeFileSync::getSyncOpImage(const CompareFilesResult cmpResult, - const bool selectedForSynchronization, - const SyncDirection syncDir) +const wxBitmap& FreeFileSync::getSyncOpImage(SyncOperation syncOp) { - switch (getSyncOperation(cmpResult, selectedForSynchronization, syncDir)) //evaluate comparison result and sync direction + switch (syncOp) //evaluate comparison result and sync direction { case SO_CREATE_NEW_LEFT: return *GlobalResources::getInstance().bitmapCreateLeftSmall; diff --git a/library/CustomGrid.h b/library/CustomGrid.h index 08ec5f55..59bc97c0 100644 --- a/library/CustomGrid.h +++ b/library/CustomGrid.h @@ -23,11 +23,9 @@ class CustomGridRight; namespace FreeFileSync { - class GridView; +class GridView; - const wxBitmap& getSyncOpImage(const CompareFilesResult cmpResult, - const bool selectedForSynchronization, - const SyncDirection syncDir); +const wxBitmap& getSyncOpImage(SyncOperation syncOp); } //################################################################################## @@ -299,9 +297,9 @@ class FFSCheckRowsEvent : public wxCommandEvent { public: FFSCheckRowsEvent(const int from, const int to) : - wxCommandEvent(FFS_CHECK_ROWS_EVENT), - rowFrom(from), - rowTo(to) {} + wxCommandEvent(FFS_CHECK_ROWS_EVENT), + rowFrom(from), + rowTo(to) {} virtual wxEvent* Clone() const { @@ -326,10 +324,10 @@ class FFSSyncDirectionEvent : public wxCommandEvent { public: FFSSyncDirectionEvent(const int from, const int to, const FreeFileSync::SyncDirection dir) : - wxCommandEvent(FFS_SYNC_DIRECTION_EVENT), - rowFrom(from), - rowTo(to), - direction(dir) {} + wxCommandEvent(FFS_SYNC_DIRECTION_EVENT), + rowFrom(from), + rowTo(to), + direction(dir) {} virtual wxEvent* Clone() const { diff --git a/library/SyncDB.ico b/library/SyncDB.ico Binary files differnew file mode 100644 index 00000000..e70a3a16 --- /dev/null +++ b/library/SyncDB.ico diff --git a/library/errorLogging.h b/library/errorLogging.h index 5fc5dacd..7b2b32c1 100644 --- a/library/errorLogging.h +++ b/library/errorLogging.h @@ -8,36 +8,36 @@ class Zstring; namespace FreeFileSync { - class ErrorLogging +class ErrorLogging +{ +public: + ErrorLogging() : errorCount(0) {} + + void logError(const wxString& errorMessage); + void logWarning(const wxString& warningMessage); + void logInfo(const wxString& infoMessage); + + int errorsTotal() + { + return errorCount; + } + + const std::vector<wxString>& getFormattedMessages() { - public: - ErrorLogging() : errorCount(0) {} - - void logError(const wxString& errorMessage); - void logWarning(const wxString& warningMessage); - void logInfo(const wxString& infoMessage); - - int errorsTotal() - { - return errorCount; - } - - const std::vector<wxString>& getFormattedMessages() - { - return formattedMessages; - } - - size_t messageCount() - { - return formattedMessages.size(); - } - - private: - wxString assembleMessage(const wxString& prefix, const wxString& message); - - std::vector<wxString> formattedMessages; //list of non-resolved errors and warnings - int errorCount; - }; + return formattedMessages; + } + + size_t messageCount() + { + return formattedMessages.size(); + } + +private: + wxString assembleMessage(const wxString& prefix, const wxString& message); + + std::vector<wxString> formattedMessages; //list of non-resolved errors and warnings + int errorCount; +}; } #endif // ERRORLOGGING_H_INCLUDED diff --git a/library/filter.cpp b/library/filter.cpp index 30cd9341..c2d972d4 100644 --- a/library/filter.cpp +++ b/library/filter.cpp @@ -22,14 +22,16 @@ void addFilterEntry(const Zstring& filtername, std::set<Zstring>& fileFilter, st //Linux DOES distinguish between upper/lower-case: nothing to do here #endif - static const Zstring sepAsterisk = Zstring() + globalFunctions::FILE_NAME_SEPARATOR + wxT('*'); - static const Zstring sepQuestionMark = Zstring() + globalFunctions::FILE_NAME_SEPARATOR + wxT('?'); - static const Zstring asteriskSep = Zstring(wxT("*")) + globalFunctions::FILE_NAME_SEPARATOR; - static const Zstring questionMarkSep = Zstring(wxT("?")) + globalFunctions::FILE_NAME_SEPARATOR; + static const Zstring sepAsterisk = Zstring() + globalFunctions::FILE_NAME_SEPARATOR + DefaultChar('*'); + static const Zstring sepQuestionMark = Zstring() + globalFunctions::FILE_NAME_SEPARATOR + DefaultChar('?'); + static const Zstring asteriskSep = Zstring(DefaultStr("*")) + globalFunctions::FILE_NAME_SEPARATOR; + static const Zstring questionMarkSep = Zstring(DefaultStr("?")) + globalFunctions::FILE_NAME_SEPARATOR; +//-------------------------------------------------------------------------------------------------- //add some syntactic sugar: handle beginning of filtername if (filterFormatted.StartsWith(globalFunctions::FILE_NAME_SEPARATOR)) - { //remove leading separators (keep BEFORE test for Zstring::empty()!) + { + //remove leading separators (keep BEFORE test for Zstring::empty()!) filterFormatted = filterFormatted.AfterFirst(globalFunctions::FILE_NAME_SEPARATOR); } else if (filterFormatted.StartsWith(asteriskSep) || // *\abc @@ -38,7 +40,7 @@ void addFilterEntry(const Zstring& filtername, std::set<Zstring>& fileFilter, st addFilterEntry(Zstring(filterFormatted.c_str() + 1), fileFilter, directoryFilter); //prevent further recursion by prefix } - +//-------------------------------------------------------------------------------------------------- //even more syntactic sugar: handle end of filtername if (filterFormatted.EndsWith(globalFunctions::FILE_NAME_SEPARATOR)) { @@ -150,14 +152,14 @@ std::vector<Zstring> compoundStringToFilter(const Zstring& filterString) //############################################################## -FilterProcess::FilterProcess(const wxString& includeFilter, const wxString& excludeFilter) +FilterProcess::FilterProcess(const Zstring& includeFilter, const Zstring& excludeFilter) { //no need for regular expressions! In tests wxRegex was by factor of 10 slower than wxString::Matches()!! //load filter into vectors of strings //delimiters may be ';' or '\n' - const std::vector<Zstring> includeList = compoundStringToFilter(includeFilter.c_str()); - const std::vector<Zstring> excludeList = compoundStringToFilter(excludeFilter.c_str()); + const std::vector<Zstring> includeList = compoundStringToFilter(includeFilter); + const std::vector<Zstring> excludeList = compoundStringToFilter(excludeFilter); //setup include/exclude filters for files and directories std::for_each(includeList.begin(), includeList.end(), boost::bind(addFilterEntry, _1, boost::ref(filterFileIn), boost::ref(filterFolderIn))); @@ -199,101 +201,110 @@ bool FilterProcess::passDirFilter(const DefaultChar* relDirname, bool* subObjMig } -class FilterData +template <bool include> +class InOrExcludeAllRows { public: - FilterData(const FilterProcess& filterProcIn) : filterProc(filterProcIn) {} - - void operator()(FreeFileSync::FileMapping& fileObj) + void operator()(FreeFileSync::BaseDirMapping& baseDirectory) const //be careful with operator() to no get called by std::for_each! { - const Zstring relName = fileObj.isEmpty<FreeFileSync::LEFT_SIDE>() ? - fileObj.getRelativeName<FreeFileSync::RIGHT_SIDE>() : - fileObj.getRelativeName<FreeFileSync::LEFT_SIDE>(); - - fileObj.selectedForSynchronization = filterProc.passFileFilter(relName); + execute(baseDirectory); } - void operator()(FreeFileSync::DirMapping& dirObj) + void execute(FreeFileSync::HierarchyObject& hierObj) const //don't create ambiguity by replacing with operator() { - const Zstring relName = dirObj.isEmpty<FreeFileSync::LEFT_SIDE>() ? - dirObj.getRelativeName<FreeFileSync::RIGHT_SIDE>() : - dirObj.getRelativeName<FreeFileSync::LEFT_SIDE>(); + std::for_each(hierObj.subFiles.begin(), hierObj.subFiles.end(), *this); //files + std::for_each(hierObj.subDirs.begin(), hierObj.subDirs.end(), *this); //directories + } - bool subObjMightMatch = true; - dirObj.selectedForSynchronization = filterProc.passDirFilter(relName, &subObjMightMatch); +private: + template<typename Iterator, typename Function> + friend Function std::for_each(Iterator, Iterator, Function); - if (subObjMightMatch) //use same logic like directory traversing here: evaluate filter in subdirs only if objects could match - filterProc.filterAll(dirObj); //process sub-dirs/files - else - FilterProcess::setActiveStatus(false, dirObj); //exclude all files dirs in subfolders + void operator()(FreeFileSync::FileMapping& fileObj) const + { + fileObj.setActive(include); } -private: - const FilterProcess& filterProc; + void operator()(FreeFileSync::DirMapping& dirObj) const + { + dirObj.setActive(include); + execute(dirObj); //recursion + } }; -void FilterProcess::filterAll(FreeFileSync::HierarchyObject& baseDirectory) const +class FilterData { - //files - std::for_each(baseDirectory.subFiles.begin(), baseDirectory.subFiles.end(), FilterData(*this)); +public: + FilterData(const FilterProcess& filterProcIn) : filterProc(filterProcIn) {} - //directories - std::for_each(baseDirectory.subDirs.begin(), baseDirectory.subDirs.end(), FilterData(*this)); + void execute(FreeFileSync::HierarchyObject& hierObj) + { + //files + std::for_each(hierObj.subFiles.begin(), hierObj.subFiles.end(), *this); - //recursion happens in FilterData -} + //directories + std::for_each(hierObj.subDirs.begin(), hierObj.subDirs.end(), *this); + }; +private: + template<typename Iterator, typename Function> + friend Function std::for_each(Iterator, Iterator, Function); -template <bool include> -struct SetSelected -{ - void operator()(FreeFileSync::FileSystemObject& fsObj) const + + void operator()(FreeFileSync::FileMapping& fileObj) + { + fileObj.setActive(filterProc.passFileFilter(fileObj.getObjRelativeName())); + } + + void operator()(FreeFileSync::DirMapping& dirObj) { - fsObj.selectedForSynchronization = include; + bool subObjMightMatch = true; + dirObj.setActive(filterProc.passDirFilter(dirObj.getObjRelativeName(), &subObjMightMatch)); + + if (subObjMightMatch) //use same logic as within directory traversing here: evaluate filter in subdirs only if objects could match + execute(dirObj); //recursion + else + InOrExcludeAllRows<false>().execute(dirObj); //exclude all files dirs in subfolders } + + const FilterProcess& filterProc; }; -template <bool include> -void inOrExcludeAllRows(FreeFileSync::HierarchyObject& hierObj) +void FilterProcess::filterAll(FreeFileSync::HierarchyObject& baseDirectory) const { - //directories - std::for_each(hierObj.subDirs.begin(), hierObj.subDirs.end(), SetSelected<include>()); - //files - std::for_each(hierObj.subFiles.begin(), hierObj.subFiles.end(), SetSelected<include>()); - //recurse into sub-dirs - std::for_each(hierObj.subDirs.begin(), hierObj.subDirs.end(), inOrExcludeAllRows<include>); + FilterData(*this).execute(baseDirectory); } void FilterProcess::setActiveStatus(bool newStatus, FreeFileSync::FolderComparison& folderCmp) { if (newStatus) - std::for_each(folderCmp.begin(), folderCmp.end(), inOrExcludeAllRows<true>); //include all rows + std::for_each(folderCmp.begin(), folderCmp.end(), InOrExcludeAllRows<true>()); //include all rows else - std::for_each(folderCmp.begin(), folderCmp.end(), inOrExcludeAllRows<false>); //exclude all rows + std::for_each(folderCmp.begin(), folderCmp.end(), InOrExcludeAllRows<false>()); //exclude all rows } void FilterProcess::setActiveStatus(bool newStatus, FreeFileSync::FileSystemObject& fsObj) { - fsObj.selectedForSynchronization = newStatus; + fsObj.setActive(newStatus); DirMapping* dirObj = dynamic_cast<DirMapping*>(&fsObj); if (dirObj) //process subdirectories also! { if (newStatus) - inOrExcludeAllRows<true>(*dirObj); + InOrExcludeAllRows<true>().execute(*dirObj); else - inOrExcludeAllRows<false>(*dirObj); + InOrExcludeAllRows<false>().execute(*dirObj); } } const FilterProcess& FilterProcess::nullFilter() //filter equivalent to include '*', exclude '' { - static FilterProcess output(wxT("*"), wxEmptyString); + static FilterProcess output(DefaultStr("*"), Zstring()); return output; } @@ -329,4 +340,3 @@ bool FilterProcess::operator<(const FilterProcess& other) const return false; //vectors equal } - diff --git a/library/filter.h b/library/filter.h index 0adf81cd..45aff69b 100644 --- a/library/filter.h +++ b/library/filter.h @@ -1,7 +1,6 @@ #ifndef FFS_FILTER_H_INCLUDED #define FFS_FILTER_H_INCLUDED -#include <wx/string.h> #include "../shared/zstring.h" #include <set> #include "../fileHierarchy.h" @@ -9,30 +8,30 @@ namespace FreeFileSync { - class FilterProcess //relative filtering - { - public: - FilterProcess(const wxString& includeFilter, const wxString& excludeFilter); - - bool passFileFilter(const DefaultChar* relFilename) const; - bool passDirFilter(const DefaultChar* relDirname, bool* subObjMightMatch) const; //subObjMightMatch: file/dir in subdirectories could(!) match - //note: variable is only set if passDirFilter returns false! - void filterAll(HierarchyObject& baseDirectory) const; //filter complete data: files and dirs - - static void setActiveStatus(bool newStatus, FolderComparison& folderCmp); //activate or deactivate all rows - static void setActiveStatus(bool newStatus, FileSystemObject& fsObj); //activate or deactivate row - - static const FilterProcess& nullFilter(); //filter equivalent to include '*', exclude '' - bool operator==(const FilterProcess& other) const; - bool operator!=(const FilterProcess& other) const; - bool operator<(const FilterProcess& other) const; - - private: - std::set<Zstring> filterFileIn; - std::set<Zstring> filterFolderIn; - std::set<Zstring> filterFileEx; - std::set<Zstring> filterFolderEx; - }; +class FilterProcess //relative filtering +{ +public: + FilterProcess(const Zstring& includeFilter, const Zstring& excludeFilter); + + bool passFileFilter(const DefaultChar* relFilename) const; + bool passDirFilter(const DefaultChar* relDirname, bool* subObjMightMatch) const; //subObjMightMatch: file/dir in subdirectories could(!) match + //note: variable is only set if passDirFilter returns false! + void filterAll(HierarchyObject& baseDirectory) const; //filter complete data: files and dirs + + static void setActiveStatus(bool newStatus, FolderComparison& folderCmp); //activate or deactivate all rows + static void setActiveStatus(bool newStatus, FileSystemObject& fsObj); //activate or deactivate row: works recursively! + + static const FilterProcess& nullFilter(); //filter equivalent to include '*', exclude '' + bool operator==(const FilterProcess& other) const; + bool operator!=(const FilterProcess& other) const; + bool operator<(const FilterProcess& other) const; + +private: + std::set<Zstring> filterFileIn; + std::set<Zstring> filterFolderIn; + std::set<Zstring> filterFileEx; + std::set<Zstring> filterFolderEx; +}; } diff --git a/library/iconBuffer.cpp b/library/iconBuffer.cpp index cf21104e..2f1e2915 100644 --- a/library/iconBuffer.cpp +++ b/library/iconBuffer.cpp @@ -45,12 +45,12 @@ private: WorkerThread::WorkerThread(IconBuffer* iconBuff) : - wxThread(wxTHREAD_JOINABLE), - threadHasMutex(false), - threadExitIsRequested(false), - threadIsListening(), - continueWork(threadIsListening), - iconBuffer(iconBuff) + wxThread(wxTHREAD_JOINABLE), + threadHasMutex(false), + threadExitIsRequested(false), + threadIsListening(), + continueWork(threadIsListening), + iconBuffer(iconBuff) { if (Create() != wxTHREAD_NO_ERROR) throw std::runtime_error("Error creating icon buffer worker thread!"); @@ -98,7 +98,8 @@ wxThread::ExitCode WorkerThread::Entry() try { wxMutexLocker dummy(threadIsListening); //this lock needs to be called from WITHIN the thread => calling it from constructor(Main thread) would be useless - { //this mutex STAYS locked all the time except of continueWork.Wait()! + { + //this mutex STAYS locked all the time except of continueWork.Wait()! wxCriticalSectionLocker dummy2(lockWorkload); threadHasMutex = true; } @@ -117,7 +118,7 @@ wxThread::ExitCode WorkerThread::Entry() } catch (const std::exception& e) //exceptions must be catched per thread { - wxMessageBox(wxString::From8BitData(e.what()), _("An exception occured!"), wxOK | wxICON_ERROR); + wxMessageBox(wxString::FromAscii(e.what()), _("An exception occured!"), wxOK | wxICON_ERROR); return 0; } } @@ -162,7 +163,8 @@ void WorkerThread::doWork() SHGFI_ICON | SHGFI_SMALLICON) && fileInfo.hIcon != 0) //fix for weird error: SHGetFileInfo() might return successfully WITHOUT filling fileInfo.hIcon!! - { //bug report: https://sourceforge.net/tracker/?func=detail&aid=2768004&group_id=234430&atid=1093080 + { + //bug report: https://sourceforge.net/tracker/?func=detail&aid=2768004&group_id=234430&atid=1093080 wxIcon newIcon; //attention: wxIcon uses reference counting! newIcon.SetHICON(fileInfo.hIcon); @@ -198,10 +200,10 @@ IconBuffer& IconBuffer::getInstance() IconBuffer::IconBuffer() : - lockIconDB( new wxCriticalSection), - buffer( new IconDB), - bufSequence(new IconDbSequence), - worker( new WorkerThread(this)) //might throw exceptions! + lockIconDB( new wxCriticalSection), + buffer( new IconDB), + bufSequence(new IconDbSequence), + worker( new WorkerThread(this)) //might throw exceptions! {} diff --git a/library/iconBuffer.h b/library/iconBuffer.h index f62a2772..0604060e 100644 --- a/library/iconBuffer.h +++ b/library/iconBuffer.h @@ -18,34 +18,34 @@ class wxIcon; namespace FreeFileSync { - class IconBuffer - { - friend class ::WorkerThread; +class IconBuffer +{ + friend class ::WorkerThread; - public: - static IconBuffer& getInstance(); +public: + static IconBuffer& getInstance(); - bool requestIcon(const Zstring& fileName, wxIcon* icon = NULL); //returns false if icon is not in buffer - void setWorkload(const std::vector<Zstring>& load); //(re-)set new workload of icons to be retrieved; + bool requestIcon(const Zstring& fileName, wxIcon* icon = NULL); //returns false if icon is not in buffer + void setWorkload(const std::vector<Zstring>& load); //(re-)set new workload of icons to be retrieved; - static const int ICON_SIZE = 16; //size in pixel + static const int ICON_SIZE = 16; //size in pixel - private: - IconBuffer(); - ~IconBuffer(); +private: + IconBuffer(); + ~IconBuffer(); - //methods used by worker thread - void insertIntoBuffer(const DefaultChar* fileName, const wxIcon& icon); + //methods used by worker thread + void insertIntoBuffer(const DefaultChar* fileName, const wxIcon& icon); //---------------------- Shared Data ------------------------- - std::auto_ptr<wxCriticalSection> lockIconDB; - std::auto_ptr<IconDB> buffer; //use synchronisation when accessing this! + std::auto_ptr<wxCriticalSection> lockIconDB; + std::auto_ptr<IconDB> buffer; //use synchronisation when accessing this! //------------------------------------------------------------ - std::auto_ptr<IconDbSequence> bufSequence; //save sequence of buffer entry to delte olderst elements + std::auto_ptr<IconDbSequence> bufSequence; //save sequence of buffer entry to delte olderst elements - std::auto_ptr<WorkerThread> worker; - }; + std::auto_ptr<WorkerThread> worker; +}; } #endif // ICONBUFFER_H_INCLUDED diff --git a/library/multithreading.cpp b/library/multithreading.cpp index 899a426b..aea4821b 100644 --- a/library/multithreading.cpp +++ b/library/multithreading.cpp @@ -40,12 +40,12 @@ class WorkerThread : public wxThread public: WorkerThread(UpdateWhileExecuting* handler) : - wxThread(wxTHREAD_DETACHED), - readyToBeginProcessing(), - beginProcessing(readyToBeginProcessing), - threadIsInitialized(false), - threadExitIsRequested(false), - threadHandler(handler) + wxThread(wxTHREAD_DETACHED), + readyToBeginProcessing(), + beginProcessing(readyToBeginProcessing), + threadIsInitialized(false), + threadExitIsRequested(false), + threadHandler(handler) { } @@ -93,9 +93,9 @@ private: UpdateWhileExecuting::UpdateWhileExecuting() : - readyToReceiveResult(), - receivingResult(readyToReceiveResult), - workDone(false) + readyToReceiveResult(), + receivingResult(readyToReceiveResult), + workDone(false) { //mutex needs to be initially locked for condition receivingResult to work properly readyToReceiveResult.Lock(); diff --git a/library/processXml.cpp b/library/processXml.cpp index e49e0b35..b248cf62 100644 --- a/library/processXml.cpp +++ b/library/processXml.cpp @@ -5,12 +5,14 @@ #include "../shared/globalFunctions.h" #include "../shared/fileHandling.h" #include "../shared/standardPaths.h" +#include "../shared/stringConv.h" #ifdef FFS_WIN #include <wx/msw/wrapwin.h> //includes "windows.h" #endif using namespace FreeFileSync; +using namespace xmlAccess; //functionally needed!!! class FfsXmlParser : public xmlAccess::XmlParser @@ -161,17 +163,17 @@ bool readXmlElement(const std::string& name, const TiXmlElement* parent, Compare } -bool readXmlElement(const std::string& name, const TiXmlElement* parent, SyncDirectionCfg& output) +bool readXmlElement(const std::string& name, const TiXmlElement* parent, SyncDirection& output) { std::string dummy; if (xmlAccess::readXmlElement(name, parent, dummy)) { if (dummy == "left") - output = SYNC_DIR_CFG_LEFT; + output = SYNC_DIR_LEFT; else if (dummy == "right") - output = SYNC_DIR_CFG_RIGHT; + output = SYNC_DIR_RIGHT; else //treat all other input as "none" - output = SYNC_DIR_CFG_NONE; + output = SYNC_DIR_NONE; return true; } @@ -226,7 +228,7 @@ bool readXmlElement(const std::string& name, const TiXmlElement* parent, Zstring if (!xmlAccess::readXmlElement(name, parent, dummy)) return false; - output = dummy.c_str(); + output = wxToZ(dummy); return true; } @@ -254,15 +256,17 @@ void FfsXmlParser::readXmlAlternateConfig(const TiXmlElement& folderPair, Folder //########################################################### //alternate sync configuration - const TiXmlElement* syncConfig = TiXmlHandleConst(&folderPair).FirstChild("AlternateSyncConfig").ToElement(); - if (syncConfig) + const TiXmlElement* altSyncConfig = TiXmlHandleConst(&folderPair).FirstChild("AlternateSyncConfig").ToElement(); + if (altSyncConfig) { AlternateSyncConfig* altSyncCfg = new AlternateSyncConfig; enhPair.altSyncConfig.reset(altSyncCfg); - const TiXmlElement* syncDirections = TiXmlHandleConst(syncConfig).FirstChild("Synchronization").FirstChild("Directions").ToElement(); + const TiXmlElement* syncCfg = TiXmlHandleConst(altSyncConfig).FirstChild("Synchronization").ToElement(); + const TiXmlElement* syncDirections = TiXmlHandleConst(syncCfg).FirstChild("Directions").ToElement(); //read sync configuration + readXmlElementLogging("Automatic", syncCfg, altSyncCfg->syncConfiguration.automatic); readXmlElementLogging("LeftOnly", syncDirections, altSyncCfg->syncConfiguration.exLeftSideOnly); readXmlElementLogging("RightOnly", syncDirections, altSyncCfg->syncConfiguration.exRightSideOnly); readXmlElementLogging("LeftNewer", syncDirections, altSyncCfg->syncConfiguration.leftNewer); @@ -307,9 +311,11 @@ void FfsXmlParser::readXmlMainConfig(MainConfiguration& mainCfg) readXmlElementLogging("TraverseDirectorySymlinks", cmpSettings, mainCfg.hidden.traverseDirectorySymlinks); //########################################################### - const TiXmlElement* syncDirections = hRoot.FirstChild("MainConfig").FirstChild("Synchronization").FirstChild("Directions").ToElement(); + const TiXmlElement* syncCfg = hRoot.FirstChild("MainConfig").FirstChild("Synchronization").ToElement(); + const TiXmlElement* syncDirections = TiXmlHandleConst(syncCfg).FirstChild("Directions").ToElement(); //read sync configuration + readXmlElementLogging("Automatic", syncCfg, mainCfg.syncConfiguration.automatic); readXmlElementLogging("LeftOnly", syncDirections, mainCfg.syncConfiguration.exLeftSideOnly); readXmlElementLogging("RightOnly", syncDirections, mainCfg.syncConfiguration.exRightSideOnly); readXmlElementLogging("LeftNewer", syncDirections, mainCfg.syncConfiguration.leftNewer); @@ -350,6 +356,9 @@ void FfsXmlParser::readXmlMainConfig(MainConfiguration& mainCfg) readXmlElementLogging("Right", pairs, mainCfg.mainFolderPair.rightDirectory); pairs = pairs->NextSiblingElement(); } + else + logError("Pair"); + //read additional folder pairs mainCfg.additionalPairs.clear(); @@ -422,6 +431,8 @@ void FfsXmlParser::readXmlGlobalSettings(xmlAccess::XmlGlobalSettings& outputCfg //check for unresolved conflicts readXmlElementLogging("CheckForUnresolvedConflicts", optionalDialogs, outputCfg.optDialogs.warningUnresolvedConflicts); + readXmlElementLogging("CheckSyncDatabase", optionalDialogs, outputCfg.optDialogs.warningSyncDatabase); + readXmlElementLogging("PopupOnConfigChange", optionalDialogs, outputCfg.optDialogs.popupOnConfigChange); readXmlElementLogging("SummaryBeforeSync", optionalDialogs, outputCfg.optDialogs.showSummaryBeforeSync); @@ -450,7 +461,7 @@ void FfsXmlParser::readXmlGlobalSettings(xmlAccess::XmlGlobalSettings& outputCfg unsigned int colPos = 0; while (leftColumn) { - xmlAccess::ColumnAttrib newAttrib; + ColumnAttrib newAttrib; newAttrib.position = colPos++; readXmlAttributeLogging("Type", leftColumn, newAttrib.type); readXmlAttributeLogging("Visible", leftColumn, newAttrib.visible); @@ -466,7 +477,7 @@ void FfsXmlParser::readXmlGlobalSettings(xmlAccess::XmlGlobalSettings& outputCfg colPos = 0; while (rightColumn) { - xmlAccess::ColumnAttrib newAttrib; + ColumnAttrib newAttrib; newAttrib.position = colPos++; readXmlAttributeLogging("Type", rightColumn, newAttrib.type); readXmlAttributeLogging("Visible", rightColumn, newAttrib.visible); @@ -543,17 +554,17 @@ void addXmlElement(const std::string& name, const CompareVariant variant, TiXmlE } -void addXmlElement(const std::string& name, const SyncDirectionCfg value, TiXmlElement* parent) +void addXmlElement(const std::string& name, const SyncDirection value, TiXmlElement* parent) { switch (value) { - case SYNC_DIR_CFG_LEFT: + case SYNC_DIR_LEFT: xmlAccess::addXmlElement(name, std::string("left"), parent); break; - case SYNC_DIR_CFG_RIGHT: + case SYNC_DIR_RIGHT: xmlAccess::addXmlElement(name, std::string("right"), parent); break; - case SYNC_DIR_CFG_NONE: + case SYNC_DIR_NONE: xmlAccess::addXmlElement(name, std::string("none"), parent); break; } @@ -596,7 +607,7 @@ void addXmlElement(const std::string& name, const FreeFileSync::DeletionPolicy v void addXmlElement(const std::string& name, const Zstring& value, TiXmlElement* parent) { - xmlAccess::addXmlElement(name, wxString(value.c_str()), parent); + xmlAccess::addXmlElement(name, wxString(zToWx(value)), parent); } @@ -627,15 +638,17 @@ void writeXmlAlternateConfig(const FolderPairEnh& enhPair, TiXmlElement& parent) syncCfg->LinkEndChild(syncSettings); //write sync configuration + addXmlElement("Automatic", altSyncConfig->syncConfiguration.automatic, syncSettings); + TiXmlElement* syncDirections = new TiXmlElement("Directions"); syncSettings->LinkEndChild(syncDirections); - ::addXmlElement("LeftOnly", altSyncConfig->syncConfiguration.exLeftSideOnly, syncDirections); - ::addXmlElement("RightOnly", altSyncConfig->syncConfiguration.exRightSideOnly, syncDirections); - ::addXmlElement("LeftNewer", altSyncConfig->syncConfiguration.leftNewer, syncDirections); - ::addXmlElement("RightNewer", altSyncConfig->syncConfiguration.rightNewer, syncDirections); - ::addXmlElement("Different", altSyncConfig->syncConfiguration.different, syncDirections); - ::addXmlElement("Conflict", altSyncConfig->syncConfiguration.conflict, syncDirections); + addXmlElement("LeftOnly", altSyncConfig->syncConfiguration.exLeftSideOnly, syncDirections); + addXmlElement("RightOnly", altSyncConfig->syncConfiguration.exRightSideOnly, syncDirections); + addXmlElement("LeftNewer", altSyncConfig->syncConfiguration.leftNewer, syncDirections); + addXmlElement("RightNewer", altSyncConfig->syncConfiguration.rightNewer, syncDirections); + addXmlElement("Different", altSyncConfig->syncConfiguration.different, syncDirections); + addXmlElement("Conflict", altSyncConfig->syncConfiguration.conflict, syncDirections); TiXmlElement* miscSettings = new TiXmlElement("Miscellaneous"); @@ -643,7 +656,7 @@ void writeXmlAlternateConfig(const FolderPairEnh& enhPair, TiXmlElement& parent) //misc addXmlElement("DeletionPolicy", altSyncConfig->handleDeletion, miscSettings); - xmlAccess::addXmlElement("CustomDeletionFolder", altSyncConfig->customDeletionDirectory, miscSettings); + addXmlElement("CustomDeletionFolder", altSyncConfig->customDeletionDirectory, miscSettings); } //########################################################### @@ -655,8 +668,8 @@ void writeXmlAlternateConfig(const FolderPairEnh& enhPair, TiXmlElement& parent) newfolderPair->LinkEndChild(filterCfg); //write filter settings - xmlAccess::addXmlElement("Include", altFilter->includeFilter, filterCfg); - xmlAccess::addXmlElement("Exclude", altFilter->excludeFilter, filterCfg); + addXmlElement("Include", altFilter->includeFilter, filterCfg); + addXmlElement("Exclude", altFilter->excludeFilter, filterCfg); } } @@ -679,35 +692,37 @@ bool writeXmlMainConfig(const MainConfiguration& mainCfg, TiXmlDocument& doc) settings->LinkEndChild(cmpSettings); //write compare algorithm - ::addXmlElement("Variant", mainCfgLocal.compareVar, cmpSettings); + addXmlElement("Variant", mainCfgLocal.compareVar, cmpSettings); //max. allowed file time deviation - xmlAccess::addXmlElement("FileTimeTolerance", mainCfgLocal.hidden.fileTimeTolerance, cmpSettings); + addXmlElement("FileTimeTolerance", mainCfgLocal.hidden.fileTimeTolerance, cmpSettings); //traverse into symbolic links (to folders) - xmlAccess::addXmlElement("TraverseDirectorySymlinks", mainCfgLocal.hidden.traverseDirectorySymlinks, cmpSettings); + addXmlElement("TraverseDirectorySymlinks", mainCfgLocal.hidden.traverseDirectorySymlinks, cmpSettings); //########################################################### TiXmlElement* syncSettings = new TiXmlElement("Synchronization"); settings->LinkEndChild(syncSettings); //write sync configuration + addXmlElement("Automatic", mainCfgLocal.syncConfiguration.automatic, syncSettings); + TiXmlElement* syncDirections = new TiXmlElement("Directions"); syncSettings->LinkEndChild(syncDirections); - ::addXmlElement("LeftOnly", mainCfgLocal.syncConfiguration.exLeftSideOnly, syncDirections); - ::addXmlElement("RightOnly", mainCfgLocal.syncConfiguration.exRightSideOnly, syncDirections); - ::addXmlElement("LeftNewer", mainCfgLocal.syncConfiguration.leftNewer, syncDirections); - ::addXmlElement("RightNewer", mainCfgLocal.syncConfiguration.rightNewer, syncDirections); - ::addXmlElement("Different", mainCfgLocal.syncConfiguration.different, syncDirections); - ::addXmlElement("Conflict", mainCfgLocal.syncConfiguration.conflict, syncDirections); + addXmlElement("LeftOnly", mainCfgLocal.syncConfiguration.exLeftSideOnly, syncDirections); + addXmlElement("RightOnly", mainCfgLocal.syncConfiguration.exRightSideOnly, syncDirections); + addXmlElement("LeftNewer", mainCfgLocal.syncConfiguration.leftNewer, syncDirections); + addXmlElement("RightNewer", mainCfgLocal.syncConfiguration.rightNewer, syncDirections); + addXmlElement("Different", mainCfgLocal.syncConfiguration.different, syncDirections); + addXmlElement("Conflict", mainCfgLocal.syncConfiguration.conflict, syncDirections); //########################################################### //copy symbolic links to files - xmlAccess::addXmlElement("CopyFileSymlinks", mainCfgLocal.hidden.copyFileSymlinks, syncSettings); + addXmlElement("CopyFileSymlinks", mainCfgLocal.hidden.copyFileSymlinks, syncSettings); //verify file copying - xmlAccess::addXmlElement("VerifyCopiedFiles", mainCfgLocal.hidden.verifyFileCopy, syncSettings); + addXmlElement("VerifyCopiedFiles", mainCfgLocal.hidden.verifyFileCopy, syncSettings); //########################################################### TiXmlElement* miscSettings = new TiXmlElement("Miscellaneous"); @@ -717,13 +732,13 @@ bool writeXmlMainConfig(const MainConfiguration& mainCfg, TiXmlDocument& doc) TiXmlElement* filter = new TiXmlElement("Filter"); miscSettings->LinkEndChild(filter); - xmlAccess::addXmlElement("Active", mainCfgLocal.filterIsActive, filter); - xmlAccess::addXmlElement("Include", mainCfgLocal.includeFilter, filter); - xmlAccess::addXmlElement("Exclude", mainCfgLocal.excludeFilter, filter); + addXmlElement("Active", mainCfgLocal.filterIsActive, filter); + addXmlElement("Include", mainCfgLocal.includeFilter, filter); + addXmlElement("Exclude", mainCfgLocal.excludeFilter, filter); //other addXmlElement("DeletionPolicy", mainCfgLocal.handleDeletion, miscSettings); - xmlAccess::addXmlElement("CustomDeletionFolder", mainCfgLocal.customDeletionDirectory, miscSettings); + addXmlElement("CustomDeletionFolder", mainCfgLocal.customDeletionDirectory, miscSettings); //########################################################### TiXmlElement* pairs = new TiXmlElement("FolderPairs"); @@ -757,11 +772,11 @@ bool writeXmlGuiConfig(const xmlAccess::XmlGuiConfig& inputCfg, TiXmlDocument& d TiXmlElement* guiConfig = new TiXmlElement("GuiConfig"); root->LinkEndChild(guiConfig); - xmlAccess::addXmlElement("HideFiltered", inputCfg.hideFilteredElements, guiConfig); + addXmlElement("HideFiltered", inputCfg.hideFilteredElements, guiConfig); - ::addXmlElement("HandleError", inputCfg.ignoreErrors ? xmlAccess::ON_ERROR_IGNORE : xmlAccess::ON_ERROR_POPUP, guiConfig); + addXmlElement("HandleError", inputCfg.ignoreErrors ? xmlAccess::ON_ERROR_IGNORE : xmlAccess::ON_ERROR_POPUP, guiConfig); - xmlAccess::addXmlElement("SyncPreviewActive", inputCfg.syncPreviewEnabled, guiConfig); + addXmlElement("SyncPreviewActive", inputCfg.syncPreviewEnabled, guiConfig); return true; } @@ -780,9 +795,9 @@ bool writeXmlBatchConfig(const xmlAccess::XmlBatchConfig& inputCfg, TiXmlDocumen TiXmlElement* batchConfig = new TiXmlElement("BatchConfig"); root->LinkEndChild(batchConfig); - xmlAccess::addXmlElement("Silent", inputCfg.silent, batchConfig); - xmlAccess::addXmlElement("LogfileDirectory", inputCfg.logFileDirectory, batchConfig); - ::addXmlElement("HandleError", inputCfg.handleError, batchConfig); + addXmlElement("Silent", inputCfg.silent, batchConfig); + addXmlElement("LogfileDirectory", inputCfg.logFileDirectory, batchConfig); + addXmlElement("HandleError", inputCfg.handleError, batchConfig); return true; } @@ -799,13 +814,13 @@ bool writeXmlGlobalSettings(const xmlAccess::XmlGlobalSettings& inputCfg, TiXmlD root->LinkEndChild(global); //program language - xmlAccess::addXmlElement("Language", inputCfg.programLanguage, global); + addXmlElement("Language", inputCfg.programLanguage, global); //ignore +/- 1 hour due to DST change - xmlAccess::addXmlElement("IgnoreOneHourDifference", inputCfg.ignoreOneHourDiff, global); + addXmlElement("IgnoreOneHourDifference", inputCfg.ignoreOneHourDiff, global); //last update check - xmlAccess::addXmlElement("LastCheckForUpdates", inputCfg.lastUpdateCheck, global); + addXmlElement("LastCheckForUpdates", inputCfg.lastUpdateCheck, global); //optional dialogs @@ -813,20 +828,22 @@ bool writeXmlGlobalSettings(const xmlAccess::XmlGlobalSettings& inputCfg, TiXmlD global->LinkEndChild(optionalDialogs); //warning: dependent folders - xmlAccess::addXmlElement("CheckForDependentFolders", inputCfg.optDialogs.warningDependentFolders, optionalDialogs); + addXmlElement("CheckForDependentFolders", inputCfg.optDialogs.warningDependentFolders, optionalDialogs); //significant difference check - xmlAccess::addXmlElement("CheckForSignificantDifference", inputCfg.optDialogs.warningSignificantDifference, optionalDialogs); + addXmlElement("CheckForSignificantDifference", inputCfg.optDialogs.warningSignificantDifference, optionalDialogs); //check free disk space - xmlAccess::addXmlElement("CheckForFreeDiskSpace", inputCfg.optDialogs.warningNotEnoughDiskSpace, optionalDialogs); + addXmlElement("CheckForFreeDiskSpace", inputCfg.optDialogs.warningNotEnoughDiskSpace, optionalDialogs); //check for unresolved conflicts - xmlAccess::addXmlElement("CheckForUnresolvedConflicts", inputCfg.optDialogs.warningUnresolvedConflicts, optionalDialogs); + addXmlElement("CheckForUnresolvedConflicts", inputCfg.optDialogs.warningUnresolvedConflicts, optionalDialogs); + + addXmlElement("CheckSyncDatabase", inputCfg.optDialogs.warningSyncDatabase, optionalDialogs); - xmlAccess::addXmlElement("PopupOnConfigChange", inputCfg.optDialogs.popupOnConfigChange, optionalDialogs); + addXmlElement("PopupOnConfigChange", inputCfg.optDialogs.popupOnConfigChange, optionalDialogs); - xmlAccess::addXmlElement("SummaryBeforeSync", inputCfg.optDialogs.showSummaryBeforeSync, optionalDialogs); + addXmlElement("SummaryBeforeSync", inputCfg.optDialogs.showSummaryBeforeSync, optionalDialogs); //################################################################### @@ -841,54 +858,54 @@ bool writeXmlGlobalSettings(const xmlAccess::XmlGlobalSettings& inputCfg, TiXmlD windows->LinkEndChild(mainWindow); //window size - xmlAccess::addXmlElement("Width", inputCfg.gui.widthNotMaximized, mainWindow); - xmlAccess::addXmlElement("Height", inputCfg.gui.heightNotMaximized, mainWindow); + addXmlElement("Width", inputCfg.gui.widthNotMaximized, mainWindow); + addXmlElement("Height", inputCfg.gui.heightNotMaximized, mainWindow); //window position - xmlAccess::addXmlElement("PosX", inputCfg.gui.posXNotMaximized, mainWindow); - xmlAccess::addXmlElement("PosY", inputCfg.gui.posYNotMaximized, mainWindow); - xmlAccess::addXmlElement("Maximized", inputCfg.gui.isMaximized, mainWindow); + addXmlElement("PosX", inputCfg.gui.posXNotMaximized, mainWindow); + addXmlElement("PosY", inputCfg.gui.posYNotMaximized, mainWindow); + addXmlElement("Maximized", inputCfg.gui.isMaximized, mainWindow); - xmlAccess::addXmlElement("ManualDeletionOnBothSides", inputCfg.gui.deleteOnBothSides, mainWindow); - xmlAccess::addXmlElement("ManualDeletionUseRecycler", inputCfg.gui.useRecyclerForManualDeletion, mainWindow); - xmlAccess::addXmlElement("ShowFileIconsLeft", inputCfg.gui.showFileIconsLeft, mainWindow); - xmlAccess::addXmlElement("ShowFileIconsRight", inputCfg.gui.showFileIconsRight, mainWindow); + addXmlElement("ManualDeletionOnBothSides", inputCfg.gui.deleteOnBothSides, mainWindow); + addXmlElement("ManualDeletionUseRecycler", inputCfg.gui.useRecyclerForManualDeletion, mainWindow); + addXmlElement("ShowFileIconsLeft", inputCfg.gui.showFileIconsLeft, mainWindow); + addXmlElement("ShowFileIconsRight", inputCfg.gui.showFileIconsRight, mainWindow); //write column attributes TiXmlElement* leftColumn = new TiXmlElement("LeftColumns"); mainWindow->LinkEndChild(leftColumn); - xmlAccess::addXmlAttribute("AutoAdjust", inputCfg.gui.autoAdjustColumnsLeft, leftColumn); + addXmlAttribute("AutoAdjust", inputCfg.gui.autoAdjustColumnsLeft, leftColumn); - xmlAccess::ColumnAttributes columnAtrribLeftCopy = inputCfg.gui.columnAttribLeft; //can't change const vector + ColumnAttributes columnAtrribLeftCopy = inputCfg.gui.columnAttribLeft; //can't change const vector sort(columnAtrribLeftCopy.begin(), columnAtrribLeftCopy.end(), xmlAccess::sortByPositionOnly); for (unsigned int i = 0; i < columnAtrribLeftCopy.size(); ++i) { TiXmlElement* subElement = new TiXmlElement("Column"); leftColumn->LinkEndChild(subElement); - const xmlAccess::ColumnAttrib& colAttrib = columnAtrribLeftCopy[i]; + const ColumnAttrib& colAttrib = columnAtrribLeftCopy[i]; addXmlAttribute("Type", colAttrib.type, subElement); - xmlAccess::addXmlAttribute("Visible", colAttrib.visible, subElement); - xmlAccess::addXmlAttribute("Width", colAttrib.width, subElement); + addXmlAttribute("Visible", colAttrib.visible, subElement); + addXmlAttribute("Width", colAttrib.width, subElement); } TiXmlElement* rightColumn = new TiXmlElement("RightColumns"); mainWindow->LinkEndChild(rightColumn); - xmlAccess::addXmlAttribute("AutoAdjust", inputCfg.gui.autoAdjustColumnsRight, rightColumn); + addXmlAttribute("AutoAdjust", inputCfg.gui.autoAdjustColumnsRight, rightColumn); - xmlAccess::ColumnAttributes columnAtrribRightCopy = inputCfg.gui.columnAttribRight; + ColumnAttributes columnAtrribRightCopy = inputCfg.gui.columnAttribRight; sort(columnAtrribRightCopy.begin(), columnAtrribRightCopy.end(), xmlAccess::sortByPositionOnly); for (unsigned int i = 0; i < columnAtrribRightCopy.size(); ++i) { TiXmlElement* subElement = new TiXmlElement("Column"); rightColumn->LinkEndChild(subElement); - const xmlAccess::ColumnAttrib& colAttrib = columnAtrribRightCopy[i]; + const ColumnAttrib& colAttrib = columnAtrribRightCopy[i]; addXmlAttribute("Type", colAttrib.type, subElement); - xmlAccess::addXmlAttribute("Visible", colAttrib.visible, subElement); - xmlAccess::addXmlAttribute("Width", colAttrib.width, subElement); + addXmlAttribute("Visible", colAttrib.visible, subElement); + addXmlAttribute("Width", colAttrib.width, subElement); } //write folder history elements @@ -897,24 +914,24 @@ bool writeXmlGlobalSettings(const xmlAccess::XmlGlobalSettings& inputCfg, TiXmlD TiXmlElement* historyRight = new TiXmlElement("FolderHistoryRight"); mainWindow->LinkEndChild(historyRight); - xmlAccess::addXmlAttribute("MaximumSize", inputCfg.gui.folderHistLeftMax, historyLeft); - xmlAccess::addXmlAttribute("MaximumSize", inputCfg.gui.folderHistRightMax, historyRight); + addXmlAttribute("MaximumSize", inputCfg.gui.folderHistLeftMax, historyLeft); + addXmlAttribute("MaximumSize", inputCfg.gui.folderHistRightMax, historyRight); - xmlAccess::addXmlElement("Folder", inputCfg.gui.folderHistoryLeft, historyLeft); - xmlAccess::addXmlElement("Folder", inputCfg.gui.folderHistoryRight, historyRight); + addXmlElement("Folder", inputCfg.gui.folderHistoryLeft, historyLeft); + addXmlElement("Folder", inputCfg.gui.folderHistoryRight, historyRight); - xmlAccess::addXmlElement("SelectedTabBottomLeft", inputCfg.gui.selectedTabBottomLeft, mainWindow); + addXmlElement("SelectedTabBottomLeft", inputCfg.gui.selectedTabBottomLeft, mainWindow); //external applications TiXmlElement* extApp = new TiXmlElement("ExternalApplications"); gui->LinkEndChild(extApp); - for (xmlAccess::ExternalApps::const_iterator i = inputCfg.gui.externelApplications.begin(); i != inputCfg.gui.externelApplications.end(); ++i) + for (ExternalApps::const_iterator i = inputCfg.gui.externelApplications.begin(); i != inputCfg.gui.externelApplications.end(); ++i) { TiXmlElement* newEntry = new TiXmlElement("Commandline"); extApp->LinkEndChild(newEntry); - xmlAccess::addXmlAttribute("Description", i->first, newEntry); + addXmlAttribute("Description", i->first, newEntry); newEntry->LinkEndChild(new TiXmlText(i->second.ToUTF8())); //commandline } @@ -922,8 +939,8 @@ bool writeXmlGlobalSettings(const xmlAccess::XmlGlobalSettings& inputCfg, TiXmlD TiXmlElement* cfgHistory = new TiXmlElement("ConfigHistory"); gui->LinkEndChild(cfgHistory); - xmlAccess::addXmlAttribute("MaximumSize", inputCfg.gui.cfgHistoryMax, cfgHistory); - xmlAccess::addXmlElement("File", inputCfg.gui.cfgFileHistory, cfgHistory); + addXmlAttribute("MaximumSize", inputCfg.gui.cfgHistoryMax, cfgHistory); + addXmlElement("File", inputCfg.gui.cfgFileHistory, cfgHistory); //################################################################### //write global batch settings @@ -953,6 +970,7 @@ void xmlAccess::OptionalDialogs::resetDialogs() warningSignificantDifference = true; warningNotEnoughDiskSpace = true; warningUnresolvedConflicts = true; + warningSyncDatabase = true; popupOnConfigChange = true; showSummaryBeforeSync = true; } diff --git a/library/processXml.h b/library/processXml.h index 868b859b..aafd3131 100644 --- a/library/processXml.h +++ b/library/processXml.h @@ -2,214 +2,217 @@ #define PROCESSXML_H_INCLUDED #include "../structures.h" +#include <wx/intl.h> namespace xmlAccess { - enum OnError - { - ON_ERROR_POPUP, - ON_ERROR_IGNORE, - ON_ERROR_EXIT - }; +enum OnError +{ + ON_ERROR_POPUP, + ON_ERROR_IGNORE, + ON_ERROR_EXIT +}; - enum ColumnTypes - { - DIRECTORY, - FULL_PATH, - REL_PATH, - FILENAME, - SIZE, - DATE - }; - const unsigned int COLUMN_TYPE_COUNT = 6; - - struct ColumnAttrib - { - ColumnTypes type; - bool visible; - unsigned int position; - int width; - }; - typedef std::vector<ColumnAttrib> ColumnAttributes; +enum ColumnTypes +{ + DIRECTORY, + FULL_PATH, + REL_PATH, + FILENAME, + SIZE, + DATE +}; +const unsigned int COLUMN_TYPE_COUNT = 6; + +struct ColumnAttrib +{ + ColumnTypes type; + bool visible; + unsigned int position; + int width; +}; +typedef std::vector<ColumnAttrib> ColumnAttributes; - typedef wxString Description; - typedef wxString Commandline; - typedef std::vector<std::pair<Description, Commandline> > ExternalApps; +typedef wxString Description; +typedef wxString Commandline; +typedef std::vector<std::pair<Description, Commandline> > ExternalApps; //--------------------------------------------------------------------- - struct XmlGuiConfig - { - XmlGuiConfig() : - hideFilteredElements(false), - ignoreErrors(false), - syncPreviewEnabled(true) {} //initialize values +struct XmlGuiConfig +{ + XmlGuiConfig() : + hideFilteredElements(false), + ignoreErrors(false), + syncPreviewEnabled(true) {} //initialize values - FreeFileSync::MainConfiguration mainCfg; + FreeFileSync::MainConfiguration mainCfg; - bool hideFilteredElements; - bool ignoreErrors; //reaction on error situation during synchronization - bool syncPreviewEnabled; + bool hideFilteredElements; + bool ignoreErrors; //reaction on error situation during synchronization + bool syncPreviewEnabled; - bool operator==(const XmlGuiConfig& other) const - { - return mainCfg == other.mainCfg && - hideFilteredElements == other.hideFilteredElements && - ignoreErrors == other.ignoreErrors && - syncPreviewEnabled == other.syncPreviewEnabled; - } + bool operator==(const XmlGuiConfig& other) const + { + return mainCfg == other.mainCfg && + hideFilteredElements == other.hideFilteredElements && + ignoreErrors == other.ignoreErrors && + syncPreviewEnabled == other.syncPreviewEnabled; + } - bool operator!=(const XmlGuiConfig& other) const - { - return !(*this == other); - } - }; + bool operator!=(const XmlGuiConfig& other) const + { + return !(*this == other); + } +}; - struct XmlBatchConfig - { - XmlBatchConfig() : silent(false), handleError(ON_ERROR_POPUP) {} +struct XmlBatchConfig +{ + XmlBatchConfig() : silent(false), handleError(ON_ERROR_POPUP) {} - FreeFileSync::MainConfiguration mainCfg; + FreeFileSync::MainConfiguration mainCfg; - bool silent; - OnError handleError; //reaction on error situation during synchronization - wxString logFileDirectory; // - }; + bool silent; + OnError handleError; //reaction on error situation during synchronization + wxString logFileDirectory; // +}; - int retrieveSystemLanguage(); - bool recycleBinAvailable(); +int retrieveSystemLanguage(); +bool recycleBinAvailable(); - struct OptionalDialogs +struct OptionalDialogs +{ + OptionalDialogs() { - OptionalDialogs() - { - resetDialogs(); - } + resetDialogs(); + } - void resetDialogs(); + void resetDialogs(); - bool warningDependentFolders; - bool warningSignificantDifference; - bool warningNotEnoughDiskSpace; - bool warningUnresolvedConflicts; - bool popupOnConfigChange; - bool showSummaryBeforeSync; - }; + bool warningDependentFolders; + bool warningSignificantDifference; + bool warningNotEnoughDiskSpace; + bool warningUnresolvedConflicts; + bool warningSyncDatabase; + bool popupOnConfigChange; + bool showSummaryBeforeSync; +}; - struct XmlGlobalSettings - { +struct XmlGlobalSettings +{ //--------------------------------------------------------------------- - //Shared (GUI/BATCH) settings - XmlGlobalSettings() : - programLanguage(retrieveSystemLanguage()), - ignoreOneHourDiff(false), - lastUpdateCheck(0) {} + //Shared (GUI/BATCH) settings + XmlGlobalSettings() : + programLanguage(retrieveSystemLanguage()), + ignoreOneHourDiff(false), + lastUpdateCheck(0) {} - int programLanguage; - bool ignoreOneHourDiff; //ignore +/- 1 hour due to DST change - long lastUpdateCheck; //time of last update check + int programLanguage; + bool ignoreOneHourDiff; //ignore +/- 1 hour due to DST change + long lastUpdateCheck; //time of last update check - OptionalDialogs optDialogs; + OptionalDialogs optDialogs; //--------------------------------------------------------------------- - struct _Gui + struct _Gui + { + _Gui() : + widthNotMaximized(wxDefaultCoord), + heightNotMaximized(wxDefaultCoord), + posXNotMaximized(wxDefaultCoord), + posYNotMaximized(wxDefaultCoord), + isMaximized(false), + autoAdjustColumnsLeft(false), + autoAdjustColumnsRight(false), + cfgHistoryMax(10), + folderHistLeftMax(12), + folderHistRightMax(12), + selectedTabBottomLeft(0), + deleteOnBothSides(false), + useRecyclerForManualDeletion(recycleBinAvailable()), //enable if OS supports it; else user will have to activate first and then get an error message + showFileIconsLeft(true), + showFileIconsRight(true) { - _Gui() : - widthNotMaximized(wxDefaultCoord), - heightNotMaximized(wxDefaultCoord), - posXNotMaximized(wxDefaultCoord), - posYNotMaximized(wxDefaultCoord), - isMaximized(false), - autoAdjustColumnsLeft(false), - autoAdjustColumnsRight(false), - cfgHistoryMax(10), - folderHistLeftMax(12), - folderHistRightMax(12), - selectedTabBottomLeft(0), - deleteOnBothSides(false), - useRecyclerForManualDeletion(recycleBinAvailable()), //enable if OS supports it; else user will have to activate first and then get an error message - showFileIconsLeft(true), - showFileIconsRight(true) - { #ifdef FFS_WIN - externelApplications.push_back(std::make_pair(wxT("Open with Explorer"), wxT("explorer /select, %name"))); + externelApplications.push_back(std::make_pair(_("Open with Explorer"), wxT("explorer /select, %name"))); + externelApplications.push_back(std::make_pair(_("Open directly"), wxT("cmd /c start \"\" \"%name\""))); #elif defined FFS_LINUX - externelApplications.push_back(std::make_pair(wxT("Open with Konqueror"), wxT("konqueror \"%dir\""))); + externelApplications.push_back(std::make_pair(_("Open with Konqueror"), wxT("konqueror \"%dir\""))); #endif - } + } - int widthNotMaximized; - int heightNotMaximized; - int posXNotMaximized; - int posYNotMaximized; - bool isMaximized; + int widthNotMaximized; + int heightNotMaximized; + int posXNotMaximized; + int posYNotMaximized; + bool isMaximized; - ColumnAttributes columnAttribLeft; - ColumnAttributes columnAttribRight; + ColumnAttributes columnAttribLeft; + ColumnAttributes columnAttribRight; - bool autoAdjustColumnsLeft; - bool autoAdjustColumnsRight; + bool autoAdjustColumnsLeft; + bool autoAdjustColumnsRight; - ExternalApps externelApplications; + ExternalApps externelApplications; - std::vector<wxString> cfgFileHistory; - unsigned int cfgHistoryMax; + std::vector<wxString> cfgFileHistory; + unsigned int cfgHistoryMax; - std::vector<wxString> folderHistoryLeft; - unsigned int folderHistLeftMax; + std::vector<wxString> folderHistoryLeft; + unsigned int folderHistLeftMax; - std::vector<wxString> folderHistoryRight; - unsigned int folderHistRightMax; + std::vector<wxString> folderHistoryRight; + unsigned int folderHistRightMax; - int selectedTabBottomLeft; + int selectedTabBottomLeft; - bool deleteOnBothSides; - bool useRecyclerForManualDeletion; - bool showFileIconsLeft; - bool showFileIconsRight; - } gui; + bool deleteOnBothSides; + bool useRecyclerForManualDeletion; + bool showFileIconsLeft; + bool showFileIconsRight; + } gui; //--------------------------------------------------------------------- - //struct _Batch - }; + //struct _Batch +}; - inline - bool sortByType(const ColumnAttrib& a, const ColumnAttrib& b) - { - return a.type < b.type; - } +inline +bool sortByType(const ColumnAttrib& a, const ColumnAttrib& b) +{ + return a.type < b.type; +} - inline - bool sortByPositionOnly(const ColumnAttrib& a, const ColumnAttrib& b) - { - return a.position < b.position; - } +inline +bool sortByPositionOnly(const ColumnAttrib& a, const ColumnAttrib& b) +{ + return a.position < b.position; +} - inline - bool sortByPositionAndVisibility(const ColumnAttrib& a, const ColumnAttrib& b) - { - if (a.visible == false) //hidden elements shall appear at end of vector - return false; - if (b.visible == false) - return true; - return a.position < b.position; - } +inline +bool sortByPositionAndVisibility(const ColumnAttrib& a, const ColumnAttrib& b) +{ + if (a.visible == false) //hidden elements shall appear at end of vector + return false; + if (b.visible == false) + return true; + return a.position < b.position; +} - void readGuiConfig( const wxString& filename, XmlGuiConfig& config); //throw (xmlAccess::XmlError); - void readBatchConfig(const wxString& filename, XmlBatchConfig& config); //throw (xmlAccess::XmlError); - void readGlobalSettings( XmlGlobalSettings& config); //throw (xmlAccess::XmlError); +void readGuiConfig( const wxString& filename, XmlGuiConfig& config); //throw (xmlAccess::XmlError); +void readBatchConfig(const wxString& filename, XmlBatchConfig& config); //throw (xmlAccess::XmlError); +void readGlobalSettings( XmlGlobalSettings& config); //throw (xmlAccess::XmlError); - void readGuiOrBatchConfig(const wxString& filename, XmlGuiConfig& config); //throw (xmlAccess::XmlError); +void readGuiOrBatchConfig(const wxString& filename, XmlGuiConfig& config); //throw (xmlAccess::XmlError); - void writeGuiConfig( const XmlGuiConfig& outputCfg, const wxString& filename); //throw (xmlAccess::XmlError); - void writeBatchConfig( const XmlBatchConfig& outputCfg, const wxString& filename); //throw (xmlAccess::XmlError); - void writeGlobalSettings(const XmlGlobalSettings& outputCfg); //throw (xmlAccess::XmlError); +void writeGuiConfig( const XmlGuiConfig& outputCfg, const wxString& filename); //throw (xmlAccess::XmlError); +void writeBatchConfig( const XmlBatchConfig& outputCfg, const wxString& filename); //throw (xmlAccess::XmlError); +void writeGlobalSettings(const XmlGlobalSettings& outputCfg); //throw (xmlAccess::XmlError); } diff --git a/library/resources.cpp b/library/resources.cpp index 1b9ce12d..a42f2788 100644 --- a/library/resources.cpp +++ b/library/resources.cpp @@ -4,10 +4,13 @@ #include <wx/image.h> #include <wx/icon.h> #include <wx/mstream.h> +#include "../shared/stringConv.h" #include "../shared/systemConstants.h" #include <memory> #include "../shared/standardPaths.h" +using namespace FreeFileSync; + const GlobalResources& GlobalResources::getInstance() { @@ -127,7 +130,9 @@ GlobalResources::GlobalResources() bitmapResource[wxT("france.png")] = (bitmapFrance = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("germany.png")] = (bitmapGermany = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("hungary.png")] = (bitmapHungary = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("romania.png")] = (bitmapRomania = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("taiwan.png")] = (bitmapTaiwan = new wxBitmap(wxNullBitmap)); + bitmapResource[wxT("turkey.png")] = (bitmapTurkey = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("italy.png")] = (bitmapItaly = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("japan.png")] = (bitmapJapan = new wxBitmap(wxNullBitmap)); bitmapResource[wxT("poland.png")] = (bitmapPoland = new wxBitmap(wxNullBitmap)); @@ -213,7 +218,7 @@ void loadAnimFromZip(wxZipInputStream& zipInput, wxAnimation* animation) void GlobalResources::load() const { - wxFFileInputStream input(FreeFileSync::getInstallationDir() + globalFunctions::FILE_NAME_SEPARATOR + wxT("Resources.dat")); + wxFFileInputStream input(FreeFileSync::getInstallationDir() + zToWx(globalFunctions::FILE_NAME_SEPARATOR) + wxT("Resources.dat")); if (input.IsOk()) //if not... we don't want to react too harsh here { //activate support for .png files diff --git a/library/resources.h b/library/resources.h index 804dea7a..432498a3 100644 --- a/library/resources.h +++ b/library/resources.h @@ -123,7 +123,9 @@ public: wxBitmap* bitmapFrance; wxBitmap* bitmapGermany; wxBitmap* bitmapHungary; + wxBitmap* bitmapRomania; wxBitmap* bitmapTaiwan; + wxBitmap* bitmapTurkey; wxBitmap* bitmapItaly; wxBitmap* bitmapJapan; wxBitmap* bitmapPoland; diff --git a/library/statistics.cpp b/library/statistics.cpp index 08bb5dee..fb7f5ba4 100644 --- a/library/statistics.cpp +++ b/library/statistics.cpp @@ -3,18 +3,20 @@ #include <wx/ffile.h> #include "../shared/globalFunctions.h" #include "statusHandler.h" -#include "../algorithm.h" +//#include "../algorithm.h" +#include "../ui/util.h" #include <wx/intl.h> #include <limits> #include <wx/stopwatch.h> RetrieveStatistics::RetrieveStatistics() : - timer(new wxStopWatch) {} + timer(new wxStopWatch) {} RetrieveStatistics::~RetrieveStatistics() -{ //write statistics to a file +{ + //write statistics to a file wxFFile outputFile(wxT("statistics.dat"), wxT("w")); outputFile.Write(wxT("Time(ms);Objects;Data\n")); @@ -103,13 +105,13 @@ Statistics::Statistics(const int totalObjectCount, const double totalDataAmount, const unsigned windowSizeRemainingTime, const unsigned windowSizeBytesPerSecond) : - objectsTotal(totalObjectCount), - dataTotal(totalDataAmount), - windowSizeRemTime(windowSizeRemainingTime), - windowSizeBPS(windowSizeBytesPerSecond), - windowMax(std::max(windowSizeRemainingTime, windowSizeBytesPerSecond)), - remainingTimeLast(256*256*256*100), //something "big" - timer(new wxStopWatch) {} + objectsTotal(totalObjectCount), + dataTotal(totalDataAmount), + windowSizeRemTime(windowSizeRemainingTime), + windowSizeBPS(windowSizeBytesPerSecond), + windowMax(std::max(windowSizeRemainingTime, windowSizeBytesPerSecond)), + remainingTimeLast(256*256*256*100), //something "big" + timer(new wxStopWatch) {} void Statistics::addMeasurement(const int objectsCurrent, const double dataCurrent) diff --git a/library/tinyxml/tinystr.cpp b/library/tinyxml/tinystr.cpp deleted file mode 100644 index 2b9b5467..00000000 --- a/library/tinyxml/tinystr.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* -www.sourceforge.net/projects/tinyxml -Original file by Yves Berquin. - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ - -/* - * THIS FILE WAS ALTERED BY Tyge Løvset, 7. April 2005. - */ - - -#ifndef TIXML_USE_STL - -#include "tinystr.h" - -// Error value for find primitive -const TiXmlString::size_type TiXmlString::npos = static_cast< TiXmlString::size_type >(-1); - - -// Null rep. -TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, { '\0' } }; - - -void TiXmlString::reserve (size_type cap) -{ - if (cap > capacity()) - { - TiXmlString tmp; - tmp.init(length(), cap); - memcpy(tmp.start(), data(), length()); - swap(tmp); - } -} - - -TiXmlString& TiXmlString::assign(const char* str, size_type len) -{ - size_type cap = capacity(); - if (len > cap || cap > 3*(len + 8)) - { - TiXmlString tmp; - tmp.init(len); - memcpy(tmp.start(), str, len); - swap(tmp); - } - else - { - memmove(start(), str, len); - set_size(len); - } - return *this; -} - - -TiXmlString& TiXmlString::append(const char* str, size_type len) -{ - size_type newsize = length() + len; - if (newsize > capacity()) - { - reserve (newsize + capacity()); - } - memmove(finish(), str, len); - set_size(newsize); - return *this; -} - - -TiXmlString operator + (const TiXmlString & a, const TiXmlString & b) -{ - TiXmlString tmp; - tmp.reserve(a.length() + b.length()); - tmp += a; - tmp += b; - return tmp; -} - -TiXmlString operator + (const TiXmlString & a, const char* b) -{ - TiXmlString tmp; - TiXmlString::size_type b_len = static_cast<TiXmlString::size_type>( strlen(b) ); - tmp.reserve(a.length() + b_len); - tmp += a; - tmp.append(b, b_len); - return tmp; -} - -TiXmlString operator + (const char* a, const TiXmlString & b) -{ - TiXmlString tmp; - TiXmlString::size_type a_len = static_cast<TiXmlString::size_type>( strlen(a) ); - tmp.reserve(a_len + b.length()); - tmp.append(a, a_len); - tmp += b; - return tmp; -} - - -#endif // TIXML_USE_STL diff --git a/library/tinyxml/tinystr.h b/library/tinyxml/tinystr.h deleted file mode 100644 index 3c2aa9d5..00000000 --- a/library/tinyxml/tinystr.h +++ /dev/null @@ -1,319 +0,0 @@ -/* -www.sourceforge.net/projects/tinyxml -Original file by Yves Berquin. - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ - -/* - * THIS FILE WAS ALTERED BY Tyge Lovset, 7. April 2005. - * - * - completely rewritten. compact, clean, and fast implementation. - * - sizeof(TiXmlString) = pointer size (4 bytes on 32-bit systems) - * - fixed reserve() to work as per specification. - * - fixed buggy compares operator==(), operator<(), and operator>() - * - fixed operator+=() to take a const ref argument, following spec. - * - added "copy" constructor with length, and most compare operators. - * - added swap(), clear(), size(), capacity(), operator+(). - */ - -#ifndef TIXML_USE_STL - -#ifndef TIXML_STRING_INCLUDED -#define TIXML_STRING_INCLUDED - -#include <assert.h> -#include <string.h> - -/* The support for explicit isn't that universal, and it isn't really - required - it is used to check that the TiXmlString class isn't incorrectly - used. Be nice to old compilers and macro it here: -*/ -#if defined(_MSC_VER) && (_MSC_VER >= 1200 ) - // Microsoft visual studio, version 6 and higher. - #define TIXML_EXPLICIT explicit -#elif defined(__GNUC__) && (__GNUC__ >= 3 ) - // GCC version 3 and higher.s - #define TIXML_EXPLICIT explicit -#else - #define TIXML_EXPLICIT -#endif - - -/* - TiXmlString is an emulation of a subset of the std::string template. - Its purpose is to allow compiling TinyXML on compilers with no or poor STL support. - Only the member functions relevant to the TinyXML project have been implemented. - The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase - a string and there's no more room, we allocate a buffer twice as big as we need. -*/ -class TiXmlString -{ - public : - // The size type used - typedef size_t size_type; - - // Error value for find primitive - static const size_type npos; // = -1; - - - // TiXmlString empty constructor - TiXmlString () : rep_(&nullrep_) - { - } - - // TiXmlString copy constructor - TiXmlString ( const TiXmlString & copy) : rep_(0) - { - init(copy.length()); - memcpy(start(), copy.data(), length()); - } - - // TiXmlString constructor, based on a string - TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0) - { - init( static_cast<size_type>( strlen(copy) )); - memcpy(start(), copy, length()); - } - - // TiXmlString constructor, based on a string - TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0) - { - init(len); - memcpy(start(), str, len); - } - - // TiXmlString destructor - ~TiXmlString () - { - quit(); - } - - // = operator - TiXmlString& operator = (const char * copy) - { - return assign( copy, (size_type)strlen(copy)); - } - - // = operator - TiXmlString& operator = (const TiXmlString & copy) - { - return assign(copy.start(), copy.length()); - } - - - // += operator. Maps to append - TiXmlString& operator += (const char * suffix) - { - return append(suffix, static_cast<size_type>( strlen(suffix) )); - } - - // += operator. Maps to append - TiXmlString& operator += (char single) - { - return append(&single, 1); - } - - // += operator. Maps to append - TiXmlString& operator += (const TiXmlString & suffix) - { - return append(suffix.data(), suffix.length()); - } - - - // Convert a TiXmlString into a null-terminated char * - const char * c_str () const { return rep_->str; } - - // Convert a TiXmlString into a char * (need not be null terminated). - const char * data () const { return rep_->str; } - - // Return the length of a TiXmlString - size_type length () const { return rep_->size; } - - // Alias for length() - size_type size () const { return rep_->size; } - - // Checks if a TiXmlString is empty - bool empty () const { return rep_->size == 0; } - - // Return capacity of string - size_type capacity () const { return rep_->capacity; } - - - // single char extraction - const char& at (size_type index) const - { - assert( index < length() ); - return rep_->str[ index ]; - } - - // [] operator - char& operator [] (size_type index) const - { - assert( index < length() ); - return rep_->str[ index ]; - } - - // find a char in a string. Return TiXmlString::npos if not found - size_type find (char lookup) const - { - return find(lookup, 0); - } - - // find a char in a string from an offset. Return TiXmlString::npos if not found - size_type find (char tofind, size_type offset) const - { - if (offset >= length()) return npos; - - for (const char* p = c_str() + offset; *p != '\0'; ++p) - { - if (*p == tofind) return static_cast< size_type >( p - c_str() ); - } - return npos; - } - - void clear () - { - //Lee: - //The original was just too strange, though correct: - // TiXmlString().swap(*this); - //Instead use the quit & re-init: - quit(); - init(0,0); - } - - /* Function to reserve a big amount of data when we know we'll need it. Be aware that this - function DOES NOT clear the content of the TiXmlString if any exists. - */ - void reserve (size_type cap); - - TiXmlString& assign (const char* str, size_type len); - - TiXmlString& append (const char* str, size_type len); - - void swap (TiXmlString& other) - { - Rep* r = rep_; - rep_ = other.rep_; - other.rep_ = r; - } - - private: - - void init(size_type sz) { init(sz, sz); } - void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; } - char* start() const { return rep_->str; } - char* finish() const { return rep_->str + rep_->size; } - - struct Rep - { - size_type size, capacity; - char str[1]; - }; - - void init(size_type sz, size_type cap) - { - if (cap) - { - // Lee: the original form: - // rep_ = static_cast<Rep*>(operator new(sizeof(Rep) + cap)); - // doesn't work in some cases of new being overloaded. Switching - // to the normal allocation, although use an 'int' for systems - // that are overly picky about structure alignment. - const size_type bytesNeeded = sizeof(Rep) + cap; - const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int ); - rep_ = reinterpret_cast<Rep*>( new int[ intsNeeded ] ); - - rep_->str[ rep_->size = sz ] = '\0'; - rep_->capacity = cap; - } - else - { - rep_ = &nullrep_; - } - } - - void quit() - { - if (rep_ != &nullrep_) - { - // The rep_ is really an array of ints. (see the allocator, above). - // Cast it back before delete, so the compiler won't incorrectly call destructors. - delete [] ( reinterpret_cast<int*>( rep_ ) ); - } - } - - Rep * rep_; - static Rep nullrep_; - -} ; - - -inline bool operator == (const TiXmlString & a, const TiXmlString & b) -{ - return ( a.length() == b.length() ) // optimization on some platforms - && ( strcmp(a.c_str(), b.c_str()) == 0 ); // actual compare -} -inline bool operator < (const TiXmlString & a, const TiXmlString & b) -{ - return strcmp(a.c_str(), b.c_str()) < 0; -} - -inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); } -inline bool operator > (const TiXmlString & a, const TiXmlString & b) { return b < a; } -inline bool operator <= (const TiXmlString & a, const TiXmlString & b) { return !(b < a); } -inline bool operator >= (const TiXmlString & a, const TiXmlString & b) { return !(a < b); } - -inline bool operator == (const TiXmlString & a, const char* b) { return strcmp(a.c_str(), b) == 0; } -inline bool operator == (const char* a, const TiXmlString & b) { return b == a; } -inline bool operator != (const TiXmlString & a, const char* b) { return !(a == b); } -inline bool operator != (const char* a, const TiXmlString & b) { return !(b == a); } - -TiXmlString operator + (const TiXmlString & a, const TiXmlString & b); -TiXmlString operator + (const TiXmlString & a, const char* b); -TiXmlString operator + (const char* a, const TiXmlString & b); - - -/* - TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString. - Only the operators that we need for TinyXML have been developped. -*/ -class TiXmlOutStream : public TiXmlString -{ -public : - - // TiXmlOutStream << operator. - TiXmlOutStream & operator << (const TiXmlString & in) - { - *this += in; - return *this; - } - - // TiXmlOutStream << operator. - TiXmlOutStream & operator << (const char * in) - { - *this += in; - return *this; - } - -} ; - -#endif // TIXML_STRING_INCLUDED -#endif // TIXML_USE_STL diff --git a/library/tinyxml/tinyxml.cpp b/library/tinyxml/tinyxml.cpp deleted file mode 100644 index aa13deec..00000000 --- a/library/tinyxml/tinyxml.cpp +++ /dev/null @@ -1,1942 +0,0 @@ -/* -www.sourceforge.net/projects/tinyxml -Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com) - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ - -#include <ctype.h> - -#ifdef TIXML_USE_STL -#include <sstream> -#include <iostream> -#endif - -#include "tinyxml.h" - - -bool TiXmlBase::condenseWhiteSpace = true; - -// Microsoft compiler security -FILE* TiXmlFOpen( const char* filename, const char* mode ) -{ -#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) - FILE* fp = 0; - errno_t err = fopen_s( &fp, filename, mode ); - if ( !err && fp ) - return fp; - return 0; -#else - return fopen( filename, mode ); -#endif -} - -void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString ) -{ - int i=0; - - while ( i<(int)str.length() ) - { - unsigned char c = (unsigned char) str[i]; - - if ( c == '&' - && i < ( (int)str.length() - 2 ) - && str[i+1] == '#' - && str[i+2] == 'x' ) - { - // Hexadecimal character reference. - // Pass through unchanged. - // © -- copyright symbol, for example. - // - // The -1 is a bug fix from Rob Laveaux. It keeps - // an overflow from happening if there is no ';'. - // There are actually 2 ways to exit this loop - - // while fails (error case) and break (semicolon found). - // However, there is no mechanism (currently) for - // this function to return an error. - while ( i<(int)str.length()-1 ) - { - outString->append( str.c_str() + i, 1 ); - ++i; - if ( str[i] == ';' ) - break; - } - } - else if ( c == '&' ) - { - outString->append( entity[0].str, entity[0].strLength ); - ++i; - } - else if ( c == '<' ) - { - outString->append( entity[1].str, entity[1].strLength ); - ++i; - } - else if ( c == '>' ) - { - outString->append( entity[2].str, entity[2].strLength ); - ++i; - } - else if ( c == '\"' ) - { - outString->append( entity[3].str, entity[3].strLength ); - ++i; - } - else if ( c == '\'' ) - { - outString->append( entity[4].str, entity[4].strLength ); - ++i; - } - else if ( c < 32 ) - { - // Easy pass at non-alpha/numeric/symbol - // Below 32 is symbolic. - char buf[ 32 ]; - -#if defined(TIXML_SNPRINTF) - TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) ); -#else - sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) ); -#endif - - //*ME: warning C4267: convert 'size_t' to 'int' - //*ME: Int-Cast to make compiler happy ... - outString->append( buf, (int)strlen( buf ) ); - ++i; - } - else - { - //char realc = (char) c; - //outString->append( &realc, 1 ); - *outString += (char) c; // somewhat more efficient function call. - ++i; - } - } -} - - -TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase() -{ - parent = 0; - type = _type; - firstChild = 0; - lastChild = 0; - prev = 0; - next = 0; -} - - -TiXmlNode::~TiXmlNode() -{ - TiXmlNode* node = firstChild; - TiXmlNode* temp = 0; - - while ( node ) - { - temp = node; - node = node->next; - delete temp; - } -} - - -void TiXmlNode::CopyTo( TiXmlNode* target ) const -{ - target->SetValue (value.c_str() ); - target->userData = userData; -} - - -void TiXmlNode::Clear() -{ - TiXmlNode* node = firstChild; - TiXmlNode* temp = 0; - - while ( node ) - { - temp = node; - node = node->next; - delete temp; - } - - firstChild = 0; - lastChild = 0; -} - - -TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node ) -{ - assert( node->parent == 0 || node->parent == this ); - assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() ); - - if ( node->Type() == TiXmlNode::DOCUMENT ) - { - delete node; - if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - - node->parent = this; - - node->prev = lastChild; - node->next = 0; - - if ( lastChild ) - lastChild->next = node; - else - firstChild = node; // it was an empty list. - - lastChild = node; - return node; -} - - -TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis ) -{ - if ( addThis.Type() == TiXmlNode::DOCUMENT ) - { - if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - TiXmlNode* node = addThis.Clone(); - if ( !node ) - return 0; - - return LinkEndChild( node ); -} - - -TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ) -{ - if ( !beforeThis || beforeThis->parent != this ) - { - return 0; - } - if ( addThis.Type() == TiXmlNode::DOCUMENT ) - { - if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - - TiXmlNode* node = addThis.Clone(); - if ( !node ) - return 0; - node->parent = this; - - node->next = beforeThis; - node->prev = beforeThis->prev; - if ( beforeThis->prev ) - { - beforeThis->prev->next = node; - } - else - { - assert( firstChild == beforeThis ); - firstChild = node; - } - beforeThis->prev = node; - return node; -} - - -TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ) -{ - if ( !afterThis || afterThis->parent != this ) - { - return 0; - } - if ( addThis.Type() == TiXmlNode::DOCUMENT ) - { - if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - - TiXmlNode* node = addThis.Clone(); - if ( !node ) - return 0; - node->parent = this; - - node->prev = afterThis; - node->next = afterThis->next; - if ( afterThis->next ) - { - afterThis->next->prev = node; - } - else - { - assert( lastChild == afterThis ); - lastChild = node; - } - afterThis->next = node; - return node; -} - - -TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ) -{ - if ( replaceThis->parent != this ) - return 0; - - TiXmlNode* node = withThis.Clone(); - if ( !node ) - return 0; - - node->next = replaceThis->next; - node->prev = replaceThis->prev; - - if ( replaceThis->next ) - replaceThis->next->prev = node; - else - lastChild = node; - - if ( replaceThis->prev ) - replaceThis->prev->next = node; - else - firstChild = node; - - delete replaceThis; - node->parent = this; - return node; -} - - -bool TiXmlNode::RemoveChild( TiXmlNode* removeThis ) -{ - if ( removeThis->parent != this ) - { - assert( 0 ); - return false; - } - - if ( removeThis->next ) - removeThis->next->prev = removeThis->prev; - else - lastChild = removeThis->prev; - - if ( removeThis->prev ) - removeThis->prev->next = removeThis->next; - else - firstChild = removeThis->next; - - delete removeThis; - return true; -} - -const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const -{ - const TiXmlNode* node; - for ( node = firstChild; node; node = node->next ) - { - if ( strcmp( node->Value(), _value ) == 0 ) - return node; - } - return 0; -} - - -const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const -{ - const TiXmlNode* node; - for ( node = lastChild; node; node = node->prev ) - { - if ( strcmp( node->Value(), _value ) == 0 ) - return node; - } - return 0; -} - - -const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const -{ - if ( !previous ) - { - return FirstChild(); - } - else - { - assert( previous->parent == this ); - return previous->NextSibling(); - } -} - - -const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const -{ - if ( !previous ) - { - return FirstChild( val ); - } - else - { - assert( previous->parent == this ); - return previous->NextSibling( val ); - } -} - - -const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const -{ - const TiXmlNode* node; - for ( node = next; node; node = node->next ) - { - if ( strcmp( node->Value(), _value ) == 0 ) - return node; - } - return 0; -} - - -const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const -{ - const TiXmlNode* node; - for ( node = prev; node; node = node->prev ) - { - if ( strcmp( node->Value(), _value ) == 0 ) - return node; - } - return 0; -} - - -void TiXmlElement::RemoveAttribute( const char * name ) -{ -#ifdef TIXML_USE_STL - TIXML_STRING str( name ); - TiXmlAttribute* node = attributeSet.Find( str ); -#else - TiXmlAttribute* node = attributeSet.Find( name ); -#endif - if ( node ) - { - attributeSet.Remove( node ); - delete node; - } -} - -const TiXmlElement* TiXmlNode::FirstChildElement() const -{ - const TiXmlNode* node; - - for ( node = FirstChild(); - node; - node = node->NextSibling() ) - { - if ( node->ToElement() ) - return node->ToElement(); - } - return 0; -} - - -const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const -{ - const TiXmlNode* node; - - for ( node = FirstChild( _value ); - node; - node = node->NextSibling( _value ) ) - { - if ( node->ToElement() ) - return node->ToElement(); - } - return 0; -} - - -const TiXmlElement* TiXmlNode::NextSiblingElement() const -{ - const TiXmlNode* node; - - for ( node = NextSibling(); - node; - node = node->NextSibling() ) - { - if ( node->ToElement() ) - return node->ToElement(); - } - return 0; -} - - -const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const -{ - const TiXmlNode* node; - - for ( node = NextSibling( _value ); - node; - node = node->NextSibling( _value ) ) - { - if ( node->ToElement() ) - return node->ToElement(); - } - return 0; -} - - -const TiXmlDocument* TiXmlNode::GetDocument() const -{ - const TiXmlNode* node; - - for ( node = this; node; node = node->parent ) - { - if ( node->ToDocument() ) - return node->ToDocument(); - } - return 0; -} - - -TiXmlElement::TiXmlElement (const char * _value) - : TiXmlNode( TiXmlNode::ELEMENT ) -{ - firstChild = lastChild = 0; - value = _value; -} - - -#ifdef TIXML_USE_STL -TiXmlElement::TiXmlElement( const std::string& _value ) - : TiXmlNode( TiXmlNode::ELEMENT ) -{ - firstChild = lastChild = 0; - value = _value; -} -#endif - - -TiXmlElement::TiXmlElement( const TiXmlElement& copy) - : TiXmlNode( TiXmlNode::ELEMENT ) -{ - firstChild = lastChild = 0; - copy.CopyTo( this ); -} - - -void TiXmlElement::operator=( const TiXmlElement& base ) -{ - ClearThis(); - base.CopyTo( this ); -} - - -TiXmlElement::~TiXmlElement() -{ - ClearThis(); -} - - -void TiXmlElement::ClearThis() -{ - Clear(); - while ( attributeSet.First() ) - { - TiXmlAttribute* node = attributeSet.First(); - attributeSet.Remove( node ); - delete node; - } -} - - -const char* TiXmlElement::Attribute( const char* name ) const -{ - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( node ) - return node->Value(); - return 0; -} - - -#ifdef TIXML_USE_STL -const std::string* TiXmlElement::Attribute( const std::string& name ) const -{ - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( node ) - return &node->ValueStr(); - return 0; -} -#endif - - -const char* TiXmlElement::Attribute( const char* name, int* i ) const -{ - const char* s = Attribute( name ); - if ( i ) - { - if ( s ) - { - *i = atoi( s ); - } - else - { - *i = 0; - } - } - return s; -} - - -#ifdef TIXML_USE_STL -const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const -{ - const std::string* s = Attribute( name ); - if ( i ) - { - if ( s ) - { - *i = atoi( s->c_str() ); - } - else - { - *i = 0; - } - } - return s; -} -#endif - - -const char* TiXmlElement::Attribute( const char* name, double* d ) const -{ - const char* s = Attribute( name ); - if ( d ) - { - if ( s ) - { - *d = atof( s ); - } - else - { - *d = 0; - } - } - return s; -} - - -#ifdef TIXML_USE_STL -const std::string* TiXmlElement::Attribute( const std::string& name, double* d ) const -{ - const std::string* s = Attribute( name ); - if ( d ) - { - if ( s ) - { - *d = atof( s->c_str() ); - } - else - { - *d = 0; - } - } - return s; -} -#endif - - -int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const -{ - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( !node ) - return TIXML_NO_ATTRIBUTE; - return node->QueryIntValue( ival ); -} - - -#ifdef TIXML_USE_STL -int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const -{ - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( !node ) - return TIXML_NO_ATTRIBUTE; - return node->QueryIntValue( ival ); -} -#endif - - -int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const -{ - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( !node ) - return TIXML_NO_ATTRIBUTE; - return node->QueryDoubleValue( dval ); -} - - -#ifdef TIXML_USE_STL -int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const -{ - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( !node ) - return TIXML_NO_ATTRIBUTE; - return node->QueryDoubleValue( dval ); -} -#endif - - -void TiXmlElement::SetAttribute( const char * name, int val ) -{ - char buf[64]; -#if defined(TIXML_SNPRINTF) - TIXML_SNPRINTF( buf, sizeof(buf), "%d", val ); -#else - sprintf( buf, "%d", val ); -#endif - SetAttribute( name, buf ); -} - - -#ifdef TIXML_USE_STL -void TiXmlElement::SetAttribute( const std::string& name, int val ) -{ - std::ostringstream oss; - oss << val; - SetAttribute( name, oss.str() ); -} -#endif - - -void TiXmlElement::SetDoubleAttribute( const char * name, double val ) -{ - char buf[256]; -#if defined(TIXML_SNPRINTF) - TIXML_SNPRINTF( buf, sizeof(buf), "%f", val ); -#else - sprintf( buf, "%f", val ); -#endif - SetAttribute( name, buf ); -} - - -void TiXmlElement::SetAttribute( const char * cname, const char * cvalue ) -{ -#ifdef TIXML_USE_STL - TIXML_STRING _name( cname ); - TIXML_STRING _value( cvalue ); -#else - const char* _name = cname; - const char* _value = cvalue; -#endif - - TiXmlAttribute* node = attributeSet.Find( _name ); - if ( node ) - { - node->SetValue( _value ); - return; - } - - TiXmlAttribute* attrib = new TiXmlAttribute( cname, cvalue ); - if ( attrib ) - { - attributeSet.Add( attrib ); - } - else - { - TiXmlDocument* document = GetDocument(); - if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN ); - } -} - - -#ifdef TIXML_USE_STL -void TiXmlElement::SetAttribute( const std::string& name, const std::string& _value ) -{ - TiXmlAttribute* node = attributeSet.Find( name ); - if ( node ) - { - node->SetValue( _value ); - return; - } - - TiXmlAttribute* attrib = new TiXmlAttribute( name, _value ); - if ( attrib ) - { - attributeSet.Add( attrib ); - } - else - { - TiXmlDocument* document = GetDocument(); - if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN ); - } -} -#endif - - -void TiXmlElement::Print( FILE* cfile, int depth ) const -{ - int i; - assert( cfile ); - for ( i=0; i<depth; i++ ) - { - fprintf( cfile, " " ); - } - - fprintf( cfile, "<%s", value.c_str() ); - - const TiXmlAttribute* attrib; - for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() ) - { - fprintf( cfile, " " ); - attrib->Print( cfile, depth ); - } - - // There are 3 different formatting approaches: - // 1) An element without children is printed as a <foo /> node - // 2) An element with only a text child is printed as <foo> text </foo> - // 3) An element with children is printed on multiple lines. - TiXmlNode* node; - if ( !firstChild ) - { - fprintf( cfile, " />" ); - } - else if ( firstChild == lastChild && firstChild->ToText() ) - { - fprintf( cfile, ">" ); - firstChild->Print( cfile, depth + 1 ); - fprintf( cfile, "</%s>", value.c_str() ); - } - else - { - fprintf( cfile, ">" ); - - for ( node = firstChild; node; node=node->NextSibling() ) - { - if ( !node->ToText() ) - { - fprintf( cfile, "\n" ); - } - node->Print( cfile, depth+1 ); - } - fprintf( cfile, "\n" ); - for ( i=0; i<depth; ++i ) - { - fprintf( cfile, " " ); - } - fprintf( cfile, "</%s>", value.c_str() ); - } -} - - -void TiXmlElement::CopyTo( TiXmlElement* target ) const -{ - // superclass: - TiXmlNode::CopyTo( target ); - - // Element class: - // Clone the attributes, then clone the children. - const TiXmlAttribute* attribute = 0; - for ( attribute = attributeSet.First(); - attribute; - attribute = attribute->Next() ) - { - target->SetAttribute( attribute->Name(), attribute->Value() ); - } - - TiXmlNode* node = 0; - for ( node = firstChild; node; node = node->NextSibling() ) - { - target->LinkEndChild( node->Clone() ); - } -} - -bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const -{ - if ( visitor->VisitEnter( *this, attributeSet.First() ) ) - { - for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) - { - if ( !node->Accept( visitor ) ) - break; - } - } - return visitor->VisitExit( *this ); -} - - -TiXmlNode* TiXmlElement::Clone() const -{ - TiXmlElement* clone = new TiXmlElement( Value() ); - if ( !clone ) - return 0; - - CopyTo( clone ); - return clone; -} - - -const char* TiXmlElement::GetText() const -{ - const TiXmlNode* child = this->FirstChild(); - if ( child ) - { - const TiXmlText* childText = child->ToText(); - if ( childText ) - { - return childText->Value(); - } - } - return 0; -} - - -TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::DOCUMENT ) -{ - tabsize = 4; - useMicrosoftBOM = false; - ClearError(); -} - -TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::DOCUMENT ) -{ - tabsize = 4; - useMicrosoftBOM = false; - value = documentName; - ClearError(); -} - - -#ifdef TIXML_USE_STL -TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::DOCUMENT ) -{ - tabsize = 4; - useMicrosoftBOM = false; - value = documentName; - ClearError(); -} -#endif - - -TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::DOCUMENT ) -{ - copy.CopyTo( this ); -} - - -void TiXmlDocument::operator=( const TiXmlDocument& copy ) -{ - Clear(); - copy.CopyTo( this ); -} - - -bool TiXmlDocument::LoadFile( TiXmlEncoding encoding ) -{ - // See STL_STRING_BUG below. - //StringToBuffer buf( value ); - - return LoadFile( Value(), encoding ); -} - - -bool TiXmlDocument::SaveFile() const -{ - // See STL_STRING_BUG below. -// StringToBuffer buf( value ); -// -// if ( buf.buffer && SaveFile( buf.buffer ) ) -// return true; -// -// return false; - return SaveFile( Value() ); -} - -bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding ) -{ - // There was a really terrifying little bug here. The code: - // value = filename - // in the STL case, cause the assignment method of the std::string to - // be called. What is strange, is that the std::string had the same - // address as it's c_str() method, and so bad things happen. Looks - // like a bug in the Microsoft STL implementation. - // Add an extra string to avoid the crash. - TIXML_STRING filename( _filename ); - value = filename; - - // reading in binary mode so that tinyxml can normalize the EOL - FILE* file = TiXmlFOpen( value.c_str (), "rb" ); - - if ( file ) - { - bool result = LoadFile( file, encoding ); - fclose( file ); - return result; - } - else - { - SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); - return false; - } -} - -bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding ) -{ - if ( !file ) - { - SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); - return false; - } - - // Delete the existing data: - Clear(); - location.Clear(); - - // Get the file size, so we can pre-allocate the string. HUGE speed impact. - long length = 0; - fseek( file, 0, SEEK_END ); - length = ftell( file ); - fseek( file, 0, SEEK_SET ); - - // Strange case, but good to handle up front. - if ( length <= 0 ) - { - SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return false; - } - - // If we have a file, assume it is all one big XML file, and read it in. - // The document parser may decide the document ends sooner than the entire file, however. - TIXML_STRING data; - data.reserve( length ); - - // Subtle bug here. TinyXml did use fgets. But from the XML spec: - // 2.11 End-of-Line Handling - // <snip> - // <quote> - // ...the XML processor MUST behave as if it normalized all line breaks in external - // parsed entities (including the document entity) on input, before parsing, by translating - // both the two-character sequence #xD #xA and any #xD that is not followed by #xA to - // a single #xA character. - // </quote> - // - // It is not clear fgets does that, and certainly isn't clear it works cross platform. - // Generally, you expect fgets to translate from the convention of the OS to the c/unix - // convention, and not work generally. - - /* - while( fgets( buf, sizeof(buf), file ) ) - { - data += buf; - } - */ - - char* buf = new char[ length+1 ]; - buf[0] = 0; - - if ( fread( buf, length, 1, file ) != 1 ) - { - delete [] buf; - SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN ); - return false; - } - - const char* lastPos = buf; - const char* p = buf; - - buf[length] = 0; - while ( *p ) - { - assert( p < (buf+length) ); - if ( *p == 0xa ) - { - // Newline character. No special rules for this. Append all the characters - // since the last string, and include the newline. - data.append( lastPos, (p-lastPos+1) ); // append, include the newline - ++p; // move past the newline - lastPos = p; // and point to the new buffer (may be 0) - assert( p <= (buf+length) ); - } - else if ( *p == 0xd ) - { - // Carriage return. Append what we have so far, then - // handle moving forward in the buffer. - if ( (p-lastPos) > 0 ) - { - data.append( lastPos, p-lastPos ); // do not add the CR - } - data += (char)0xa; // a proper newline - - if ( *(p+1) == 0xa ) - { - // Carriage return - new line sequence - p += 2; - lastPos = p; - assert( p <= (buf+length) ); - } - else - { - // it was followed by something else...that is presumably characters again. - ++p; - lastPos = p; - assert( p <= (buf+length) ); - } - } - else - { - ++p; - } - } - // Handle any left over characters. - if ( p-lastPos ) - { - data.append( lastPos, p-lastPos ); - } - delete [] buf; - buf = 0; - - Parse( data.c_str(), 0, encoding ); - - if ( Error() ) - return false; - else - return true; -} - - -bool TiXmlDocument::SaveFile( const char * filename ) const -{ - // The old c stuff lives on... - FILE* fp = TiXmlFOpen( filename, "w" ); - if ( fp ) - { - bool result = SaveFile( fp ); - fclose( fp ); - return result; - } - return false; -} - - -bool TiXmlDocument::SaveFile( FILE* fp ) const -{ - if ( useMicrosoftBOM ) - { - const unsigned char TIXML_UTF_LEAD_0 = 0xefU; - const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; - const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; - - fputc( TIXML_UTF_LEAD_0, fp ); - fputc( TIXML_UTF_LEAD_1, fp ); - fputc( TIXML_UTF_LEAD_2, fp ); - } - Print( fp, 0 ); - return (ferror(fp) == 0); -} - - -void TiXmlDocument::CopyTo( TiXmlDocument* target ) const -{ - TiXmlNode::CopyTo( target ); - - target->error = error; - target->errorId = errorId; - target->errorDesc = errorDesc; - target->tabsize = tabsize; - target->errorLocation = errorLocation; - target->useMicrosoftBOM = useMicrosoftBOM; - - TiXmlNode* node = 0; - for ( node = firstChild; node; node = node->NextSibling() ) - { - target->LinkEndChild( node->Clone() ); - } -} - - -TiXmlNode* TiXmlDocument::Clone() const -{ - TiXmlDocument* clone = new TiXmlDocument(); - if ( !clone ) - return 0; - - CopyTo( clone ); - return clone; -} - - -void TiXmlDocument::Print( FILE* cfile, int depth ) const -{ - assert( cfile ); - for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) - { - node->Print( cfile, depth ); - fprintf( cfile, "\n" ); - } -} - - -bool TiXmlDocument::Accept( TiXmlVisitor* visitor ) const -{ - if ( visitor->VisitEnter( *this ) ) - { - for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() ) - { - if ( !node->Accept( visitor ) ) - break; - } - } - return visitor->VisitExit( *this ); -} - - -const TiXmlAttribute* TiXmlAttribute::Next() const -{ - // We are using knowledge of the sentinel. The sentinel - // have a value or name. - if ( next->value.empty() && next->name.empty() ) - return 0; - return next; -} - -/* -TiXmlAttribute* TiXmlAttribute::Next() -{ - // We are using knowledge of the sentinel. The sentinel - // have a value or name. - if ( next->value.empty() && next->name.empty() ) - return 0; - return next; -} -*/ - -const TiXmlAttribute* TiXmlAttribute::Previous() const -{ - // We are using knowledge of the sentinel. The sentinel - // have a value or name. - if ( prev->value.empty() && prev->name.empty() ) - return 0; - return prev; -} - -/* -TiXmlAttribute* TiXmlAttribute::Previous() -{ - // We are using knowledge of the sentinel. The sentinel - // have a value or name. - if ( prev->value.empty() && prev->name.empty() ) - return 0; - return prev; -} -*/ - -void TiXmlAttribute::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const -{ - TIXML_STRING n, v; - - EncodeString( name, &n ); - EncodeString( value, &v ); - - if (value.find ('\"') == TIXML_STRING::npos) - { - if ( cfile ) - { - fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() ); - } - if ( str ) - { - (*str) += n; - (*str) += "=\""; - (*str) += v; - (*str) += "\""; - } - } - else - { - if ( cfile ) - { - fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() ); - } - if ( str ) - { - (*str) += n; - (*str) += "='"; - (*str) += v; - (*str) += "'"; - } - } -} - - -int TiXmlAttribute::QueryIntValue( int* ival ) const -{ - if ( TIXML_SSCANF( value.c_str(), "%d", ival ) == 1 ) - return TIXML_SUCCESS; - return TIXML_WRONG_TYPE; -} - -int TiXmlAttribute::QueryDoubleValue( double* dval ) const -{ - if ( TIXML_SSCANF( value.c_str(), "%lf", dval ) == 1 ) - return TIXML_SUCCESS; - return TIXML_WRONG_TYPE; -} - -void TiXmlAttribute::SetIntValue( int _value ) -{ - char buf [64]; -#if defined(TIXML_SNPRINTF) - TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value); -#else - sprintf (buf, "%d", _value); -#endif - SetValue (buf); -} - -void TiXmlAttribute::SetDoubleValue( double _value ) -{ - char buf [256]; -#if defined(TIXML_SNPRINTF) - TIXML_SNPRINTF( buf, sizeof(buf), "%lf", _value); -#else - sprintf (buf, "%lf", _value); -#endif - SetValue (buf); -} - -int TiXmlAttribute::IntValue() const -{ - return atoi (value.c_str ()); -} - -double TiXmlAttribute::DoubleValue() const -{ - return atof (value.c_str ()); -} - - -TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::COMMENT ) -{ - copy.CopyTo( this ); -} - - -void TiXmlComment::operator=( const TiXmlComment& base ) -{ - Clear(); - base.CopyTo( this ); -} - - -void TiXmlComment::Print( FILE* cfile, int depth ) const -{ - assert( cfile ); - for ( int i=0; i<depth; i++ ) - { - fprintf( cfile, " " ); - } - fprintf( cfile, "<!--%s-->", value.c_str() ); -} - - -void TiXmlComment::CopyTo( TiXmlComment* target ) const -{ - TiXmlNode::CopyTo( target ); -} - - -bool TiXmlComment::Accept( TiXmlVisitor* visitor ) const -{ - return visitor->Visit( *this ); -} - - -TiXmlNode* TiXmlComment::Clone() const -{ - TiXmlComment* clone = new TiXmlComment(); - - if ( !clone ) - return 0; - - CopyTo( clone ); - return clone; -} - - -void TiXmlText::Print( FILE* cfile, int depth ) const -{ - assert( cfile ); - if ( cdata ) - { - int i; - fprintf( cfile, "\n" ); - for ( i=0; i<depth; i++ ) - { - fprintf( cfile, " " ); - } - fprintf( cfile, "<![CDATA[%s]]>\n", value.c_str() ); // unformatted output - } - else - { - TIXML_STRING buffer; - EncodeString( value, &buffer ); - fprintf( cfile, "%s", buffer.c_str() ); - } -} - - -void TiXmlText::CopyTo( TiXmlText* target ) const -{ - TiXmlNode::CopyTo( target ); - target->cdata = cdata; -} - - -bool TiXmlText::Accept( TiXmlVisitor* visitor ) const -{ - return visitor->Visit( *this ); -} - - -TiXmlNode* TiXmlText::Clone() const -{ - TiXmlText* clone = 0; - clone = new TiXmlText( "" ); - - if ( !clone ) - return 0; - - CopyTo( clone ); - return clone; -} - - -TiXmlDeclaration::TiXmlDeclaration( const char * _version, - const char * _encoding, - const char * _standalone ) - : TiXmlNode( TiXmlNode::DECLARATION ) -{ - version = _version; - encoding = _encoding; - standalone = _standalone; -} - - -#ifdef TIXML_USE_STL -TiXmlDeclaration::TiXmlDeclaration( const std::string& _version, - const std::string& _encoding, - const std::string& _standalone ) - : TiXmlNode( TiXmlNode::DECLARATION ) -{ - version = _version; - encoding = _encoding; - standalone = _standalone; -} -#endif - - -TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy ) - : TiXmlNode( TiXmlNode::DECLARATION ) -{ - copy.CopyTo( this ); -} - - -void TiXmlDeclaration::operator=( const TiXmlDeclaration& copy ) -{ - Clear(); - copy.CopyTo( this ); -} - - -void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const -{ - if ( cfile ) fprintf( cfile, "<?xml " ); - if ( str ) (*str) += "<?xml "; - - if ( !version.empty() ) - { - if ( cfile ) fprintf (cfile, "version=\"%s\" ", version.c_str ()); - if ( str ) - { - (*str) += "version=\""; - (*str) += version; - (*str) += "\" "; - } - } - if ( !encoding.empty() ) - { - if ( cfile ) fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ()); - if ( str ) - { - (*str) += "encoding=\""; - (*str) += encoding; - (*str) += "\" "; - } - } - if ( !standalone.empty() ) - { - if ( cfile ) fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ()); - if ( str ) - { - (*str) += "standalone=\""; - (*str) += standalone; - (*str) += "\" "; - } - } - if ( cfile ) fprintf( cfile, "?>" ); - if ( str ) (*str) += "?>"; -} - - -void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const -{ - TiXmlNode::CopyTo( target ); - - target->version = version; - target->encoding = encoding; - target->standalone = standalone; -} - - -bool TiXmlDeclaration::Accept( TiXmlVisitor* visitor ) const -{ - return visitor->Visit( *this ); -} - - -TiXmlNode* TiXmlDeclaration::Clone() const -{ - TiXmlDeclaration* clone = new TiXmlDeclaration(); - - if ( !clone ) - return 0; - - CopyTo( clone ); - return clone; -} - - -void TiXmlUnknown::Print( FILE* cfile, int depth ) const -{ - for ( int i=0; i<depth; i++ ) - fprintf( cfile, " " ); - fprintf( cfile, "<%s>", value.c_str() ); -} - - -void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const -{ - TiXmlNode::CopyTo( target ); -} - - -bool TiXmlUnknown::Accept( TiXmlVisitor* visitor ) const -{ - return visitor->Visit( *this ); -} - - -TiXmlNode* TiXmlUnknown::Clone() const -{ - TiXmlUnknown* clone = new TiXmlUnknown(); - - if ( !clone ) - return 0; - - CopyTo( clone ); - return clone; -} - - -TiXmlAttributeSet::TiXmlAttributeSet() -{ - sentinel.next = &sentinel; - sentinel.prev = &sentinel; -} - - -TiXmlAttributeSet::~TiXmlAttributeSet() -{ - assert( sentinel.next == &sentinel ); - assert( sentinel.prev == &sentinel ); -} - - -void TiXmlAttributeSet::Add( TiXmlAttribute* addMe ) -{ -#ifdef TIXML_USE_STL - assert( !Find( TIXML_STRING( addMe->Name() ) ) ); // Shouldn't be multiply adding to the set. -#else - assert( !Find( addMe->Name() ) ); // Shouldn't be multiply adding to the set. -#endif - - addMe->next = &sentinel; - addMe->prev = sentinel.prev; - - sentinel.prev->next = addMe; - sentinel.prev = addMe; -} - -void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe ) -{ - TiXmlAttribute* node; - - for ( node = sentinel.next; node != &sentinel; node = node->next ) - { - if ( node == removeMe ) - { - node->prev->next = node->next; - node->next->prev = node->prev; - node->next = 0; - node->prev = 0; - return; - } - } - assert( 0 ); // we tried to remove a non-linked attribute. -} - - -#ifdef TIXML_USE_STL -const TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const -{ - for ( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) - { - if ( node->name == name ) - return node; - } - return 0; -} - -/* -TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) -{ - for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) - { - if ( node->name == name ) - return node; - } - return 0; -} -*/ -#endif - - -const TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const -{ - for ( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) - { - if ( strcmp( node->name.c_str(), name ) == 0 ) - return node; - } - return 0; -} - -/* -TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) -{ - for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next ) - { - if ( strcmp( node->name.c_str(), name ) == 0 ) - return node; - } - return 0; -} -*/ - -#ifdef TIXML_USE_STL -std::istream& operator>> (std::istream & in, TiXmlNode & base) -{ - TIXML_STRING tag; - tag.reserve( 8 * 1000 ); - base.StreamIn( &in, &tag ); - - base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING ); - return in; -} -#endif - - -#ifdef TIXML_USE_STL -std::ostream& operator<< (std::ostream & out, const TiXmlNode & base) -{ - TiXmlPrinter printer; - printer.SetStreamPrinting(); - base.Accept( &printer ); - out << printer.Str(); - - return out; -} - - -std::string& operator<< (std::string& out, const TiXmlNode& base ) -{ - TiXmlPrinter printer; - printer.SetStreamPrinting(); - base.Accept( &printer ); - out.append( printer.Str() ); - - return out; -} -#endif - - -TiXmlHandle TiXmlHandle::FirstChild() const -{ - if ( node ) - { - TiXmlNode* child = node->FirstChild(); - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const -{ - if ( node ) - { - TiXmlNode* child = node->FirstChild( value ); - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::FirstChildElement() const -{ - if ( node ) - { - TiXmlElement* child = node->FirstChildElement(); - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const -{ - if ( node ) - { - TiXmlElement* child = node->FirstChildElement( value ); - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::Child( int count ) const -{ - if ( node ) - { - int i; - TiXmlNode* child = node->FirstChild(); - for ( i=0; - child && i<count; - child = child->NextSibling(), ++i ) - { - // nothing - } - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const -{ - if ( node ) - { - int i; - TiXmlNode* child = node->FirstChild( value ); - for ( i=0; - child && i<count; - child = child->NextSibling( value ), ++i ) - { - // nothing - } - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::ChildElement( int count ) const -{ - if ( node ) - { - int i; - TiXmlElement* child = node->FirstChildElement(); - for ( i=0; - child && i<count; - child = child->NextSiblingElement(), ++i ) - { - // nothing - } - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const -{ - if ( node ) - { - int i; - TiXmlElement* child = node->FirstChildElement( value ); - for ( i=0; - child && i<count; - child = child->NextSiblingElement( value ), ++i ) - { - // nothing - } - if ( child ) - return TiXmlHandle( child ); - } - return TiXmlHandle( 0 ); -} - - -bool TiXmlPrinter::VisitEnter( const TiXmlDocument& ) -{ - return true; -} - -bool TiXmlPrinter::VisitExit( const TiXmlDocument& ) -{ - return true; -} - -bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ) -{ - DoIndent(); - buffer += "<"; - buffer += element.Value(); - - for ( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() ) - { - buffer += " "; - attrib->Print( 0, 0, &buffer ); - } - - if ( !element.FirstChild() ) - { - buffer += " />"; - DoLineBreak(); - } - else - { - buffer += ">"; - if ( element.FirstChild()->ToText() - && element.LastChild() == element.FirstChild() - && element.FirstChild()->ToText()->CDATA() == false ) - { - simpleTextPrint = true; - // no DoLineBreak()! - } - else - { - DoLineBreak(); - } - } - ++depth; - return true; -} - - -bool TiXmlPrinter::VisitExit( const TiXmlElement& element ) -{ - --depth; - if ( !element.FirstChild() ) - { - // nothing. - } - else - { - if ( simpleTextPrint ) - { - simpleTextPrint = false; - } - else - { - DoIndent(); - } - buffer += "</"; - buffer += element.Value(); - buffer += ">"; - DoLineBreak(); - } - return true; -} - - -bool TiXmlPrinter::Visit( const TiXmlText& text ) -{ - if ( text.CDATA() ) - { - DoIndent(); - buffer += "<![CDATA["; - buffer += text.Value(); - buffer += "]]>"; - DoLineBreak(); - } - else if ( simpleTextPrint ) - { - TIXML_STRING str; - TiXmlBase::EncodeString( text.ValueTStr(), &str ); - buffer += str; - } - else - { - DoIndent(); - TIXML_STRING str; - TiXmlBase::EncodeString( text.ValueTStr(), &str ); - buffer += str; - DoLineBreak(); - } - return true; -} - - -bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration ) -{ - DoIndent(); - declaration.Print( 0, 0, &buffer ); - DoLineBreak(); - return true; -} - - -bool TiXmlPrinter::Visit( const TiXmlComment& comment ) -{ - DoIndent(); - buffer += "<!--"; - buffer += comment.Value(); - buffer += "-->"; - DoLineBreak(); - return true; -} - - -bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown ) -{ - DoIndent(); - buffer += "<"; - buffer += unknown.Value(); - buffer += ">"; - DoLineBreak(); - return true; -} - diff --git a/library/tinyxml/tinyxml.h b/library/tinyxml/tinyxml.h deleted file mode 100644 index c6f40cc2..00000000 --- a/library/tinyxml/tinyxml.h +++ /dev/null @@ -1,1802 +0,0 @@ -/* -www.sourceforge.net/projects/tinyxml -Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com) - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ - - -#ifndef TINYXML_INCLUDED -#define TINYXML_INCLUDED - -#ifdef _MSC_VER -#pragma warning( push ) -#pragma warning( disable : 4530 ) -#pragma warning( disable : 4786 ) -#endif - -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -// Help out windows: -#if defined( _DEBUG ) && !defined( DEBUG ) -#define DEBUG -#endif - -#ifdef TIXML_USE_STL - #include <string> - #include <iostream> - #include <sstream> - #define TIXML_STRING std::string -#else - #include "tinystr.h" - #define TIXML_STRING TiXmlString -#endif - -// Deprecated library function hell. Compilers want to use the -// new safe versions. This probably doesn't fully address the problem, -// but it gets closer. There are too many compilers for me to fully -// test. If you get compilation troubles, undefine TIXML_SAFE -#define TIXML_SAFE - -#ifdef TIXML_SAFE - #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) - // Microsoft visual studio, version 2005 and higher. - #define TIXML_SNPRINTF _snprintf_s - #define TIXML_SNSCANF _snscanf_s - #define TIXML_SSCANF sscanf_s - #elif defined(_MSC_VER) && (_MSC_VER >= 1200 ) - // Microsoft visual studio, version 6 and higher. - //#pragma message( "Using _sn* functions." ) - #define TIXML_SNPRINTF _snprintf - #define TIXML_SNSCANF _snscanf - #define TIXML_SSCANF sscanf - #elif defined(__GNUC__) && (__GNUC__ >= 3 ) - // GCC version 3 and higher.s - //#warning( "Using sn* functions." ) - #define TIXML_SNPRINTF snprintf - #define TIXML_SNSCANF snscanf - #define TIXML_SSCANF sscanf - #else - #define TIXML_SSCANF sscanf - #endif -#endif - -class TiXmlDocument; -class TiXmlElement; -class TiXmlComment; -class TiXmlUnknown; -class TiXmlAttribute; -class TiXmlText; -class TiXmlDeclaration; -class TiXmlParsingData; - -const int TIXML_MAJOR_VERSION = 2; -const int TIXML_MINOR_VERSION = 5; -const int TIXML_PATCH_VERSION = 3; - -/* Internal structure for tracking location of items - in the XML file. -*/ -struct TiXmlCursor -{ - TiXmlCursor() { Clear(); } - void Clear() { row = col = -1; } - - int row; // 0 based. - int col; // 0 based. -}; - - -/** - If you call the Accept() method, it requires being passed a TiXmlVisitor - class to handle callbacks. For nodes that contain other nodes (Document, Element) - you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves - are simple called with Visit(). - - If you return 'true' from a Visit method, recursive parsing will continue. If you return - false, <b>no children of this node or its sibilings</b> will be Visited. - - All flavors of Visit methods have a default implementation that returns 'true' (continue - visiting). You need to only override methods that are interesting to you. - - Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting. - - You should never change the document from a callback. - - @sa TiXmlNode::Accept() -*/ -class TiXmlVisitor -{ -public: - virtual ~TiXmlVisitor() {} - - /// Visit a document. - virtual bool VisitEnter( const TiXmlDocument& /*doc*/ ) { return true; } - /// Visit a document. - virtual bool VisitExit( const TiXmlDocument& /*doc*/ ) { return true; } - - /// Visit an element. - virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ ) { return true; } - /// Visit an element. - virtual bool VisitExit( const TiXmlElement& /*element*/ ) { return true; } - - /// Visit a declaration - virtual bool Visit( const TiXmlDeclaration& /*declaration*/ ) { return true; } - /// Visit a text node - virtual bool Visit( const TiXmlText& /*text*/ ) { return true; } - /// Visit a comment node - virtual bool Visit( const TiXmlComment& /*comment*/ ) { return true; } - /// Visit an unknow node - virtual bool Visit( const TiXmlUnknown& /*unknown*/ ) { return true; } -}; - -// Only used by Attribute::Query functions -enum -{ - TIXML_SUCCESS, - TIXML_NO_ATTRIBUTE, - TIXML_WRONG_TYPE -}; - - -// Used by the parsing routines. -enum TiXmlEncoding -{ - TIXML_ENCODING_UNKNOWN, - TIXML_ENCODING_UTF8, - TIXML_ENCODING_LEGACY -}; - -const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN; - -/** TiXmlBase is a base class for every class in TinyXml. - It does little except to establish that TinyXml classes - can be printed and provide some utility functions. - - In XML, the document and elements can contain - other elements and other types of nodes. - - @verbatim - A Document can contain: Element (container or leaf) - Comment (leaf) - Unknown (leaf) - Declaration( leaf ) - - An Element can contain: Element (container or leaf) - Text (leaf) - Attributes (not on tree) - Comment (leaf) - Unknown (leaf) - - A Decleration contains: Attributes (not on tree) - @endverbatim -*/ -class TiXmlBase -{ - friend class TiXmlNode; - friend class TiXmlElement; - friend class TiXmlDocument; - -public: - TiXmlBase() : userData(0) {} - virtual ~TiXmlBase() {} - - /** All TinyXml classes can print themselves to a filestream - or the string class (TiXmlString in non-STL mode, std::string - in STL mode.) Either or both cfile and str can be null. - - This is a formatted print, and will insert - tabs and newlines. - - (For an unformatted stream, use the << operator.) - */ - virtual void Print( FILE* cfile, int depth ) const = 0; - - /** The world does not agree on whether white space should be kept or - not. In order to make everyone happy, these global, static functions - are provided to set whether or not TinyXml will condense all white space - into a single space or not. The default is to condense. Note changing this - value is not thread safe. - */ - static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; } - - /// Return the current white space setting. - static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; } - - /** Return the position, in the original source file, of this node or attribute. - The row and column are 1-based. (That is the first row and first column is - 1,1). If the returns values are 0 or less, then the parser does not have - a row and column value. - - Generally, the row and column value will be set when the TiXmlDocument::Load(), - TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set - when the DOM was created from operator>>. - - The values reflect the initial load. Once the DOM is modified programmatically - (by adding or changing nodes and attributes) the new values will NOT update to - reflect changes in the document. - - There is a minor performance cost to computing the row and column. Computation - can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value. - - @sa TiXmlDocument::SetTabSize() - */ - int Row() const { return location.row + 1; } - int Column() const { return location.col + 1; } ///< See Row() - - void SetUserData( void* user ) { userData = user; } ///< Set a pointer to arbitrary user data. - void* GetUserData() { return userData; } ///< Get a pointer to arbitrary user data. - const void* GetUserData() const { return userData; } ///< Get a pointer to arbitrary user data. - - // Table that returs, for a given lead byte, the total number of bytes - // in the UTF-8 sequence. - static const int utf8ByteTable[256]; - - virtual const char* Parse( const char* p, - TiXmlParsingData* data, - TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0; - - /** Expands entities in a string. Note this should not contian the tag's '<', '>', etc, - or they will be transformed into entities! - */ - static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out ); - - enum - { - TIXML_NO_ERROR = 0, - TIXML_ERROR, - TIXML_ERROR_OPENING_FILE, - TIXML_ERROR_OUT_OF_MEMORY, - TIXML_ERROR_PARSING_ELEMENT, - TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, - TIXML_ERROR_READING_ELEMENT_VALUE, - TIXML_ERROR_READING_ATTRIBUTES, - TIXML_ERROR_PARSING_EMPTY, - TIXML_ERROR_READING_END_TAG, - TIXML_ERROR_PARSING_UNKNOWN, - TIXML_ERROR_PARSING_COMMENT, - TIXML_ERROR_PARSING_DECLARATION, - TIXML_ERROR_DOCUMENT_EMPTY, - TIXML_ERROR_EMBEDDED_NULL, - TIXML_ERROR_PARSING_CDATA, - TIXML_ERROR_DOCUMENT_TOP_ONLY, - - TIXML_ERROR_STRING_COUNT - }; - -protected: - - static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding ); - inline static bool IsWhiteSpace( char c ) - { - return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); - } - inline static bool IsWhiteSpace( int c ) - { - if ( c < 256 ) - return IsWhiteSpace( (char) c ); - return false; // Again, only truly correct for English/Latin...but usually works. - } - - #ifdef TIXML_USE_STL - static bool StreamWhiteSpace( std::istream * in, TIXML_STRING * tag ); - static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag ); - #endif - - /* Reads an XML name into the string provided. Returns - a pointer just past the last character of the name, - or 0 if the function has an error. - */ - static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding ); - - /* Reads text. Returns a pointer past the given end tag. - Wickedly complex options, but it keeps the (sensitive) code in one place. - */ - static const char* ReadText( const char* in, // where to start - TIXML_STRING* text, // the string read - bool ignoreWhiteSpace, // whether to keep the white space - const char* endTag, // what ends this text - bool ignoreCase, // whether to ignore case in the end tag - TiXmlEncoding encoding ); // the current encoding - - // If an entity has been found, transform it into a character. - static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding ); - - // Get a character, while interpreting entities. - // The length can be from 0 to 4 bytes. - inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding ) - { - assert( p ); - if ( encoding == TIXML_ENCODING_UTF8 ) - { - *length = utf8ByteTable[ *((const unsigned char*)p) ]; - assert( *length >= 0 && *length < 5 ); - } - else - { - *length = 1; - } - - if ( *length == 1 ) - { - if ( *p == '&' ) - return GetEntity( p, _value, length, encoding ); - *_value = *p; - return p+1; - } - else if ( *length ) - { - //strncpy( _value, p, *length ); // lots of compilers don't like this function (unsafe), - // and the null terminator isn't needed - for( int i=0; p[i] && i<*length; ++i ) { - _value[i] = p[i]; - } - return p + (*length); - } - else - { - // Not valid text. - return 0; - } - } - - // Return true if the next characters in the stream are any of the endTag sequences. - // Ignore case only works for english, and should only be relied on when comparing - // to English words: StringEqual( p, "version", true ) is fine. - static bool StringEqual( const char* p, - const char* endTag, - bool ignoreCase, - TiXmlEncoding encoding ); - - static const char* errorString[ TIXML_ERROR_STRING_COUNT ]; - - TiXmlCursor location; - - /// Field containing a generic user pointer - void* userData; - - // None of these methods are reliable for any language except English. - // Good for approximation, not great for accuracy. - static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding ); - static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding ); - inline static int ToLower( int v, TiXmlEncoding encoding ) - { - if ( encoding == TIXML_ENCODING_UTF8 ) - { - if ( v < 128 ) return tolower( v ); - return v; - } - else - { - return tolower( v ); - } - } - static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); - -private: - TiXmlBase( const TiXmlBase& ); // not implemented. - void operator=( const TiXmlBase& base ); // not allowed. - - struct Entity - { - const char* str; - unsigned int strLength; - char chr; - }; - enum - { - NUM_ENTITY = 5, - MAX_ENTITY_LENGTH = 6 - - }; - static Entity entity[ NUM_ENTITY ]; - static bool condenseWhiteSpace; -}; - - -/** The parent class for everything in the Document Object Model. - (Except for attributes). - Nodes have siblings, a parent, and children. A node can be - in a document, or stand on its own. The type of a TiXmlNode - can be queried, and it can be cast to its more defined type. -*/ -class TiXmlNode : public TiXmlBase -{ - friend class TiXmlDocument; - friend class TiXmlElement; - -public: - #ifdef TIXML_USE_STL - - /** An input stream operator, for every class. Tolerant of newlines and - formatting, but doesn't expect them. - */ - friend std::istream& operator >> (std::istream& in, TiXmlNode& base); - - /** An output stream operator, for every class. Note that this outputs - without any newlines or formatting, as opposed to Print(), which - includes tabs and new lines. - - The operator<< and operator>> are not completely symmetric. Writing - a node to a stream is very well defined. You'll get a nice stream - of output, without any extra whitespace or newlines. - - But reading is not as well defined. (As it always is.) If you create - a TiXmlElement (for example) and read that from an input stream, - the text needs to define an element or junk will result. This is - true of all input streams, but it's worth keeping in mind. - - A TiXmlDocument will read nodes until it reads a root element, and - all the children of that root element. - */ - friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base); - - /// Appends the XML node or attribute to a std::string. - friend std::string& operator<< (std::string& out, const TiXmlNode& base ); - - #endif - - /** The types of XML nodes supported by TinyXml. (All the - unsupported types are picked up by UNKNOWN.) - */ - enum NodeType - { - DOCUMENT, - ELEMENT, - COMMENT, - UNKNOWN, - TEXT, - DECLARATION, - TYPECOUNT - }; - - virtual ~TiXmlNode(); - - /** The meaning of 'value' changes for the specific type of - TiXmlNode. - @verbatim - Document: filename of the xml file - Element: name of the element - Comment: the comment text - Unknown: the tag contents - Text: the text string - @endverbatim - - The subclasses will wrap this function. - */ - const char *Value() const { return value.c_str (); } - - #ifdef TIXML_USE_STL - /** Return Value() as a std::string. If you only use STL, - this is more efficient than calling Value(). - Only available in STL mode. - */ - const std::string& ValueStr() const { return value; } - #endif - - const TIXML_STRING& ValueTStr() const { return value; } - - /** Changes the value of the node. Defined as: - @verbatim - Document: filename of the xml file - Element: name of the element - Comment: the comment text - Unknown: the tag contents - Text: the text string - @endverbatim - */ - void SetValue(const char * _value) { value = _value;} - - #ifdef TIXML_USE_STL - /// STL std::string form. - void SetValue( const std::string& _value ) { value = _value; } - #endif - - /// Delete all the children of this node. Does not affect 'this'. - void Clear(); - - /// One step up the DOM. - TiXmlNode* Parent() { return parent; } - const TiXmlNode* Parent() const { return parent; } - - const TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children. - TiXmlNode* FirstChild() { return firstChild; } - const TiXmlNode* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found. - /// The first child of this node with the matching 'value'. Will be null if none found. - TiXmlNode* FirstChild( const char * _value ) { - // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe) - // call the method, cast the return back to non-const. - return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value )); - } - const TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children. - TiXmlNode* LastChild() { return lastChild; } - - const TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children. - TiXmlNode* LastChild( const char * _value ) { - return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value )); - } - - #ifdef TIXML_USE_STL - const TiXmlNode* FirstChild( const std::string& _value ) const { return FirstChild (_value.c_str ()); } ///< STL std::string form. - TiXmlNode* FirstChild( const std::string& _value ) { return FirstChild (_value.c_str ()); } ///< STL std::string form. - const TiXmlNode* LastChild( const std::string& _value ) const { return LastChild (_value.c_str ()); } ///< STL std::string form. - TiXmlNode* LastChild( const std::string& _value ) { return LastChild (_value.c_str ()); } ///< STL std::string form. - #endif - - /** An alternate way to walk the children of a node. - One way to iterate over nodes is: - @verbatim - for( child = parent->FirstChild(); child; child = child->NextSibling() ) - @endverbatim - - IterateChildren does the same thing with the syntax: - @verbatim - child = 0; - while( child = parent->IterateChildren( child ) ) - @endverbatim - - IterateChildren takes the previous child as input and finds - the next one. If the previous child is null, it returns the - first. IterateChildren will return null when done. - */ - const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const; - TiXmlNode* IterateChildren( const TiXmlNode* previous ) { - return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) ); - } - - /// This flavor of IterateChildren searches for children with a particular 'value' - const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const; - TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) { - return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) ); - } - - #ifdef TIXML_USE_STL - const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. - TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. - #endif - - /** Add a new node related to this. Adds a child past the LastChild. - Returns a pointer to the new object or NULL if an error occured. - */ - TiXmlNode* InsertEndChild( const TiXmlNode& addThis ); - - - /** Add a new node related to this. Adds a child past the LastChild. - - NOTE: the node to be added is passed by pointer, and will be - henceforth owned (and deleted) by tinyXml. This method is efficient - and avoids an extra copy, but should be used with care as it - uses a different memory model than the other insert functions. - - @sa InsertEndChild - */ - TiXmlNode* LinkEndChild( TiXmlNode* addThis ); - - /** Add a new node related to this. Adds a child before the specified child. - Returns a pointer to the new object or NULL if an error occured. - */ - TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ); - - /** Add a new node related to this. Adds a child after the specified child. - Returns a pointer to the new object or NULL if an error occured. - */ - TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ); - - /** Replace a child of this node. - Returns a pointer to the new object or NULL if an error occured. - */ - TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ); - - /// Delete a child of this node. - bool RemoveChild( TiXmlNode* removeThis ); - - /// Navigate to a sibling node. - const TiXmlNode* PreviousSibling() const { return prev; } - TiXmlNode* PreviousSibling() { return prev; } - - /// Navigate to a sibling node. - const TiXmlNode* PreviousSibling( const char * ) const; - TiXmlNode* PreviousSibling( const char *_prev ) { - return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) ); - } - - #ifdef TIXML_USE_STL - const TiXmlNode* PreviousSibling( const std::string& _value ) const { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. - TiXmlNode* PreviousSibling( const std::string& _value ) { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. - const TiXmlNode* NextSibling( const std::string& _value) const { return NextSibling (_value.c_str ()); } ///< STL std::string form. - TiXmlNode* NextSibling( const std::string& _value) { return NextSibling (_value.c_str ()); } ///< STL std::string form. - #endif - - /// Navigate to a sibling node. - const TiXmlNode* NextSibling() const { return next; } - TiXmlNode* NextSibling() { return next; } - - /// Navigate to a sibling node with the given 'value'. - const TiXmlNode* NextSibling( const char * ) const; - TiXmlNode* NextSibling( const char* _next ) { - return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) ); - } - - /** Convenience function to get through elements. - Calls NextSibling and ToElement. Will skip all non-Element - nodes. Returns 0 if there is not another element. - */ - const TiXmlElement* NextSiblingElement() const; - TiXmlElement* NextSiblingElement() { - return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() ); - } - - /** Convenience function to get through elements. - Calls NextSibling and ToElement. Will skip all non-Element - nodes. Returns 0 if there is not another element. - */ - const TiXmlElement* NextSiblingElement( const char * ) const; - TiXmlElement* NextSiblingElement( const char *_next ) { - return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) ); - } - - #ifdef TIXML_USE_STL - const TiXmlElement* NextSiblingElement( const std::string& _value) const { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. - TiXmlElement* NextSiblingElement( const std::string& _value) { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. - #endif - - /// Convenience function to get through elements. - const TiXmlElement* FirstChildElement() const; - TiXmlElement* FirstChildElement() { - return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() ); - } - - /// Convenience function to get through elements. - const TiXmlElement* FirstChildElement( const char * _value ) const; - TiXmlElement* FirstChildElement( const char * _value ) { - return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) ); - } - - #ifdef TIXML_USE_STL - const TiXmlElement* FirstChildElement( const std::string& _value ) const { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. - TiXmlElement* FirstChildElement( const std::string& _value ) { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. - #endif - - /** Query the type (as an enumerated value, above) of this node. - The possible types are: DOCUMENT, ELEMENT, COMMENT, - UNKNOWN, TEXT, and DECLARATION. - */ - int Type() const { return type; } - - /** Return a pointer to the Document this node lives in. - Returns null if not in a document. - */ - const TiXmlDocument* GetDocument() const; - TiXmlDocument* GetDocument() { - return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() ); - } - - /// Returns true if this node has no children. - bool NoChildren() const { return !firstChild; } - - virtual const TiXmlDocument* ToDocument() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual const TiXmlElement* ToElement() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual const TiXmlComment* ToComment() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual const TiXmlUnknown* ToUnknown() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual const TiXmlText* ToText() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - - virtual TiXmlDocument* ToDocument() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual TiXmlElement* ToElement() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual TiXmlComment* ToComment() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual TiXmlUnknown* ToUnknown() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual TiXmlText* ToText() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - virtual TiXmlDeclaration* ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. - - /** Create an exact duplicate of this node and return it. The memory must be deleted - by the caller. - */ - virtual TiXmlNode* Clone() const = 0; - - /** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the - XML tree will be conditionally visited and the host will be called back - via the TiXmlVisitor interface. - - This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse - the XML for the callbacks, so the performance of TinyXML is unchanged by using this - interface versus any other.) - - The interface has been based on ideas from: - - - http://www.saxproject.org/ - - http://c2.com/cgi/wiki?HierarchicalVisitorPattern - - Which are both good references for "visiting". - - An example of using Accept(): - @verbatim - TiXmlPrinter printer; - tinyxmlDoc.Accept( &printer ); - const char* xmlcstr = printer.CStr(); - @endverbatim - */ - virtual bool Accept( TiXmlVisitor* visitor ) const = 0; - -protected: - TiXmlNode( NodeType _type ); - - // Copy to the allocated object. Shared functionality between Clone, Copy constructor, - // and the assignment operator. - void CopyTo( TiXmlNode* target ) const; - - #ifdef TIXML_USE_STL - // The real work of the input operator. - virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0; - #endif - - // Figure out what is at *p, and parse it. Returns null if it is not an xml node. - TiXmlNode* Identify( const char* start, TiXmlEncoding encoding ); - - TiXmlNode* parent; - NodeType type; - - TiXmlNode* firstChild; - TiXmlNode* lastChild; - - TIXML_STRING value; - - TiXmlNode* prev; - TiXmlNode* next; - -private: - TiXmlNode( const TiXmlNode& ); // not implemented. - void operator=( const TiXmlNode& base ); // not allowed. -}; - - -/** An attribute is a name-value pair. Elements have an arbitrary - number of attributes, each with a unique name. - - @note The attributes are not TiXmlNodes, since they are not - part of the tinyXML document object model. There are other - suggested ways to look at this problem. -*/ -class TiXmlAttribute : public TiXmlBase -{ - friend class TiXmlAttributeSet; - -public: - /// Construct an empty attribute. - TiXmlAttribute() : TiXmlBase() - { - document = 0; - prev = next = 0; - } - - #ifdef TIXML_USE_STL - /// std::string constructor. - TiXmlAttribute( const std::string& _name, const std::string& _value ) - { - name = _name; - value = _value; - document = 0; - prev = next = 0; - } - #endif - - /// Construct an attribute with a name and value. - TiXmlAttribute( const char * _name, const char * _value ) - { - name = _name; - value = _value; - document = 0; - prev = next = 0; - } - - const char* Name() const { return name.c_str(); } ///< Return the name of this attribute. - const char* Value() const { return value.c_str(); } ///< Return the value of this attribute. - #ifdef TIXML_USE_STL - const std::string& ValueStr() const { return value; } ///< Return the value of this attribute. - #endif - int IntValue() const; ///< Return the value of this attribute, converted to an integer. - double DoubleValue() const; ///< Return the value of this attribute, converted to a double. - - // Get the tinyxml string representation - const TIXML_STRING& NameTStr() const { return name; } - - /** QueryIntValue examines the value string. It is an alternative to the - IntValue() method with richer error checking. - If the value is an integer, it is stored in 'value' and - the call returns TIXML_SUCCESS. If it is not - an integer, it returns TIXML_WRONG_TYPE. - - A specialized but useful call. Note that for success it returns 0, - which is the opposite of almost all other TinyXml calls. - */ - int QueryIntValue( int* _value ) const; - /// QueryDoubleValue examines the value string. See QueryIntValue(). - int QueryDoubleValue( double* _value ) const; - - void SetName( const char* _name ) { name = _name; } ///< Set the name of this attribute. - void SetValue( const char* _value ) { value = _value; } ///< Set the value. - - void SetIntValue( int _value ); ///< Set the value from an integer. - void SetDoubleValue( double _value ); ///< Set the value from a double. - - #ifdef TIXML_USE_STL - /// STL std::string form. - void SetName( const std::string& _name ) { name = _name; } - /// STL std::string form. - void SetValue( const std::string& _value ) { value = _value; } - #endif - - /// Get the next sibling attribute in the DOM. Returns null at end. - const TiXmlAttribute* Next() const; - TiXmlAttribute* Next() { - return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); - } - - /// Get the previous sibling attribute in the DOM. Returns null at beginning. - const TiXmlAttribute* Previous() const; - TiXmlAttribute* Previous() { - return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); - } - - bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; } - bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; } - bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; } - - /* Attribute parsing starts: first letter of the name - returns: the next char after the value end quote - */ - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - // Prints this Attribute to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const { - Print( cfile, depth, 0 ); - } - void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; - - // [internal use] - // Set the document pointer so the attribute can report errors. - void SetDocument( TiXmlDocument* doc ) { document = doc; } - -private: - TiXmlAttribute( const TiXmlAttribute& ); // not implemented. - void operator=( const TiXmlAttribute& base ); // not allowed. - - TiXmlDocument* document; // A pointer back to a document, for error reporting. - TIXML_STRING name; - TIXML_STRING value; - TiXmlAttribute* prev; - TiXmlAttribute* next; -}; - - -/* A class used to manage a group of attributes. - It is only used internally, both by the ELEMENT and the DECLARATION. - - The set can be changed transparent to the Element and Declaration - classes that use it, but NOT transparent to the Attribute - which has to implement a next() and previous() method. Which makes - it a bit problematic and prevents the use of STL. - - This version is implemented with circular lists because: - - I like circular lists - - it demonstrates some independence from the (typical) doubly linked list. -*/ -class TiXmlAttributeSet -{ -public: - TiXmlAttributeSet(); - ~TiXmlAttributeSet(); - - void Add( TiXmlAttribute* attribute ); - void Remove( TiXmlAttribute* attribute ); - - const TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } - TiXmlAttribute* First() { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } - const TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } - TiXmlAttribute* Last() { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } - - const TiXmlAttribute* Find( const char* _name ) const; - TiXmlAttribute* Find( const char* _name ) { - return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) ); - } - #ifdef TIXML_USE_STL - const TiXmlAttribute* Find( const std::string& _name ) const; - TiXmlAttribute* Find( const std::string& _name ) { - return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) ); - } - - #endif - -private: - //*ME: Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element), - //*ME: this class must be also use a hidden/disabled copy-constructor !!! - TiXmlAttributeSet( const TiXmlAttributeSet& ); // not allowed - void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute) - - TiXmlAttribute sentinel; -}; - - -/** The element is a container class. It has a value, the element name, - and can contain other elements, text, comments, and unknowns. - Elements also contain an arbitrary number of attributes. -*/ -class TiXmlElement : public TiXmlNode -{ -public: - /// Construct an element. - TiXmlElement (const char * in_value); - - #ifdef TIXML_USE_STL - /// std::string constructor. - TiXmlElement( const std::string& _value ); - #endif - - TiXmlElement( const TiXmlElement& ); - - void operator=( const TiXmlElement& base ); - - virtual ~TiXmlElement(); - - /** Given an attribute name, Attribute() returns the value - for the attribute of that name, or null if none exists. - */ - const char* Attribute( const char* name ) const; - - /** Given an attribute name, Attribute() returns the value - for the attribute of that name, or null if none exists. - If the attribute exists and can be converted to an integer, - the integer value will be put in the return 'i', if 'i' - is non-null. - */ - const char* Attribute( const char* name, int* i ) const; - - /** Given an attribute name, Attribute() returns the value - for the attribute of that name, or null if none exists. - If the attribute exists and can be converted to an double, - the double value will be put in the return 'd', if 'd' - is non-null. - */ - const char* Attribute( const char* name, double* d ) const; - - /** QueryIntAttribute examines the attribute - it is an alternative to the - Attribute() method with richer error checking. - If the attribute is an integer, it is stored in 'value' and - the call returns TIXML_SUCCESS. If it is not - an integer, it returns TIXML_WRONG_TYPE. If the attribute - does not exist, then TIXML_NO_ATTRIBUTE is returned. - */ - int QueryIntAttribute( const char* name, int* _value ) const; - /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute(). - int QueryDoubleAttribute( const char* name, double* _value ) const; - /// QueryFloatAttribute examines the attribute - see QueryIntAttribute(). - int QueryFloatAttribute( const char* name, float* _value ) const { - double d; - int result = QueryDoubleAttribute( name, &d ); - if ( result == TIXML_SUCCESS ) { - *_value = (float)d; - } - return result; - } - - #ifdef TIXML_USE_STL - /** Template form of the attribute query which will try to read the - attribute into the specified type. Very easy, very powerful, but - be careful to make sure to call this with the correct type. - - NOTE: This method doesn't work correctly for 'string' types. - - @return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE - */ - template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const - { - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( !node ) - return TIXML_NO_ATTRIBUTE; - - std::stringstream sstream( node->ValueStr() ); - sstream >> *outValue; - if ( !sstream.fail() ) - return TIXML_SUCCESS; - return TIXML_WRONG_TYPE; - } - /* - This is - in theory - a bug fix for "QueryValueAtribute returns truncated std::string" - but template specialization is hard to get working cross-compiler. Leaving the bug for now. - - // The above will fail for std::string because the space character is used as a seperator. - // Specialize for strings. Bug [ 1695429 ] QueryValueAtribute returns truncated std::string - template<> int QueryValueAttribute( const std::string& name, std::string* outValue ) const - { - const TiXmlAttribute* node = attributeSet.Find( name ); - if ( !node ) - return TIXML_NO_ATTRIBUTE; - *outValue = node->ValueStr(); - return TIXML_SUCCESS; - } - */ - #endif - - /** Sets an attribute of name to a given value. The attribute - will be created if it does not exist, or changed if it does. - */ - void SetAttribute( const char* name, const char * _value ); - - #ifdef TIXML_USE_STL - const std::string* Attribute( const std::string& name ) const; - const std::string* Attribute( const std::string& name, int* i ) const; - const std::string* Attribute( const std::string& name, double* d ) const; - int QueryIntAttribute( const std::string& name, int* _value ) const; - int QueryDoubleAttribute( const std::string& name, double* _value ) const; - - /// STL std::string form. - void SetAttribute( const std::string& name, const std::string& _value ); - ///< STL std::string form. - void SetAttribute( const std::string& name, int _value ); - #endif - - /** Sets an attribute of name to a given value. The attribute - will be created if it does not exist, or changed if it does. - */ - void SetAttribute( const char * name, int value ); - - /** Sets an attribute of name to a given value. The attribute - will be created if it does not exist, or changed if it does. - */ - void SetDoubleAttribute( const char * name, double value ); - - /** Deletes an attribute with the given name. - */ - void RemoveAttribute( const char * name ); - #ifdef TIXML_USE_STL - void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); } ///< STL std::string form. - #endif - - const TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element. - TiXmlAttribute* FirstAttribute() { return attributeSet.First(); } - const TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); } ///< Access the last attribute in this element. - TiXmlAttribute* LastAttribute() { return attributeSet.Last(); } - - /** Convenience function for easy access to the text inside an element. Although easy - and concise, GetText() is limited compared to getting the TiXmlText child - and accessing it directly. - - If the first child of 'this' is a TiXmlText, the GetText() - returns the character string of the Text node, else null is returned. - - This is a convenient method for getting the text of simple contained text: - @verbatim - <foo>This is text</foo> - const char* str = fooElement->GetText(); - @endverbatim - - 'str' will be a pointer to "This is text". - - Note that this function can be misleading. If the element foo was created from - this XML: - @verbatim - <foo><b>This is text</b></foo> - @endverbatim - - then the value of str would be null. The first child node isn't a text node, it is - another element. From this XML: - @verbatim - <foo>This is <b>text</b></foo> - @endverbatim - GetText() will return "This is ". - - WARNING: GetText() accesses a child node - don't become confused with the - similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are - safe type casts on the referenced node. - */ - const char* GetText() const; - - /// Creates a new Element and returns it - the returned element is a copy. - virtual TiXmlNode* Clone() const; - // Print the Element to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const; - - /* Attribtue parsing starts: next char past '<' - returns: next char past '>' - */ - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - virtual const TiXmlElement* ToElement() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlElement* ToElement() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* visitor ) const; - -protected: - - void CopyTo( TiXmlElement* target ) const; - void ClearThis(); // like clear, but initializes 'this' object as well - - // Used to be public [internal use] - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif - /* [internal use] - Reads the "value" of the element -- another element, or text. - This should terminate with the current end tag. - */ - const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding ); - -private: - - TiXmlAttributeSet attributeSet; -}; - - -/** An XML comment. -*/ -class TiXmlComment : public TiXmlNode -{ -public: - /// Constructs an empty comment. - TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {} - /// Construct a comment from text. - TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::COMMENT ) { - SetValue( _value ); - } - TiXmlComment( const TiXmlComment& ); - void operator=( const TiXmlComment& base ); - - virtual ~TiXmlComment() {} - - /// Returns a copy of this Comment. - virtual TiXmlNode* Clone() const; - // Write this Comment to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const; - - /* Attribtue parsing starts: at the ! of the !-- - returns: next char past '>' - */ - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - virtual const TiXmlComment* ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlComment* ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* visitor ) const; - -protected: - void CopyTo( TiXmlComment* target ) const; - - // used to be public - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif -// virtual void StreamOut( TIXML_OSTREAM * out ) const; - -private: - -}; - - -/** XML text. A text node can have 2 ways to output the next. "normal" output - and CDATA. It will default to the mode it was parsed from the XML file and - you generally want to leave it alone, but you can change the output mode with - SetCDATA() and query it with CDATA(). -*/ -class TiXmlText : public TiXmlNode -{ - friend class TiXmlElement; -public: - /** Constructor for text element. By default, it is treated as - normal, encoded text. If you want it be output as a CDATA text - element, set the parameter _cdata to 'true' - */ - TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TEXT) - { - SetValue( initValue ); - cdata = false; - } - virtual ~TiXmlText() {} - - #ifdef TIXML_USE_STL - /// Constructor. - TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT) - { - SetValue( initValue ); - cdata = false; - } - #endif - - TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT ) { copy.CopyTo( this ); } - void operator=( const TiXmlText& base ) { base.CopyTo( this ); } - - // Write this text object to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const; - - /// Queries whether this represents text using a CDATA section. - bool CDATA() const { return cdata; } - /// Turns on or off a CDATA representation of text. - void SetCDATA( bool _cdata ) { cdata = _cdata; } - - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlText* ToText() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* content ) const; - -protected : - /// [internal use] Creates a new Element and returns it. - virtual TiXmlNode* Clone() const; - void CopyTo( TiXmlText* target ) const; - - bool Blank() const; // returns true if all white space and new lines - // [internal use] - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif - -private: - bool cdata; // true if this should be input and output as a CDATA style text element -}; - - -/** In correct XML the declaration is the first entry in the file. - @verbatim - <?xml version="1.0" standalone="yes"?> - @endverbatim - - TinyXml will happily read or write files without a declaration, - however. There are 3 possible attributes to the declaration: - version, encoding, and standalone. - - Note: In this version of the code, the attributes are - handled as special cases, not generic attributes, simply - because there can only be at most 3 and they are always the same. -*/ -class TiXmlDeclaration : public TiXmlNode -{ -public: - /// Construct an empty declaration. - TiXmlDeclaration() : TiXmlNode( TiXmlNode::DECLARATION ) {} - -#ifdef TIXML_USE_STL - /// Constructor. - TiXmlDeclaration( const std::string& _version, - const std::string& _encoding, - const std::string& _standalone ); -#endif - - /// Construct. - TiXmlDeclaration( const char* _version, - const char* _encoding, - const char* _standalone ); - - TiXmlDeclaration( const TiXmlDeclaration& copy ); - void operator=( const TiXmlDeclaration& copy ); - - virtual ~TiXmlDeclaration() {} - - /// Version. Will return an empty string if none was found. - const char *Version() const { return version.c_str (); } - /// Encoding. Will return an empty string if none was found. - const char *Encoding() const { return encoding.c_str (); } - /// Is this a standalone document? - const char *Standalone() const { return standalone.c_str (); } - - /// Creates a copy of this Declaration and returns it. - virtual TiXmlNode* Clone() const; - // Print this declaration to a FILE stream. - virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; - virtual void Print( FILE* cfile, int depth ) const { - Print( cfile, depth, 0 ); - } - - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlDeclaration* ToDeclaration() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* visitor ) const; - -protected: - void CopyTo( TiXmlDeclaration* target ) const; - // used to be public - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif - -private: - - TIXML_STRING version; - TIXML_STRING encoding; - TIXML_STRING standalone; -}; - - -/** Any tag that tinyXml doesn't recognize is saved as an - unknown. It is a tag of text, but should not be modified. - It will be written back to the XML, unchanged, when the file - is saved. - - DTD tags get thrown into TiXmlUnknowns. -*/ -class TiXmlUnknown : public TiXmlNode -{ -public: - TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {} - virtual ~TiXmlUnknown() {} - - TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN ) { copy.CopyTo( this ); } - void operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); } - - /// Creates a copy of this Unknown and returns it. - virtual TiXmlNode* Clone() const; - // Print this Unknown to a FILE stream. - virtual void Print( FILE* cfile, int depth ) const; - - virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); - - virtual const TiXmlUnknown* ToUnknown() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlUnknown* ToUnknown() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* content ) const; - -protected: - void CopyTo( TiXmlUnknown* target ) const; - - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif - -private: - -}; - - -/** Always the top level node. A document binds together all the - XML pieces. It can be saved, loaded, and printed to the screen. - The 'value' of a document node is the xml file name. -*/ -class TiXmlDocument : public TiXmlNode -{ -public: - /// Create an empty document, that has no name. - TiXmlDocument(); - /// Create a document with a name. The name of the document is also the filename of the xml. - TiXmlDocument( const char * documentName ); - - #ifdef TIXML_USE_STL - /// Constructor. - TiXmlDocument( const std::string& documentName ); - #endif - - TiXmlDocument( const TiXmlDocument& copy ); - void operator=( const TiXmlDocument& copy ); - - virtual ~TiXmlDocument() {} - - /** Load a file using the current document value. - Returns true if successful. Will delete any existing - document data before loading. - */ - bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); - /// Save a file using the current document value. Returns true if successful. - bool SaveFile() const; - /// Load a file using the given filename. Returns true if successful. - bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); - /// Save a file using the given filename. Returns true if successful. - bool SaveFile( const char * filename ) const; - /** Load a file using the given FILE*. Returns true if successful. Note that this method - doesn't stream - the entire object pointed at by the FILE* - will be interpreted as an XML file. TinyXML doesn't stream in XML from the current - file location. Streaming may be added in the future. - */ - bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); - /// Save a file using the given FILE*. Returns true if successful. - bool SaveFile( FILE* ) const; - - #ifdef TIXML_USE_STL - bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL std::string version. - { -// StringToBuffer f( filename ); -// return ( f.buffer && LoadFile( f.buffer, encoding )); - return LoadFile( filename.c_str(), encoding ); - } - bool SaveFile( const std::string& filename ) const ///< STL std::string version. - { -// StringToBuffer f( filename ); -// return ( f.buffer && SaveFile( f.buffer )); - return SaveFile( filename.c_str() ); - } - #endif - - /** Parse the given null terminated block of xml data. Passing in an encoding to this - method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml - to use that encoding, regardless of what TinyXml might otherwise try to detect. - */ - virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); - - /** Get the root element -- the only top level element -- of the document. - In well formed XML, there should only be one. TinyXml is tolerant of - multiple elements at the document level. - */ - const TiXmlElement* RootElement() const { return FirstChildElement(); } - TiXmlElement* RootElement() { return FirstChildElement(); } - - /** If an error occurs, Error will be set to true. Also, - - The ErrorId() will contain the integer identifier of the error (not generally useful) - - The ErrorDesc() method will return the name of the error. (very useful) - - The ErrorRow() and ErrorCol() will return the location of the error (if known) - */ - bool Error() const { return error; } - - /// Contains a textual (english) description of the error if one occurs. - const char * ErrorDesc() const { return errorDesc.c_str (); } - - /** Generally, you probably want the error string ( ErrorDesc() ). But if you - prefer the ErrorId, this function will fetch it. - */ - int ErrorId() const { return errorId; } - - /** Returns the location (if known) of the error. The first column is column 1, - and the first row is row 1. A value of 0 means the row and column wasn't applicable - (memory errors, for example, have no row/column) or the parser lost the error. (An - error in the error reporting, in that case.) - - @sa SetTabSize, Row, Column - */ - int ErrorRow() const { return errorLocation.row+1; } - int ErrorCol() const { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow() - - /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol()) - to report the correct values for row and column. It does not change the output - or input in any way. - - By calling this method, with a tab size - greater than 0, the row and column of each node and attribute is stored - when the file is loaded. Very useful for tracking the DOM back in to - the source file. - - The tab size is required for calculating the location of nodes. If not - set, the default of 4 is used. The tabsize is set per document. Setting - the tabsize to 0 disables row/column tracking. - - Note that row and column tracking is not supported when using operator>>. - - The tab size needs to be enabled before the parse or load. Correct usage: - @verbatim - TiXmlDocument doc; - doc.SetTabSize( 8 ); - doc.Load( "myfile.xml" ); - @endverbatim - - @sa Row, Column - */ - void SetTabSize( int _tabsize ) { tabsize = _tabsize; } - - int TabSize() const { return tabsize; } - - /** If you have handled the error, it can be reset with this call. The error - state is automatically cleared if you Parse a new XML block. - */ - void ClearError() { error = false; - errorId = 0; - errorDesc = ""; - errorLocation.row = errorLocation.col = 0; - //errorLocation.last = 0; - } - - /** Write the document to standard out using formatted printing ("pretty print"). */ - void Print() const { Print( stdout, 0 ); } - - /* Write the document to a string using formatted printing ("pretty print"). This - will allocate a character array (new char[]) and return it as a pointer. The - calling code pust call delete[] on the return char* to avoid a memory leak. - */ - //char* PrintToMemory() const; - - /// Print this Document to a FILE stream. - virtual void Print( FILE* cfile, int depth = 0 ) const; - // [internal use] - void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding ); - - virtual const TiXmlDocument* ToDocument() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - virtual TiXmlDocument* ToDocument() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. - - /** Walk the XML tree visiting this node and all of its children. - */ - virtual bool Accept( TiXmlVisitor* content ) const; - -protected : - // [internal use] - virtual TiXmlNode* Clone() const; - #ifdef TIXML_USE_STL - virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); - #endif - -private: - void CopyTo( TiXmlDocument* target ) const; - - bool error; - int errorId; - TIXML_STRING errorDesc; - int tabsize; - TiXmlCursor errorLocation; - bool useMicrosoftBOM; // the UTF-8 BOM were found when read. Note this, and try to write. -}; - - -/** - A TiXmlHandle is a class that wraps a node pointer with null checks; this is - an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml - DOM structure. It is a separate utility class. - - Take an example: - @verbatim - <Document> - <Element attributeA = "valueA"> - <Child attributeB = "value1" /> - <Child attributeB = "value2" /> - </Element> - <Document> - @endverbatim - - Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very - easy to write a *lot* of code that looks like: - - @verbatim - TiXmlElement* root = document.FirstChildElement( "Document" ); - if ( root ) - { - TiXmlElement* element = root->FirstChildElement( "Element" ); - if ( element ) - { - TiXmlElement* child = element->FirstChildElement( "Child" ); - if ( child ) - { - TiXmlElement* child2 = child->NextSiblingElement( "Child" ); - if ( child2 ) - { - // Finally do something useful. - @endverbatim - - And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity - of such code. A TiXmlHandle checks for null pointers so it is perfectly safe - and correct to use: - - @verbatim - TiXmlHandle docHandle( &document ); - TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement(); - if ( child2 ) - { - // do something useful - @endverbatim - - Which is MUCH more concise and useful. - - It is also safe to copy handles - internally they are nothing more than node pointers. - @verbatim - TiXmlHandle handleCopy = handle; - @endverbatim - - What they should not be used for is iteration: - - @verbatim - int i=0; - while ( true ) - { - TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement(); - if ( !child ) - break; - // do something - ++i; - } - @endverbatim - - It seems reasonable, but it is in fact two embedded while loops. The Child method is - a linear walk to find the element, so this code would iterate much more than it needs - to. Instead, prefer: - - @verbatim - TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement(); - - for( child; child; child=child->NextSiblingElement() ) - { - // do something - } - @endverbatim -*/ -class TiXmlHandle -{ -public: - /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. - TiXmlHandle( TiXmlNode* _node ) { this->node = _node; } - /// Copy constructor - TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; } - TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; } - - /// Return a handle to the first child node. - TiXmlHandle FirstChild() const; - /// Return a handle to the first child node with the given name. - TiXmlHandle FirstChild( const char * value ) const; - /// Return a handle to the first child element. - TiXmlHandle FirstChildElement() const; - /// Return a handle to the first child element with the given name. - TiXmlHandle FirstChildElement( const char * value ) const; - - /** Return a handle to the "index" child with the given name. - The first child is 0, the second 1, etc. - */ - TiXmlHandle Child( const char* value, int index ) const; - /** Return a handle to the "index" child. - The first child is 0, the second 1, etc. - */ - TiXmlHandle Child( int index ) const; - /** Return a handle to the "index" child element with the given name. - The first child element is 0, the second 1, etc. Note that only TiXmlElements - are indexed: other types are not counted. - */ - TiXmlHandle ChildElement( const char* value, int index ) const; - /** Return a handle to the "index" child element. - The first child element is 0, the second 1, etc. Note that only TiXmlElements - are indexed: other types are not counted. - */ - TiXmlHandle ChildElement( int index ) const; - - #ifdef TIXML_USE_STL - TiXmlHandle FirstChild( const std::string& _value ) const { return FirstChild( _value.c_str() ); } - TiXmlHandle FirstChildElement( const std::string& _value ) const { return FirstChildElement( _value.c_str() ); } - - TiXmlHandle Child( const std::string& _value, int index ) const { return Child( _value.c_str(), index ); } - TiXmlHandle ChildElement( const std::string& _value, int index ) const { return ChildElement( _value.c_str(), index ); } - #endif - - /** Return the handle as a TiXmlNode. This may return null. - */ - TiXmlNode* ToNode() const { return node; } - /** Return the handle as a TiXmlElement. This may return null. - */ - TiXmlElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } - /** Return the handle as a TiXmlText. This may return null. - */ - TiXmlText* ToText() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } - /** Return the handle as a TiXmlUnknown. This may return null. - */ - TiXmlUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } - - /** @deprecated use ToNode. - Return the handle as a TiXmlNode. This may return null. - */ - TiXmlNode* Node() const { return ToNode(); } - /** @deprecated use ToElement. - Return the handle as a TiXmlElement. This may return null. - */ - TiXmlElement* Element() const { return ToElement(); } - /** @deprecated use ToText() - Return the handle as a TiXmlText. This may return null. - */ - TiXmlText* Text() const { return ToText(); } - /** @deprecated use ToUnknown() - Return the handle as a TiXmlUnknown. This may return null. - */ - TiXmlUnknown* Unknown() const { return ToUnknown(); } - -private: - TiXmlNode* node; -}; - - -/** Print to memory functionality. The TiXmlPrinter is useful when you need to: - - -# Print to memory (especially in non-STL mode) - -# Control formatting (line endings, etc.) - - When constructed, the TiXmlPrinter is in its default "pretty printing" mode. - Before calling Accept() you can call methods to control the printing - of the XML document. After TiXmlNode::Accept() is called, the printed document can - be accessed via the CStr(), Str(), and Size() methods. - - TiXmlPrinter uses the Visitor API. - @verbatim - TiXmlPrinter printer; - printer.SetIndent( "\t" ); - - doc.Accept( &printer ); - fprintf( stdout, "%s", printer.CStr() ); - @endverbatim -*/ -class TiXmlPrinter : public TiXmlVisitor -{ -public: - TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ), - buffer(), indent( " " ), lineBreak( "\n" ) {} - - virtual bool VisitEnter( const TiXmlDocument& doc ); - virtual bool VisitExit( const TiXmlDocument& doc ); - - virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ); - virtual bool VisitExit( const TiXmlElement& element ); - - virtual bool Visit( const TiXmlDeclaration& declaration ); - virtual bool Visit( const TiXmlText& text ); - virtual bool Visit( const TiXmlComment& comment ); - virtual bool Visit( const TiXmlUnknown& unknown ); - - /** Set the indent characters for printing. By default 4 spaces - but tab (\t) is also useful, or null/empty string for no indentation. - */ - void SetIndent( const char* _indent ) { indent = _indent ? _indent : "" ; } - /// Query the indention string. - const char* Indent() { return indent.c_str(); } - /** Set the line breaking string. By default set to newline (\n). - Some operating systems prefer other characters, or can be - set to the null/empty string for no indenation. - */ - void SetLineBreak( const char* _lineBreak ) { lineBreak = _lineBreak ? _lineBreak : ""; } - /// Query the current line breaking string. - const char* LineBreak() { return lineBreak.c_str(); } - - /** Switch over to "stream printing" which is the most dense formatting without - linebreaks. Common when the XML is needed for network transmission. - */ - void SetStreamPrinting() { indent = ""; - lineBreak = ""; - } - /// Return the result. - const char* CStr() { return buffer.c_str(); } - /// Return the length of the result string. - size_t Size() { return buffer.size(); } - - #ifdef TIXML_USE_STL - /// Return the result. - const std::string& Str() { return buffer; } - #endif - -private: - void DoIndent() { - for( int i=0; i<depth; ++i ) - buffer += indent; - } - void DoLineBreak() { - buffer += lineBreak; - } - - int depth; - bool simpleTextPrint; - TIXML_STRING buffer; - TIXML_STRING indent; - TIXML_STRING lineBreak; -}; - - -#ifdef _MSC_VER -#pragma warning( pop ) -#endif - -#endif - diff --git a/library/tinyxml/tinyxmlerror.cpp b/library/tinyxml/tinyxmlerror.cpp deleted file mode 100644 index 3f068f2b..00000000 --- a/library/tinyxml/tinyxmlerror.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* -www.sourceforge.net/projects/tinyxml -Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com) - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ - -#include "tinyxml.h" - -// The goal of the seperate error file is to make the first -// step towards localization. tinyxml (currently) only supports -// english error messages, but the could now be translated. -// -// It also cleans up the code a bit. -// - -const char* TiXmlBase::errorString[ TIXML_ERROR_STRING_COUNT ] = -{ - "No error", - "Error", - "Failed to open file", - "Memory allocation failed.", - "Error parsing Element.", - "Failed to read Element name", - "Error reading Element value.", - "Error reading Attributes.", - "Error: empty tag.", - "Error reading end tag.", - "Error parsing Unknown.", - "Error parsing Comment.", - "Error parsing Declaration.", - "Error document empty.", - "Error null (0) or unexpected EOF found in input stream.", - "Error parsing CDATA.", - "Error when TiXmlDocument added to document, because TiXmlDocument can only be at the root.", -}; diff --git a/library/tinyxml/tinyxmlparser.cpp b/library/tinyxml/tinyxmlparser.cpp deleted file mode 100644 index 539f72cf..00000000 --- a/library/tinyxml/tinyxmlparser.cpp +++ /dev/null @@ -1,1660 +0,0 @@ -/* -www.sourceforge.net/projects/tinyxml -Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com) - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ - -#include <ctype.h> -#include <stddef.h> - -#include "tinyxml.h" - -//#define DEBUG_PARSER -#if defined( DEBUG_PARSER ) -# if defined( DEBUG ) && defined( _MSC_VER ) -# include <windows.h> -# define TIXML_LOG OutputDebugString -# else -# define TIXML_LOG printf -# endif -#endif - -// Note tha "PutString" hardcodes the same list. This -// is less flexible than it appears. Changing the entries -// or order will break putstring. -TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] = -{ - { "&", 5, '&' }, - { "<", 4, '<' }, - { ">", 4, '>' }, - { """, 6, '\"' }, - { "'", 6, '\'' } -}; - -// Bunch of unicode info at: -// http://www.unicode.org/faq/utf_bom.html -// Including the basic of this table, which determines the #bytes in the -// sequence from the lead byte. 1 placed for invalid sequences -- -// although the result will be junk, pass it through as much as possible. -// Beware of the non-characters in UTF-8: -// ef bb bf (Microsoft "lead bytes") -// ef bf be -// ef bf bf - -const unsigned char TIXML_UTF_LEAD_0 = 0xefU; -const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; -const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; - -const int TiXmlBase::utf8ByteTable[256] = -{ - // 0 1 2 3 4 5 6 7 8 9 a b c d e f - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x20 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x30 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x50 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 End of ASCII range - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 0x80 to 0xc1 invalid - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0 - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0 - 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 0xc2 to 0xdf 2 byte - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0 - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xe0 0xe0 to 0xef 3 byte - 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid -}; - - -void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ) -{ - const unsigned long BYTE_MASK = 0xBF; - const unsigned long BYTE_MARK = 0x80; - const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - - if (input < 0x80) - *length = 1; - else if ( input < 0x800 ) - *length = 2; - else if ( input < 0x10000 ) - *length = 3; - else if ( input < 0x200000 ) - *length = 4; - else - { - *length = 0; // This code won't covert this correctly anyway. - return; - } - - output += *length; - - // Scary scary fall throughs. - switch (*length) - { - case 4: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - case 3: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - case 2: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - case 1: - --output; - *output = (char)(input | FIRST_BYTE_MARK[*length]); - } -} - - -/*static*/ -int TiXmlBase::IsAlpha( unsigned char anyByte, TiXmlEncoding /*encoding*/ ) -{ - // This will only work for low-ascii, everything else is assumed to be a valid - // letter. I'm not sure this is the best approach, but it is quite tricky trying - // to figure out alhabetical vs. not across encoding. So take a very - // conservative approach. - -// if ( encoding == TIXML_ENCODING_UTF8 ) -// { - if ( anyByte < 127 ) - return isalpha( anyByte ); - else - return 1; // What else to do? The unicode set is huge...get the english ones right. -// } -// else -// { -// return isalpha( anyByte ); -// } -} - - -/*static*/ -int TiXmlBase::IsAlphaNum( unsigned char anyByte, TiXmlEncoding /*encoding*/ ) -{ - // This will only work for low-ascii, everything else is assumed to be a valid - // letter. I'm not sure this is the best approach, but it is quite tricky trying - // to figure out alhabetical vs. not across encoding. So take a very - // conservative approach. - -// if ( encoding == TIXML_ENCODING_UTF8 ) -// { - if ( anyByte < 127 ) - return isalnum( anyByte ); - else - return 1; // What else to do? The unicode set is huge...get the english ones right. -// } -// else -// { -// return isalnum( anyByte ); -// } -} - - -class TiXmlParsingData -{ - friend class TiXmlDocument; -public: - void Stamp( const char* now, TiXmlEncoding encoding ); - - const TiXmlCursor& Cursor() - { - return cursor; - } - -private: - // Only used by the document! - TiXmlParsingData( const char* start, int _tabsize, int row, int col ) - { - assert( start ); - stamp = start; - tabsize = _tabsize; - cursor.row = row; - cursor.col = col; - } - - TiXmlCursor cursor; - const char* stamp; - int tabsize; -}; - - -void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding ) -{ - assert( now ); - - // Do nothing if the tabsize is 0. - if ( tabsize < 1 ) - { - return; - } - - // Get the current row, column. - int row = cursor.row; - int col = cursor.col; - const char* p = stamp; - assert( p ); - - while ( p < now ) - { - // Treat p as unsigned, so we have a happy compiler. - const unsigned char* pU = (const unsigned char*)p; - - // Code contributed by Fletcher Dunn: (modified by lee) - switch (*pU) - { - case 0: - // We *should* never get here, but in case we do, don't - // advance past the terminating null character, ever - return; - - case '\r': - // bump down to the next line - ++row; - col = 0; - // Eat the character - ++p; - - // Check for \r\n sequence, and treat this as a single character - if (*p == '\n') - { - ++p; - } - break; - - case '\n': - // bump down to the next line - ++row; - col = 0; - - // Eat the character - ++p; - - // Check for \n\r sequence, and treat this as a single - // character. (Yes, this bizarre thing does occur still - // on some arcane platforms...) - if (*p == '\r') - { - ++p; - } - break; - - case '\t': - // Eat the character - ++p; - - // Skip to next tab stop - col = (col / tabsize + 1) * tabsize; - break; - - case TIXML_UTF_LEAD_0: - if ( encoding == TIXML_ENCODING_UTF8 ) - { - if ( *(p+1) && *(p+2) ) - { - // In these cases, don't advance the column. These are - // 0-width spaces. - if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 ) - p += 3; - else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU ) - p += 3; - else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU ) - p += 3; - else - { - p +=3; // A normal character. - ++col; - } - } - } - else - { - ++p; - ++col; - } - break; - - default: - if ( encoding == TIXML_ENCODING_UTF8 ) - { - // Eat the 1 to 4 byte utf8 character. - int step = TiXmlBase::utf8ByteTable[*((const unsigned char*)p)]; - if ( step == 0 ) - step = 1; // Error case from bad encoding, but handle gracefully. - p += step; - - // Just advance one column, of course. - ++col; - } - else - { - ++p; - ++col; - } - break; - } - } - cursor.row = row; - cursor.col = col; - assert( cursor.row >= -1 ); - assert( cursor.col >= -1 ); - stamp = p; - assert( stamp ); -} - - -const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding ) -{ - if ( !p || !*p ) - { - return 0; - } - if ( encoding == TIXML_ENCODING_UTF8 ) - { - while ( *p ) - { - const unsigned char* pU = (const unsigned char*)p; - - // Skip the stupid Microsoft UTF-8 Byte order marks - if ( *(pU+0)==TIXML_UTF_LEAD_0 - && *(pU+1)==TIXML_UTF_LEAD_1 - && *(pU+2)==TIXML_UTF_LEAD_2 ) - { - p += 3; - continue; - } - else if (*(pU+0)==TIXML_UTF_LEAD_0 - && *(pU+1)==0xbfU - && *(pU+2)==0xbeU ) - { - p += 3; - continue; - } - else if (*(pU+0)==TIXML_UTF_LEAD_0 - && *(pU+1)==0xbfU - && *(pU+2)==0xbfU ) - { - p += 3; - continue; - } - - if ( IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' ) // Still using old rules for white space. - ++p; - else - break; - } - } - else - { - while ( (*p && IsWhiteSpace( *p )) || *p == '\n' || *p =='\r' ) - ++p; - } - - return p; -} - -#ifdef TIXML_USE_STL -/*static*/ bool TiXmlBase::StreamWhiteSpace( std::istream * in, TIXML_STRING * tag ) -{ - for ( ;; ) - { - if ( !in->good() ) return false; - - int c = in->peek(); - // At this scope, we can't get to a document. So fail silently. - if ( !IsWhiteSpace( c ) || c <= 0 ) - return true; - - *tag += (char) in->get(); - } -} - -/*static*/ -bool TiXmlBase::StreamTo( std::istream * in, int character, TIXML_STRING * tag ) -{ - //assert( character > 0 && character < 128 ); // else it won't work in utf-8 - while ( in->good() ) - { - int c = in->peek(); - if ( c == character ) - return true; - if ( c <= 0 ) // Silent failure: can't get document at this scope - return false; - - in->get(); - *tag += (char) c; - } - return false; -} -#endif - -// One of TinyXML's more performance demanding functions. Try to keep the memory overhead down. The -// "assign" optimization removes over 10% of the execution time. -// -const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding ) -{ - // Oddly, not supported on some comilers, - //name->clear(); - // So use this: - *name = ""; - assert( p ); - - // Names start with letters or underscores. - // Of course, in unicode, tinyxml has no idea what a letter *is*. The - // algorithm is generous. - // - // After that, they can be letters, underscores, numbers, - // hyphens, or colons. (Colons are valid ony for namespaces, - // but tinyxml can't tell namespaces from names.) - if ( p && *p - && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) ) - { - const char* start = p; - while ( p && *p - && ( IsAlphaNum( (unsigned char ) *p, encoding ) - || *p == '_' - || *p == '-' - || *p == '.' - || *p == ':' ) ) - { - //(*name) += *p; // expensive - ++p; - } - if ( p-start > 0 ) - { - name->assign( start, p-start ); - } - return p; - } - return 0; -} - -const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXmlEncoding encoding ) -{ - // Presume an entity, and pull it out. - TIXML_STRING ent; - int i; - *length = 0; - - if ( *(p+1) && *(p+1) == '#' && *(p+2) ) - { - unsigned long ucs = 0; - ptrdiff_t delta = 0; - unsigned mult = 1; - - if ( *(p+2) == 'x' ) - { - // Hexadecimal. - if ( !*(p+3) ) return 0; - - const char* q = p+3; - q = strchr( q, ';' ); - - if ( !q || !*q ) return 0; - - delta = q-p; - --q; - - while ( *q != 'x' ) - { - if ( *q >= '0' && *q <= '9' ) - ucs += mult * (*q - '0'); - else if ( *q >= 'a' && *q <= 'f' ) - ucs += mult * (*q - 'a' + 10); - else if ( *q >= 'A' && *q <= 'F' ) - ucs += mult * (*q - 'A' + 10 ); - else - return 0; - mult *= 16; - --q; - } - } - else - { - // Decimal. - if ( !*(p+2) ) return 0; - - const char* q = p+2; - q = strchr( q, ';' ); - - if ( !q || !*q ) return 0; - - delta = q-p; - --q; - - while ( *q != '#' ) - { - if ( *q >= '0' && *q <= '9' ) - ucs += mult * (*q - '0'); - else - return 0; - mult *= 10; - --q; - } - } - if ( encoding == TIXML_ENCODING_UTF8 ) - { - // convert the UCS to UTF-8 - ConvertUTF32ToUTF8( ucs, value, length ); - } - else - { - *value = (char)ucs; - *length = 1; - } - return p + delta + 1; - } - - // Now try to match it. - for ( i=0; i<NUM_ENTITY; ++i ) - { - if ( strncmp( entity[i].str, p, entity[i].strLength ) == 0 ) - { - assert( strlen( entity[i].str ) == entity[i].strLength ); - *value = entity[i].chr; - *length = 1; - return ( p + entity[i].strLength ); - } - } - - // So it wasn't an entity, its unrecognized, or something like that. - *value = *p; // Don't put back the last one, since we return it! - //*length = 1; // Leave unrecognized entities - this doesn't really work. - // Just writes strange XML. - return p+1; -} - - -bool TiXmlBase::StringEqual( const char* p, - const char* tag, - bool ignoreCase, - TiXmlEncoding encoding ) -{ - assert( p ); - assert( tag ); - if ( !p || !*p ) - { - assert( 0 ); - return false; - } - - const char* q = p; - - if ( ignoreCase ) - { - while ( *q && *tag && ToLower( *q, encoding ) == ToLower( *tag, encoding ) ) - { - ++q; - ++tag; - } - - if ( *tag == 0 ) - return true; - } - else - { - while ( *q && *tag && *q == *tag ) - { - ++q; - ++tag; - } - - if ( *tag == 0 ) // Have we found the end of the tag, and everything equal? - return true; - } - return false; -} - -const char* TiXmlBase::ReadText( const char* p, - TIXML_STRING * text, - bool trimWhiteSpace, - const char* endTag, - bool caseInsensitive, - TiXmlEncoding encoding ) -{ - *text = ""; - if ( !trimWhiteSpace // certain tags always keep whitespace - || !condenseWhiteSpace ) // if true, whitespace is always kept - { - // Keep all the white space. - while ( p && *p - && !StringEqual( p, endTag, caseInsensitive, encoding ) - ) - { - int len; - char cArr[4] = { 0, 0, 0, 0 }; - p = GetChar( p, cArr, &len, encoding ); - text->append( cArr, len ); - } - } - else - { - bool whitespace = false; - - // Remove leading white space: - p = SkipWhiteSpace( p, encoding ); - while ( p && *p - && !StringEqual( p, endTag, caseInsensitive, encoding ) ) - { - if ( *p == '\r' || *p == '\n' ) - { - whitespace = true; - ++p; - } - else if ( IsWhiteSpace( *p ) ) - { - whitespace = true; - ++p; - } - else - { - // If we've found whitespace, add it before the - // new character. Any whitespace just becomes a space. - if ( whitespace ) - { - (*text) += ' '; - whitespace = false; - } - int len; - char cArr[4] = { 0, 0, 0, 0 }; - p = GetChar( p, cArr, &len, encoding ); - if ( len == 1 ) - (*text) += cArr[0]; // more efficient - else - text->append( cArr, len ); - } - } - } - if ( p ) - p += strlen( endTag ); - return p; -} - -#ifdef TIXML_USE_STL - -void TiXmlDocument::StreamIn( std::istream * in, TIXML_STRING * tag ) -{ - // The basic issue with a document is that we don't know what we're - // streaming. Read something presumed to be a tag (and hope), then - // identify it, and call the appropriate stream method on the tag. - // - // This "pre-streaming" will never read the closing ">" so the - // sub-tag can orient itself. - - if ( !StreamTo( in, '<', tag ) ) - { - SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return; - } - - while ( in->good() ) - { - int tagIndex = (int) tag->length(); - while ( in->good() && in->peek() != '>' ) - { - int c = in->get(); - if ( c <= 0 ) - { - SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); - break; - } - (*tag) += (char) c; - } - - if ( in->good() ) - { - // We now have something we presume to be a node of - // some sort. Identify it, and call the node to - // continue streaming. - TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING ); - - if ( node ) - { - node->StreamIn( in, tag ); - bool isElement = node->ToElement() != 0; - delete node; - node = 0; - - // If this is the root element, we're done. Parsing will be - // done by the >> operator. - if ( isElement ) - { - return; - } - } - else - { - SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); - return; - } - } - } - // We should have returned sooner. - SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN ); -} - -#endif - -const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiXmlEncoding encoding ) -{ - ClearError(); - - // Parse away, at the document level. Since a document - // contains nothing but other tags, most of what happens - // here is skipping white space. - if ( !p || !*p ) - { - SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - - // Note that, for a document, this needs to come - // before the while space skip, so that parsing - // starts from the pointer we are given. - location.Clear(); - if ( prevData ) - { - location.row = prevData->cursor.row; - location.col = prevData->cursor.col; - } - else - { - location.row = 0; - location.col = 0; - } - TiXmlParsingData data( p, TabSize(), location.row, location.col ); - location = data.Cursor(); - - if ( encoding == TIXML_ENCODING_UNKNOWN ) - { - // Check for the Microsoft UTF-8 lead bytes. - const unsigned char* pU = (const unsigned char*)p; - if ( *(pU+0) && *(pU+0) == TIXML_UTF_LEAD_0 - && *(pU+1) && *(pU+1) == TIXML_UTF_LEAD_1 - && *(pU+2) && *(pU+2) == TIXML_UTF_LEAD_2 ) - { - encoding = TIXML_ENCODING_UTF8; - useMicrosoftBOM = true; - } - } - - p = SkipWhiteSpace( p, encoding ); - if ( !p ) - { - SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN ); - return 0; - } - - while ( p && *p ) - { - TiXmlNode* node = Identify( p, encoding ); - if ( node ) - { - p = node->Parse( p, &data, encoding ); - LinkEndChild( node ); - } - else - { - break; - } - - // Did we get encoding info? - if ( encoding == TIXML_ENCODING_UNKNOWN - && node->ToDeclaration() ) - { - TiXmlDeclaration* dec = node->ToDeclaration(); - const char* enc = dec->Encoding(); - assert( enc ); - - if ( *enc == 0 ) - encoding = TIXML_ENCODING_UTF8; - else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) ) - encoding = TIXML_ENCODING_UTF8; - else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) ) - encoding = TIXML_ENCODING_UTF8; // incorrect, but be nice - else - encoding = TIXML_ENCODING_LEGACY; - } - - p = SkipWhiteSpace( p, encoding ); - } - - // Was this empty? - if ( !firstChild ) - { - SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, encoding ); - return 0; - } - - // All is well. - return p; -} - -void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding ) -{ - // The first error in a chain is more accurate - don't set again! - if ( error ) - return; - - assert( err > 0 && err < TIXML_ERROR_STRING_COUNT ); - error = true; - errorId = err; - errorDesc = errorString[ errorId ]; - - errorLocation.Clear(); - if ( pError && data ) - { - data->Stamp( pError, encoding ); - errorLocation = data->Cursor(); - } -} - - -TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding ) -{ - TiXmlNode* returnNode = 0; - - p = SkipWhiteSpace( p, encoding ); - if ( !p || !*p || *p != '<' ) - { - return 0; - } - - TiXmlDocument* doc = GetDocument(); - p = SkipWhiteSpace( p, encoding ); - - if ( !p || !*p ) - { - return 0; - } - - // What is this thing? - // - Elements start with a letter or underscore, but xml is reserved. - // - Comments: <!-- - // - Decleration: <?xml - // - Everthing else is unknown to tinyxml. - // - - const char* xmlHeader = { "<?xml" }; - const char* commentHeader = { "<!--" }; - const char* dtdHeader = { "<!" }; - const char* cdataHeader = { "<![CDATA[" }; - - if ( StringEqual( p, xmlHeader, true, encoding ) ) - { -#ifdef DEBUG_PARSER - TIXML_LOG( "XML parsing Declaration\n" ); -#endif - returnNode = new TiXmlDeclaration(); - } - else if ( StringEqual( p, commentHeader, false, encoding ) ) - { -#ifdef DEBUG_PARSER - TIXML_LOG( "XML parsing Comment\n" ); -#endif - returnNode = new TiXmlComment(); - } - else if ( StringEqual( p, cdataHeader, false, encoding ) ) - { -#ifdef DEBUG_PARSER - TIXML_LOG( "XML parsing CDATA\n" ); -#endif - TiXmlText* text = new TiXmlText( "" ); - text->SetCDATA( true ); - returnNode = text; - } - else if ( StringEqual( p, dtdHeader, false, encoding ) ) - { -#ifdef DEBUG_PARSER - TIXML_LOG( "XML parsing Unknown(1)\n" ); -#endif - returnNode = new TiXmlUnknown(); - } - else if ( IsAlpha( *(p+1), encoding ) - || *(p+1) == '_' ) - { -#ifdef DEBUG_PARSER - TIXML_LOG( "XML parsing Element\n" ); -#endif - returnNode = new TiXmlElement( "" ); - } - else - { -#ifdef DEBUG_PARSER - TIXML_LOG( "XML parsing Unknown(2)\n" ); -#endif - returnNode = new TiXmlUnknown(); - } - - if ( returnNode ) - { - // Set the parent, so it can report errors - returnNode->parent = this; - } - else - { - if ( doc ) - doc->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN ); - } - return returnNode; -} - -#ifdef TIXML_USE_STL - -void TiXmlElement::StreamIn (std::istream * in, TIXML_STRING * tag) -{ - // We're called with some amount of pre-parsing. That is, some of "this" - // element is in "tag". Go ahead and stream to the closing ">" - while ( in->good() ) - { - int c = in->get(); - if ( c <= 0 ) - { - TiXmlDocument* document = GetDocument(); - if ( document ) - document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); - return; - } - (*tag) += (char) c ; - - if ( c == '>' ) - break; - } - - if ( tag->length() < 3 ) return; - - // Okay...if we are a "/>" tag, then we're done. We've read a complete tag. - // If not, identify and stream. - - if ( tag->at( tag->length() - 1 ) == '>' - && tag->at( tag->length() - 2 ) == '/' ) - { - // All good! - return; - } - else if ( tag->at( tag->length() - 1 ) == '>' ) - { - // There is more. Could be: - // text - // cdata text (which looks like another node) - // closing tag - // another node. - for ( ;; ) - { - StreamWhiteSpace( in, tag ); - - // Do we have text? - if ( in->good() && in->peek() != '<' ) - { - // Yep, text. - TiXmlText text( "" ); - text.StreamIn( in, tag ); - - // What follows text is a closing tag or another node. - // Go around again and figure it out. - continue; - } - - // We now have either a closing tag...or another node. - // We should be at a "<", regardless. - if ( !in->good() ) return; - assert( in->peek() == '<' ); - int tagIndex = (int) tag->length(); - - bool closingTag = false; - bool firstCharFound = false; - - for ( ;; ) - { - if ( !in->good() ) - return; - - int c = in->peek(); - if ( c <= 0 ) - { - TiXmlDocument* document = GetDocument(); - if ( document ) - document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); - return; - } - - if ( c == '>' ) - break; - - *tag += (char) c; - in->get(); - - // Early out if we find the CDATA id. - if ( c == '[' && tag->size() >= 9 ) - { - size_t len = tag->size(); - const char* start = tag->c_str() + len - 9; - if ( strcmp( start, "<![CDATA[" ) == 0 ) - { - assert( !closingTag ); - break; - } - } - - if ( !firstCharFound && c != '<' && !IsWhiteSpace( c ) ) - { - firstCharFound = true; - if ( c == '/' ) - closingTag = true; - } - } - // If it was a closing tag, then read in the closing '>' to clean up the input stream. - // If it was not, the streaming will be done by the tag. - if ( closingTag ) - { - if ( !in->good() ) - return; - - int c = in->get(); - if ( c <= 0 ) - { - TiXmlDocument* document = GetDocument(); - if ( document ) - document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); - return; - } - assert( c == '>' ); - *tag += (char) c; - - // We are done, once we've found our closing tag. - return; - } - else - { - // If not a closing tag, id it, and stream. - const char* tagloc = tag->c_str() + tagIndex; - TiXmlNode* node = Identify( tagloc, TIXML_DEFAULT_ENCODING ); - if ( !node ) - return; - node->StreamIn( in, tag ); - delete node; - node = 0; - - // No return: go around from the beginning: text, closing tag, or node. - } - } - } -} -#endif - -const char* TiXmlElement::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) -{ - p = SkipWhiteSpace( p, encoding ); - TiXmlDocument* document = GetDocument(); - - if ( !p || !*p ) - { - if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, 0, 0, encoding ); - return 0; - } - - if ( data ) - { - data->Stamp( p, encoding ); - location = data->Cursor(); - } - - if ( *p != '<' ) - { - if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, p, data, encoding ); - return 0; - } - - p = SkipWhiteSpace( p+1, encoding ); - - // Read the name. - const char* pErr = p; - - p = ReadName( p, &value, encoding ); - if ( !p || !*p ) - { - if ( document ) document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, pErr, data, encoding ); - return 0; - } - - TIXML_STRING endTag ("</"); - endTag += value; - endTag += ">"; - - // Check for and read attributes. Also look for an empty - // tag or an end tag. - while ( p && *p ) - { - pErr = p; - p = SkipWhiteSpace( p, encoding ); - if ( !p || !*p ) - { - if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding ); - return 0; - } - if ( *p == '/' ) - { - ++p; - // Empty tag. - if ( *p != '>' ) - { - if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY, p, data, encoding ); - return 0; - } - return (p+1); - } - else if ( *p == '>' ) - { - // Done with attributes (if there were any.) - // Read the value -- which can include other - // elements -- read the end tag, and return. - ++p; - p = ReadValue( p, data, encoding ); // Note this is an Element method, and will set the error if one happens. - if ( !p || !*p ) - { - // We were looking for the end tag, but found nothing. - // Fix for [ 1663758 ] Failure to report error on bad XML - if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding ); - return 0; - } - - // We should find the end tag now - if ( StringEqual( p, endTag.c_str(), false, encoding ) ) - { - p += endTag.length(); - return p; - } - else - { - if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding ); - return 0; - } - } - else - { - // Try to read an attribute: - TiXmlAttribute* attrib = new TiXmlAttribute(); - if ( !attrib ) - { - if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, pErr, data, encoding ); - return 0; - } - - attrib->SetDocument( document ); - pErr = p; - p = attrib->Parse( p, data, encoding ); - - if ( !p || !*p ) - { - if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, pErr, data, encoding ); - delete attrib; - return 0; - } - - // Handle the strange case of double attributes: -#ifdef TIXML_USE_STL - TiXmlAttribute* node = attributeSet.Find( attrib->NameTStr() ); -#else - TiXmlAttribute* node = attributeSet.Find( attrib->Name() ); -#endif - if ( node ) - { - node->SetValue( attrib->Value() ); - delete attrib; - return 0; - } - - attributeSet.Add( attrib ); - } - } - return p; -} - - -const char* TiXmlElement::ReadValue( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) -{ - TiXmlDocument* document = GetDocument(); - - // Read in text and elements in any order. - const char* pWithWhiteSpace = p; - p = SkipWhiteSpace( p, encoding ); - - while ( p && *p ) - { - if ( *p != '<' ) - { - // Take what we have, make a text element. - TiXmlText* textNode = new TiXmlText( "" ); - - if ( !textNode ) - { - if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, encoding ); - return 0; - } - - if ( TiXmlBase::IsWhiteSpaceCondensed() ) - { - p = textNode->Parse( p, data, encoding ); - } - else - { - // Special case: we want to keep the white space - // so that leading spaces aren't removed. - p = textNode->Parse( pWithWhiteSpace, data, encoding ); - } - - if ( !textNode->Blank() ) - LinkEndChild( textNode ); - else - delete textNode; - } - else - { - // We hit a '<' - // Have we hit a new element or an end tag? This could also be - // a TiXmlText in the "CDATA" style. - if ( StringEqual( p, "</", false, encoding ) ) - { - return p; - } - else - { - TiXmlNode* node = Identify( p, encoding ); - if ( node ) - { - p = node->Parse( p, data, encoding ); - LinkEndChild( node ); - } - else - { - return 0; - } - } - } - pWithWhiteSpace = p; - p = SkipWhiteSpace( p, encoding ); - } - - if ( !p ) - { - if ( document ) document->SetError( TIXML_ERROR_READING_ELEMENT_VALUE, 0, 0, encoding ); - } - return p; -} - - -#ifdef TIXML_USE_STL -void TiXmlUnknown::StreamIn( std::istream * in, TIXML_STRING * tag ) -{ - while ( in->good() ) - { - int c = in->get(); - if ( c <= 0 ) - { - TiXmlDocument* document = GetDocument(); - if ( document ) - document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); - return; - } - (*tag) += (char) c; - - if ( c == '>' ) - { - // All is well. - return; - } - } -} -#endif - - -const char* TiXmlUnknown::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) -{ - TiXmlDocument* document = GetDocument(); - p = SkipWhiteSpace( p, encoding ); - - if ( data ) - { - data->Stamp( p, encoding ); - location = data->Cursor(); - } - if ( !p || !*p || *p != '<' ) - { - if ( document ) document->SetError( TIXML_ERROR_PARSING_UNKNOWN, p, data, encoding ); - return 0; - } - ++p; - value = ""; - - while ( p && *p && *p != '>' ) - { - value += *p; - ++p; - } - - if ( !p ) - { - if ( document ) document->SetError( TIXML_ERROR_PARSING_UNKNOWN, 0, 0, encoding ); - } - if ( *p == '>' ) - return p+1; - return p; -} - -#ifdef TIXML_USE_STL -void TiXmlComment::StreamIn( std::istream * in, TIXML_STRING * tag ) -{ - while ( in->good() ) - { - int c = in->get(); - if ( c <= 0 ) - { - TiXmlDocument* document = GetDocument(); - if ( document ) - document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); - return; - } - - (*tag) += (char) c; - - if ( c == '>' - && tag->at( tag->length() - 2 ) == '-' - && tag->at( tag->length() - 3 ) == '-' ) - { - // All is well. - return; - } - } -} -#endif - - -const char* TiXmlComment::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) -{ - TiXmlDocument* document = GetDocument(); - value = ""; - - p = SkipWhiteSpace( p, encoding ); - - if ( data ) - { - data->Stamp( p, encoding ); - location = data->Cursor(); - } - const char* startTag = "<!--"; - const char* endTag = "-->"; - - if ( !StringEqual( p, startTag, false, encoding ) ) - { - document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding ); - return 0; - } - p += strlen( startTag ); - - // [ 1475201 ] TinyXML parses entities in comments - // Oops - ReadText doesn't work, because we don't want to parse the entities. - // p = ReadText( p, &value, false, endTag, false, encoding ); - // - // from the XML spec: - /* - [Definition: Comments may appear anywhere in a document outside other markup; in addition, - they may appear within the document type declaration at places allowed by the grammar. - They are not part of the document's character data; an XML processor MAY, but need not, - make it possible for an application to retrieve the text of comments. For compatibility, - the string "--" (double-hyphen) MUST NOT occur within comments.] Parameter entity - references MUST NOT be recognized within comments. - - An example of a comment: - - <!-- declarations for <head> & <body> --> - */ - - value = ""; - // Keep all the white space. - while ( p && *p && !StringEqual( p, endTag, false, encoding ) ) - { - value.append( p, 1 ); - ++p; - } - if ( p ) - p += strlen( endTag ); - - return p; -} - - -const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) -{ - p = SkipWhiteSpace( p, encoding ); - if ( !p || !*p ) return 0; - -// int tabsize = 4; -// if ( document ) -// tabsize = document->TabSize(); - - if ( data ) - { - data->Stamp( p, encoding ); - location = data->Cursor(); - } - // Read the name, the '=' and the value. - const char* pErr = p; - p = ReadName( p, &name, encoding ); - if ( !p || !*p ) - { - if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding ); - return 0; - } - p = SkipWhiteSpace( p, encoding ); - if ( !p || !*p || *p != '=' ) - { - if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); - return 0; - } - - ++p; // skip '=' - p = SkipWhiteSpace( p, encoding ); - if ( !p || !*p ) - { - if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); - return 0; - } - - const char* end; - const char SINGLE_QUOTE = '\''; - const char DOUBLE_QUOTE = '\"'; - - if ( *p == SINGLE_QUOTE ) - { - ++p; - end = "\'"; // single quote in string - p = ReadText( p, &value, false, end, false, encoding ); - } - else if ( *p == DOUBLE_QUOTE ) - { - ++p; - end = "\""; // double quote in string - p = ReadText( p, &value, false, end, false, encoding ); - } - else - { - // All attribute values should be in single or double quotes. - // But this is such a common error that the parser will try - // its best, even without them. - value = ""; - while ( p && *p // existence - && !IsWhiteSpace( *p ) && *p != '\n' && *p != '\r' // whitespace - && *p != '/' && *p != '>' ) // tag end - { - if ( *p == SINGLE_QUOTE || *p == DOUBLE_QUOTE ) - { - // [ 1451649 ] Attribute values with trailing quotes not handled correctly - // We did not have an opening quote but seem to have a - // closing one. Give up and throw an error. - if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding ); - return 0; - } - value += *p; - ++p; - } - } - return p; -} - -#ifdef TIXML_USE_STL -void TiXmlText::StreamIn( std::istream * in, TIXML_STRING * tag ) -{ - while ( in->good() ) - { - int c = in->peek(); - if ( !cdata && (c == '<' ) ) - { - return; - } - if ( c <= 0 ) - { - TiXmlDocument* document = GetDocument(); - if ( document ) - document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); - return; - } - - (*tag) += (char) c; - in->get(); // "commits" the peek made above - - if ( cdata && c == '>' && tag->size() >= 3 ) - { - size_t len = tag->size(); - if ( (*tag)[len-2] == ']' && (*tag)[len-3] == ']' ) - { - // terminator of cdata. - return; - } - } - } -} -#endif - -const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ) -{ - value = ""; - TiXmlDocument* document = GetDocument(); - - if ( data ) - { - data->Stamp( p, encoding ); - location = data->Cursor(); - } - - const char* const startTag = "<![CDATA["; - const char* const endTag = "]]>"; - - if ( cdata || StringEqual( p, startTag, false, encoding ) ) - { - cdata = true; - - if ( !StringEqual( p, startTag, false, encoding ) ) - { - document->SetError( TIXML_ERROR_PARSING_CDATA, p, data, encoding ); - return 0; - } - p += strlen( startTag ); - - // Keep all the white space, ignore the encoding, etc. - while ( p && *p - && !StringEqual( p, endTag, false, encoding ) - ) - { - value += *p; - ++p; - } - - TIXML_STRING dummy; - p = ReadText( p, &dummy, false, endTag, false, encoding ); - return p; - } - else - { - bool ignoreWhite = true; - - const char* end = "<"; - p = ReadText( p, &value, ignoreWhite, end, false, encoding ); - if ( p ) - return p-1; // don't truncate the '<' - return 0; - } -} - -#ifdef TIXML_USE_STL -void TiXmlDeclaration::StreamIn( std::istream * in, TIXML_STRING * tag ) -{ - while ( in->good() ) - { - int c = in->get(); - if ( c <= 0 ) - { - TiXmlDocument* document = GetDocument(); - if ( document ) - document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN ); - return; - } - (*tag) += (char) c; - - if ( c == '>' ) - { - // All is well. - return; - } - } -} -#endif - -const char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding ) -{ - p = SkipWhiteSpace( p, _encoding ); - // Find the beginning, find the end, and look for - // the stuff in-between. - TiXmlDocument* document = GetDocument(); - if ( !p || !*p || !StringEqual( p, "<?xml", true, _encoding ) ) - { - if ( document ) document->SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding ); - return 0; - } - if ( data ) - { - data->Stamp( p, _encoding ); - location = data->Cursor(); - } - p += 5; - - version = ""; - encoding = ""; - standalone = ""; - - while ( p && *p ) - { - if ( *p == '>' ) - { - ++p; - return p; - } - - p = SkipWhiteSpace( p, _encoding ); - if ( StringEqual( p, "version", true, _encoding ) ) - { - TiXmlAttribute attrib; - p = attrib.Parse( p, data, _encoding ); - version = attrib.Value(); - } - else if ( StringEqual( p, "encoding", true, _encoding ) ) - { - TiXmlAttribute attrib; - p = attrib.Parse( p, data, _encoding ); - encoding = attrib.Value(); - } - else if ( StringEqual( p, "standalone", true, _encoding ) ) - { - TiXmlAttribute attrib; - p = attrib.Parse( p, data, _encoding ); - standalone = attrib.Value(); - } - else - { - // Read over whatever it is. - while ( p && *p && *p != '>' && !IsWhiteSpace( *p ) ) - ++p; - } - } - return 0; -} - -bool TiXmlText::Blank() const -{ - for ( unsigned i=0; i<value.length(); i++ ) - if ( !IsWhiteSpace( value[i] ) ) - return false; - return true; -} - |