summaryrefslogtreecommitdiff
path: root/library
diff options
context:
space:
mode:
Diffstat (limited to 'library')
-rw-r--r--library/binary.cpp2
-rw-r--r--library/binary.h2
-rw-r--r--library/cmp_filetime.h66
-rw-r--r--library/custom_grid.cpp26
-rw-r--r--library/custom_grid.h6
-rw-r--r--library/db_file.cpp159
-rw-r--r--library/db_file.h2
-rw-r--r--library/detect_renaming.cpp2
-rw-r--r--library/detect_renaming.h2
-rw-r--r--library/dir_lock.cpp70
-rw-r--r--library/dir_lock.h2
-rw-r--r--library/error_log.cpp2
-rw-r--r--library/error_log.h2
-rw-r--r--library/filter.cpp2
-rw-r--r--library/filter.h19
-rw-r--r--library/icon_buffer.cpp9
-rw-r--r--library/icon_buffer.h10
-rw-r--r--library/pch.h2
-rw-r--r--library/process_xml.cpp20
-rw-r--r--library/process_xml.h10
-rw-r--r--library/resources.cpp2
-rw-r--r--library/resources.h2
-rw-r--r--library/soft_filter.cpp2
-rw-r--r--library/soft_filter.h2
-rw-r--r--library/statistics.cpp82
-rw-r--r--library/statistics.h29
-rw-r--r--library/status_handler.cpp2
-rw-r--r--library/status_handler.h2
28 files changed, 326 insertions, 212 deletions
diff --git a/library/binary.cpp b/library/binary.cpp
index cbcef238..1b722702 100644
--- a/library/binary.cpp
+++ b/library/binary.cpp
@@ -1,7 +1,7 @@
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
#include "binary.h"
diff --git a/library/binary.h b/library/binary.h
index bf477116..847c7169 100644
--- a/library/binary.h
+++ b/library/binary.h
@@ -1,7 +1,7 @@
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
#ifndef BINARY_H_INCLUDED
diff --git a/library/cmp_filetime.h b/library/cmp_filetime.h
new file mode 100644
index 00000000..b95eae5f
--- /dev/null
+++ b/library/cmp_filetime.h
@@ -0,0 +1,66 @@
+#ifndef CMP_FILETIME_H_INCLUDED
+#define CMP_FILETIME_H_INCLUDED
+
+#include <wx/longlong.h>
+#include <wx/stopwatch.h>
+
+
+namespace ffs3
+{
+//---------------------------------------------------------------------------------------------------------------
+inline
+bool sameFileTime(const wxLongLong& a, const wxLongLong& b, size_t tolerance)
+{
+ if (a < b)
+ return b <= a + tolerance;
+ else
+ return a <= b + tolerance;
+}
+//---------------------------------------------------------------------------------------------------------------
+
+class CmpFileTime
+{
+public:
+ CmpFileTime(size_t tolerance) :
+ tolerance_(tolerance) {}
+
+ enum Result
+ {
+ TIME_EQUAL,
+ TIME_LEFT_NEWER,
+ TIME_RIGHT_NEWER,
+ TIME_LEFT_INVALID,
+ TIME_RIGHT_INVALID
+ };
+
+ Result getResult(const wxLongLong& lhs, const wxLongLong& rhs) const
+ {
+ if (lhs == rhs)
+ return TIME_EQUAL;
+
+ //number of seconds since Jan 1st 1970 + 1 year (needn't be too precise)
+ static const long oneYearFromNow = wxGetUTCTime() + 365 * 24 * 3600; //static in header: not a big deal in this case!
+
+ //check for erroneous dates (but only if dates are not (EXACTLY) the same)
+ if (lhs < 0 || lhs > oneYearFromNow) //earlier than Jan 1st 1970 or more than one year in future
+ return TIME_LEFT_INVALID;
+
+ if (rhs < 0 || rhs > oneYearFromNow)
+ return TIME_RIGHT_INVALID;
+
+ if (sameFileTime(lhs, rhs, tolerance_)) //last write time may differ by up to 2 seconds (NTFS vs FAT32)
+ return TIME_EQUAL;
+
+ //regular time comparison
+ if (lhs < rhs)
+ return TIME_RIGHT_NEWER;
+ else
+ return TIME_LEFT_NEWER;
+ }
+
+private:
+ const size_t tolerance_;
+};
+}
+
+#endif // CMP_FILETIME_H_INCLUDED
diff --git a/library/custom_grid.cpp b/library/custom_grid.cpp
index e7a724a0..274ef778 100644
--- a/library/custom_grid.cpp
+++ b/library/custom_grid.cpp
@@ -1,7 +1,7 @@
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
#include "custom_grid.h"
@@ -197,8 +197,11 @@ protected:
static const wxColour COLOR_CMP_BLUE;
static const wxColour COLOR_CMP_GREEN;
static const wxColour COLOR_SYNC_BLUE;
+ static const wxColour COLOR_SYNC_BLUE_LIGHT;
static const wxColour COLOR_SYNC_GREEN;
+ static const wxColour COLOR_SYNC_GREEN_LIGHT;
static const wxColour COLOR_YELLOW;
+ static const wxColour COLOR_YELLOW_LIGHT;
const GridView* gridDataView; //(very fast) access to underlying grid data :)
@@ -217,8 +220,11 @@ const wxColour CustomGridTable::COLOR_CMP_RED( 249, 163, 165);
const wxColour CustomGridTable::COLOR_CMP_BLUE( 144, 232, 246);
const wxColour CustomGridTable::COLOR_CMP_GREEN( 147, 253, 159);
const wxColour CustomGridTable::COLOR_SYNC_BLUE( 201, 203, 247);
+const wxColour CustomGridTable::COLOR_SYNC_BLUE_LIGHT(201, 225, 247);
const wxColour CustomGridTable::COLOR_SYNC_GREEN(197, 248, 190);
+const wxColour CustomGridTable::COLOR_SYNC_GREEN_LIGHT(226, 248, 190);
const wxColour CustomGridTable::COLOR_YELLOW( 247, 252, 62);
+const wxColour CustomGridTable::COLOR_YELLOW_LIGHT(253, 252, 169);
class CustomGridTableRim : public CustomGridTable
@@ -331,10 +337,10 @@ protected:
value = zToWx(dirObj.getFullName<side>());
break;
case xmlAccess::FILENAME:
- value = wxEmptyString;
+ value = zToWx(dirObj.getShortName<side>());
break;
case xmlAccess::REL_PATH:
- value = zToWx(dirObj.getRelativeName<side>());
+ value = zToWx(dirObj.getParentRelativeName());
break;
case xmlAccess::DIRECTORY:
value = zToWx(dirObj.getBaseDirPf<side>());
@@ -527,10 +533,14 @@ private:
case SO_DELETE_LEFT:
case SO_OVERWRITE_LEFT:
return COLOR_SYNC_BLUE;
+ case SO_COPY_METADATA_TO_LEFT:
+ return COLOR_SYNC_BLUE_LIGHT;
case SO_CREATE_NEW_RIGHT:
case SO_DELETE_RIGHT:
case SO_OVERWRITE_RIGHT:
return COLOR_SYNC_GREEN;
+ case SO_COPY_METADATA_TO_RIGHT:
+ return COLOR_SYNC_GREEN_LIGHT;
case SO_UNRESOLVED_CONFLICT:
return COLOR_YELLOW;
case SO_DO_NOTHING:
@@ -554,6 +564,8 @@ private:
return *wxWHITE;
case FILE_CONFLICT:
return COLOR_YELLOW;
+ case FILE_DIFFERENT_METADATA:
+ return COLOR_YELLOW_LIGHT;
}
}
}
@@ -1919,9 +1931,11 @@ void CustomGridMiddle::showToolTip(int rowNumber, wxPoint pos)
toolTip->show(getDescription(syncOp), pos, &GlobalResources::getInstance().getImageByName(wxT("syncDeleteRightAct")));
break;
case SO_OVERWRITE_LEFT:
+ case SO_COPY_METADATA_TO_LEFT:
toolTip->show(getDescription(syncOp), pos, &GlobalResources::getInstance().getImageByName(wxT("syncDirLeftAct")));
break;
case SO_OVERWRITE_RIGHT:
+ case SO_COPY_METADATA_TO_RIGHT:
toolTip->show(getDescription(syncOp), pos, &GlobalResources::getInstance().getImageByName(wxT("syncDirRightAct")));
break;
case SO_DO_NOTHING:
@@ -1958,6 +1972,9 @@ void CustomGridMiddle::showToolTip(int rowNumber, wxPoint pos)
case FILE_EQUAL:
toolTip->show(getDescription(cmpRes), pos, &GlobalResources::getInstance().getImageByName(wxT("equalAct")));
break;
+ case FILE_DIFFERENT_METADATA:
+ toolTip->show(getDescription(cmpRes), pos, &GlobalResources::getInstance().getImageByName(wxT("conflictAct")));
+ break;
case FILE_CONFLICT:
toolTip->show(fsObj->getCatConflict(), pos, &GlobalResources::getInstance().getImageByName(wxT("conflictAct")));
break;
@@ -2178,6 +2195,7 @@ void GridCellRendererMiddle::Draw(wxGrid& grid,
dc.DrawLabel(wxEmptyString, GlobalResources::getInstance().getImageByName(wxT("equalSmall")), rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
break;
case FILE_CONFLICT:
+ case FILE_DIFFERENT_METADATA:
dc.DrawLabel(wxEmptyString, GlobalResources::getInstance().getImageByName(wxT("conflictSmall")), rectShrinked, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
break;
}
@@ -2232,8 +2250,10 @@ const wxBitmap& ffs3::getSyncOpImage(SyncOperation syncOp)
case SO_DELETE_RIGHT:
return GlobalResources::getInstance().getImageByName(wxT("deleteRightSmall"));
case SO_OVERWRITE_RIGHT:
+ case SO_COPY_METADATA_TO_RIGHT:
return GlobalResources::getInstance().getImageByName(wxT("syncDirRightSmall"));
case SO_OVERWRITE_LEFT:
+ case SO_COPY_METADATA_TO_LEFT:
return GlobalResources::getInstance().getImageByName(wxT("syncDirLeftSmall"));
case SO_DO_NOTHING:
return GlobalResources::getInstance().getImageByName(wxT("syncDirNoneSmall"));
diff --git a/library/custom_grid.h b/library/custom_grid.h
index 193b403d..1517230b 100644
--- a/library/custom_grid.h
+++ b/library/custom_grid.h
@@ -1,7 +1,7 @@
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
#ifndef CUSTOMGRID_H_INCLUDED
@@ -167,12 +167,12 @@ protected:
template <ffs3::SelectedSide side>
void setTooltip(const wxMouseEvent& event);
-void setOtherGrid(CustomGridRim* other); //call during initialization!
+ void setOtherGrid(CustomGridRim* other); //call during initialization!
private:
CustomGridTableRim* getGridDataTableRim() const;
-void OnResizeColumn(wxGridSizeEvent& event);
+ void OnResizeColumn(wxGridSizeEvent& event);
//this method is called when grid view changes: useful for parallel updating of multiple grids
virtual void alignOtherGrids(CustomGrid* gridLeft, CustomGrid* gridMiddle, CustomGrid* gridRight);
diff --git a/library/db_file.cpp b/library/db_file.cpp
index a0f5099c..180ab0a4 100644
--- a/library/db_file.cpp
+++ b/library/db_file.cpp
@@ -1,7 +1,7 @@
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
#include "db_file.h"
@@ -29,7 +29,7 @@ namespace
{
//-------------------------------------------------------------------------------------------------------------------------------
const char FILE_FORMAT_DESCR[] = "FreeFileSync";
-const int FILE_FORMAT_VER = 4;
+const int FILE_FORMAT_VER = 5;
//-------------------------------------------------------------------------------------------------------------------------------
@@ -40,11 +40,10 @@ public:
FileInputStream(filename)
{
//read FreeFileSync file identifier
- char formatDescr[sizeof(FILE_FORMAT_DESCR)];
+ char formatDescr[sizeof(FILE_FORMAT_DESCR)] = {};
Read(formatDescr, sizeof(formatDescr)); //throw (FileError)
- formatDescr[sizeof(formatDescr) - 1] = 0;
- if (std::string(formatDescr) != FILE_FORMAT_DESCR)
+ if (!std::equal(FILE_FORMAT_DESCR, FILE_FORMAT_DESCR + sizeof(FILE_FORMAT_DESCR), formatDescr))
throw FileError(wxString(_("Incompatible synchronization database format:")) + wxT(" \n") + wxT("\"") + zToWx(filename) + wxT("\""));
}
@@ -75,6 +74,10 @@ class ReadDirInfo : public util::ReadInputStream
public:
ReadDirInfo(wxInputStream& stream, const wxString& errorObjName, DirInformation& dirInfo) : ReadInputStream(stream, errorObjName)
{
+ //|-------------------------------------------------------------------------------------
+ //| ensure 32/64 bit portability: used fixed size data types only e.g. boost::uint32_t |
+ //|-------------------------------------------------------------------------------------
+
//read filter settings
dirInfo.filter = BaseFilter::loadFilter(getStream());
check();
@@ -86,15 +89,15 @@ public:
private:
void execute(DirContainer& dirCont) const
{
- size_t fileCount = readNumberC<size_t>();
+ boost::uint32_t fileCount = readNumberC<boost::uint32_t>();
while (fileCount-- != 0)
readSubFile(dirCont);
- size_t symlinkCount = readNumberC<size_t>();
+ boost::uint32_t symlinkCount = readNumberC<boost::uint32_t>();
while (symlinkCount-- != 0)
readSubLink(dirCont);
- size_t dirCount = readNumberC<size_t>();
+ boost::uint32_t dirCount = readNumberC<boost::uint32_t>();
while (dirCount-- != 0)
readSubDirectory(dirCont);
}
@@ -104,11 +107,11 @@ private:
//attention: order of function argument evaluation is undefined! So do it one after the other...
const Zstring shortName = readStringC(); //file name
- const long modHigh = readNumberC<long>();
- const unsigned long modLow = readNumberC<unsigned long>();
+ const boost::int32_t modHigh = readNumberC<boost::int32_t>();
+ const boost::uint32_t modLow = readNumberC<boost::uint32_t>();
- const unsigned long sizeHigh = readNumberC<unsigned long>();
- const unsigned long sizeLow = readNumberC<unsigned long>();
+ const boost::uint32_t sizeHigh = readNumberC<boost::uint32_t>();
+ const boost::uint32_t sizeLow = readNumberC<boost::uint32_t>();
//const util::FileID fileIdentifier(stream_);
//check();
@@ -122,11 +125,11 @@ private:
void readSubLink(DirContainer& dirCont) const
{
//attention: order of function argument evaluation is undefined! So do it one after the other...
- const Zstring shortName = readStringC(); //file name
- const long modHigh = readNumberC<long>();
- const unsigned long modLow = readNumberC<unsigned long>();
- const Zstring targetPath = readStringC(); //file name
- const LinkDescriptor::LinkType linkType = static_cast<LinkDescriptor::LinkType>(readNumberC<int>());
+ const Zstring shortName = readStringC(); //file name
+ const boost::int32_t modHigh = readNumberC<boost::int32_t>();
+ const boost::uint32_t modLow = readNumberC<boost::uint32_t>();
+ const Zstring targetPath = readStringC(); //file name
+ const LinkDescriptor::LinkType linkType = static_cast<LinkDescriptor::LinkType>(readNumberC<boost::int32_t>());
dirCont.addSubLink(shortName,
LinkDescriptor(wxLongLong(modHigh, modLow), targetPath, linkType));
@@ -141,10 +144,13 @@ private:
}
};
-
-typedef boost::shared_ptr<std::vector<char> > MemoryStreamPtr; //byte stream representing DirInformation
-typedef std::map<util::UniqueId, MemoryStreamPtr> DirectoryTOC; //list of streams ordered by a UUID pointing to their partner database
-typedef std::pair<util::UniqueId, DirectoryTOC> DbStreamData; //header data: UUID representing this database, item data: list of dir-streams
+namespace
+{
+typedef std::string UniqueId;
+typedef boost::shared_ptr<std::vector<char> > MemoryStreamPtr; //byte stream representing DirInformation
+typedef std::map<UniqueId, MemoryStreamPtr> DirectoryTOC; //list of streams ordered by a UUID pointing to their partner database
+typedef std::pair<UniqueId, DirectoryTOC> DbStreamData; //header data: UUID representing this database, item data: list of dir-streams
+}
/* Example
left side right side
--------- ----------
@@ -160,21 +166,26 @@ class ReadFileStream : public util::ReadInputStream
public:
ReadFileStream(wxInputStream& stream, const wxString& filename, DbStreamData& output) : ReadInputStream(stream, filename)
{
- if (readNumberC<int>() != FILE_FORMAT_VER) //read file format version
+ //|-------------------------------------------------------------------------------------
+ //| ensure 32/64 bit portability: used fixed size data types only e.g. boost::uint32_t |
+ //|-------------------------------------------------------------------------------------
+
+ if (readNumberC<boost::int32_t>() != FILE_FORMAT_VER) //read file format version
throw FileError(wxString(_("Incompatible synchronization database format:")) + wxT(" \n") + wxT("\"") + filename + wxT("\""));
//read DB id
- output.first = util::UniqueId(getStream());
- check();
+ const CharArray tmp = readArrayC();
+ output.first.assign(tmp->begin(), tmp->end());
DirectoryTOC& dbList = output.second;
dbList.clear();
- size_t dbCount = readNumberC<size_t>(); //number of databases: one for each sync-pair
+ boost::uint32_t dbCount = readNumberC<boost::uint32_t>(); //number of databases: one for each sync-pair
while (dbCount-- != 0)
{
- const util::UniqueId partnerID(getStream()); //DB id of partner databases
- check();
+ //DB id of partner databases
+ const CharArray tmp2 = readArrayC();
+ const std::string partnerID(tmp2->begin(), tmp2->end());
CharArray buffer = readArrayC(); //read db-entry stream (containing DirInformation)
@@ -188,8 +199,8 @@ DbStreamData loadFile(const Zstring& filename) //throw (FileError)
{
if (!ffs3::fileExists(filename))
throw FileErrorDatabaseNotExisting(wxString(_("Initial synchronization:")) + wxT(" \n\n") +
- _("One of the FreeFileSync database files is not yet existing:") + wxT(" \n") +
- wxT("\"") + zToWx(filename) + wxT("\""));
+ _("One of the FreeFileSync database files is not yet existing:") + wxT(" \n") +
+ wxT("\"") + zToWx(filename) + wxT("\""));
//read format description (uncompressed)
FileInputStreamDB uncompressed(filename); //throw (FileError)
@@ -219,13 +230,13 @@ std::pair<DirInfoPtr, DirInfoPtr> ffs3::loadFromDisk(const BaseDirMapping& baseM
if (dbLeft == dbEntriesLeft.second.end())
throw FileErrorDatabaseNotExisting(wxString(_("Initial synchronization:")) + wxT(" \n\n") +
- _("One of the FreeFileSync database entries within the following file is not yet existing:") + wxT(" \n") +
- wxT("\"") + zToWx(fileNameLeft) + wxT("\""));
+ _("One of the FreeFileSync database entries within the following file is not yet existing:") + wxT(" \n") +
+ wxT("\"") + zToWx(fileNameLeft) + wxT("\""));
if (dbRight == dbEntriesRight.second.end())
throw FileErrorDatabaseNotExisting(wxString(_("Initial synchronization:")) + wxT(" \n\n") +
- _("One of the FreeFileSync database entries within the following file is not yet existing:") + wxT(" \n") +
- wxT("\"") + zToWx(fileNameRight) + wxT("\""));
+ _("One of the FreeFileSync database entries within the following file is not yet existing:") + wxT(" \n") +
+ wxT("\"") + zToWx(fileNameRight) + wxT("\""));
//read streams into DirInfo
boost::shared_ptr<DirInformation> dirInfoLeft(new DirInformation);
@@ -278,13 +289,13 @@ private:
{
util::ProxyForEach<SaveDirInfo<side> > prx(*this); //grant std::for_each access to private parts of this class
- writeNumberC<size_t>(std::count_if(hierObj.useSubFiles().begin(), hierObj.useSubFiles().end(), IsNonEmpty<side>())); //number of (existing) files
+ writeNumberC<boost::uint32_t>(std::count_if(hierObj.useSubFiles().begin(), hierObj.useSubFiles().end(), IsNonEmpty<side>())); //number of (existing) files
std::for_each(hierObj.useSubFiles().begin(), hierObj.useSubFiles().end(), prx);
- writeNumberC<size_t>(std::count_if(hierObj.useSubLinks().begin(), hierObj.useSubLinks().end(), IsNonEmpty<side>())); //number of (existing) files
+ writeNumberC<boost::uint32_t>(std::count_if(hierObj.useSubLinks().begin(), hierObj.useSubLinks().end(), IsNonEmpty<side>())); //number of (existing) files
std::for_each(hierObj.useSubLinks().begin(), hierObj.useSubLinks().end(), prx);
- writeNumberC<size_t>(std::count_if(hierObj.useSubDirs().begin(), hierObj.useSubDirs().end(), IsNonEmpty<side>())); //number of (existing) directories
+ writeNumberC<boost::uint32_t>(std::count_if(hierObj.useSubDirs().begin(), hierObj.useSubDirs().end(), IsNonEmpty<side>())); //number of (existing) directories
std::for_each(hierObj.useSubDirs().begin(), hierObj.useSubDirs().end(), prx);
}
@@ -292,11 +303,11 @@ private:
{
if (!fileMap.isEmpty<side>())
{
- writeStringC(fileMap.getObjShortName()); //file name
- writeNumberC<long>( fileMap.getLastWriteTime<side>().GetHi()); //last modification time
- writeNumberC<unsigned long>(fileMap.getLastWriteTime<side>().GetLo()); //
- writeNumberC<unsigned long>(fileMap.getFileSize<side>().GetHi()); //filesize
- writeNumberC<unsigned long>(fileMap.getFileSize<side>().GetLo()); //
+ writeStringC(fileMap.getShortName<side>()); //file name
+ writeNumberC<boost::int32_t> (fileMap.getLastWriteTime<side>().GetHi()); //last modification time
+ writeNumberC<boost::uint32_t>(fileMap.getLastWriteTime<side>().GetLo()); //
+ writeNumberC<boost::uint32_t>(fileMap.getFileSize<side>().GetHi()); //filesize
+ writeNumberC<boost::uint32_t>(fileMap.getFileSize<side>().GetLo()); //
//fileMap.getFileID<side>().toStream(stream_); //unique file identifier
//check();
@@ -307,11 +318,11 @@ private:
{
if (!linkObj.isEmpty<side>())
{
- writeStringC(linkObj.getObjShortName());
- writeNumberC<long>( linkObj.getLastWriteTime<side>().GetHi()); //last modification time
- writeNumberC<unsigned long>(linkObj.getLastWriteTime<side>().GetLo()); //
+ writeStringC(linkObj.getShortName<side>());
+ writeNumberC<boost::int32_t> (linkObj.getLastWriteTime<side>().GetHi()); //last modification time
+ writeNumberC<boost::uint32_t>(linkObj.getLastWriteTime<side>().GetLo()); //
writeStringC(linkObj.getTargetPath<side>());
- writeNumberC<int>(linkObj.getLinkType<side>());
+ writeNumberC<boost::int32_t>(linkObj.getLinkType<side>());
}
}
@@ -319,7 +330,7 @@ private:
{
if (!dirMap.isEmpty<side>())
{
- writeStringC(dirMap.getObjShortName()); //directory name
+ writeStringC(dirMap.getShortName<side>()); //directory name
execute(dirMap); //recurse
}
}
@@ -332,22 +343,22 @@ public:
WriteFileStream(const DbStreamData& input, const wxString& filename, wxOutputStream& stream) : WriteOutputStream(filename, stream)
{
//save file format version
- writeNumberC<int>(FILE_FORMAT_VER);
+ writeNumberC<boost::int32_t>(FILE_FORMAT_VER);
//write DB id
- input.first.toStream(getStream());
- check();
+ writeArrayC(std::vector<char>(input.first.begin(), input.first.end()));
const DirectoryTOC& dbList = input.second;
- writeNumberC<size_t>(dbList.size()); //number of database records: one for each sync-pair
+ writeNumberC<boost::uint32_t>(static_cast<boost::uint32_t>(dbList.size())); //number of database records: one for each sync-pair
for (DirectoryTOC::const_iterator i = dbList.begin(); i != dbList.end(); ++i)
{
- i->first.toStream(getStream()); //DB id of partner database
- check();
+ //DB id of partner database
+ writeArrayC(std::vector<char>(i->first.begin(), i->first.end()));
- writeArrayC(*(i->second)); //write DirInformation stream
+ //write DirInformation stream
+ writeArrayC(*(i->second));
}
}
};
@@ -377,19 +388,16 @@ void saveFile(const DbStreamData& dbStream, const Zstring& filename) //throw (Fi
}
-bool entryExisting(const DirectoryTOC& table, const util::UniqueId& newKey, const MemoryStreamPtr& newValue)
+bool entryExisting(const DirectoryTOC& table, const UniqueId& newKey, const MemoryStreamPtr& newValue)
{
DirectoryTOC::const_iterator iter = table.find(newKey);
if (iter == table.end())
return false;
- if (!iter->second.get())
- return !newValue.get();
-
- if (!newValue.get())
- return false;
+ if (!newValue.get() || !iter->second.get())
+ return !newValue.get() && !iter->second.get();
- return newValue->size() == iter->second->size() && std::equal(newValue->begin(), newValue->end(), iter->second->begin());
+ return *newValue == *iter->second;
}
@@ -407,22 +415,27 @@ void ffs3::saveToDisk(const BaseDirMapping& baseMapping) //throw (FileError)
//read file data: db ID + mapping of partner-ID/DirInfo-stream: may throw!
DbStreamData dbEntriesLeft;
- if (ffs3::fileExists(baseMapping.getDBFilename<LEFT_SIDE>()))
- try
- {
- dbEntriesLeft = ::loadFile(baseMapping.getDBFilename<LEFT_SIDE>());
- }
- catch(FileError&) {} //if error occurs: just overwrite old file! User is already informed about issues right after comparing!
- //else -> dbEntriesLeft has empty mapping, but already a DB-ID!
+ try
+ {
+ dbEntriesLeft = ::loadFile(baseMapping.getDBFilename<LEFT_SIDE>());
+ }
+ catch(FileError&)
+ {
+ //if error occurs: just overwrite old file! User is already informed about issues right after comparing!
+ //dbEntriesLeft has empty mapping, but already a DB-ID!
+ dbEntriesLeft.first = util::generateGUID();
+ }
//read file data: db ID + mapping of partner-ID/DirInfo-stream: may throw!
DbStreamData dbEntriesRight;
- if (ffs3::fileExists(baseMapping.getDBFilename<RIGHT_SIDE>()))
- try
- {
- dbEntriesRight = ::loadFile(baseMapping.getDBFilename<RIGHT_SIDE>());
- }
- catch(FileError&) {} //if error occurs: just overwrite old file! User is already informed about issues right after comparing!
+ try
+ {
+ dbEntriesRight = ::loadFile(baseMapping.getDBFilename<RIGHT_SIDE>());
+ }
+ catch(FileError&)
+ {
+ dbEntriesRight.first = util::generateGUID();
+ }
//create new database entries
MemoryStreamPtr dbEntryLeft(new std::vector<char>);
diff --git a/library/db_file.h b/library/db_file.h
index ea9d68ad..8b88473d 100644
--- a/library/db_file.h
+++ b/library/db_file.h
@@ -1,7 +1,7 @@
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
#ifndef DBFILE_H_INCLUDED
diff --git a/library/detect_renaming.cpp b/library/detect_renaming.cpp
index 617a3eba..3c491ae3 100644
--- a/library/detect_renaming.cpp
+++ b/library/detect_renaming.cpp
@@ -1,7 +1,7 @@
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
#include "detect_renaming.h"
diff --git a/library/detect_renaming.h b/library/detect_renaming.h
index 45bdf59d..ab974cf9 100644
--- a/library/detect_renaming.h
+++ b/library/detect_renaming.h
@@ -1,7 +1,7 @@
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
#ifndef DETECTRENAMING_H_INCLUDED
diff --git a/library/dir_lock.cpp b/library/dir_lock.cpp
index f4ed8e07..3d443b11 100644
--- a/library/dir_lock.cpp
+++ b/library/dir_lock.cpp
@@ -17,6 +17,7 @@
#include "../shared/serialize.h"
#include <boost/cstdint.hpp>
#include "../shared/build_info.h"
+#include <wx/log.h>
#ifdef FFS_WIN
#include <tlhelp32.h>
@@ -40,6 +41,9 @@ const size_t EMIT_LIFE_SIGN_INTERVAL = 5000; //show life sign; unit [ms]
const size_t POLL_LIFE_SIGN_INTERVAL = 6000; //poll for life sign; unit [ms]
const size_t DETECT_EXITUS_INTERVAL = 30000; //assume abandoned lock; unit [ms]
+const char LOCK_FORMAT_DESCR[] = "FreeFileSync";
+const int LOCK_FORMAT_VER = 1; //lock file format version
+
typedef Zbase<Zchar, StorageDeepCopy> BasicString; //thread safe string class
}
@@ -72,7 +76,7 @@ public:
}
catch (const std::exception& e) //exceptions must be catched per thread
{
- wxMessageBox(wxString::FromAscii(e.what()), wxString(_("An exception occurred!")) + wxT("(Dirlock)"), wxOK | wxICON_ERROR);
+ wxSafeShowMessage(wxString(_("An exception occurred!")) + wxT("(Dirlock)"), wxString::FromAscii(e.what())); //simple wxMessageBox won't do for threads
}
}
@@ -130,18 +134,6 @@ private:
namespace
{
-bool somethingExists(const Zstring& objname) //throw() check whether any object with this name exists
-{
-#ifdef FFS_WIN
- return ::GetFileAttributes(applyLongPathPrefix(objname).c_str()) != INVALID_FILE_ATTRIBUTES;
-
-#elif defined FFS_LINUX
- struct stat fileInfo;
- return ::lstat(objname.c_str(), &fileInfo) == 0;
-#endif
-}
-
-
void deleteLockFile(const Zstring& filename) //throw (FileError)
{
#ifdef FFS_WIN
@@ -207,24 +199,25 @@ Zstring deleteAbandonedLockName(const Zstring& lockfilename)
namespace
{
+//read string from file stream
inline
-std::string readString(wxInputStream& stream) //read string from file stream
+std::string readString(wxInputStream& stream) //throw (std::exception)
{
const boost::uint32_t strLength = util::readNumber<boost::uint32_t>(stream);
std::string output;
- if (strLength > 0)
- {
- output.resize(strLength);
- stream.Read(&output[0], strLength);
- }
+ if (strLength > 0)
+ {
+ output.resize(strLength); //may throw for corrupted data
+ stream.Read(&output[0], strLength);
+ }
return output;
}
inline
void writeString(wxOutputStream& stream, const std::string& str) //write string to filestream
-{
- const boost::uint32_t strLength = static_cast<boost::uint32_t>(str.length());
+{
+ const boost::uint32_t strLength = static_cast<boost::uint32_t>(str.length());
util::writeNumber<boost::uint32_t>(stream, strLength);
stream.Write(str.c_str(), strLength);
}
@@ -246,6 +239,7 @@ struct LockInformation
{
LockInformation()
{
+ lockId = util::generateGUID();
#ifdef FFS_WIN
procDescr.processId = ::GetCurrentProcessId();
#elif defined FFS_LINUX
@@ -254,9 +248,16 @@ struct LockInformation
procDescr.computerId = getComputerId();
}
- LockInformation(wxInputStream& stream) : //read
- lockId(util::UniqueId(stream))
+ LockInformation(wxInputStream& stream) //read
{
+ char formatDescr[sizeof(LOCK_FORMAT_DESCR)] = {};
+ stream.Read(formatDescr, sizeof(LOCK_FORMAT_DESCR)); //file format header
+ const int lockFileVersion = util::readNumber<boost::int32_t>(stream); //
+ (void)lockFileVersion;
+
+ //some format checking here?
+
+ lockId = readString(stream);
procDescr.processId = static_cast<ProcessId>(util::readNumber<boost::uint64_t>(stream)); //possible loss of precision (32/64 bit process) covered by buildId
procDescr.computerId = readString(stream);
}
@@ -265,7 +266,10 @@ struct LockInformation
{
assert_static(sizeof(ProcessId) <= sizeof(boost::uint64_t)); //ensure portability
- lockId.toStream(stream);
+ stream.Write(LOCK_FORMAT_DESCR, sizeof(LOCK_FORMAT_DESCR));
+ util::writeNumber<boost::int32_t>(stream, LOCK_FORMAT_VER);
+
+ writeString(stream, lockId);
util::writeNumber<boost::uint64_t>(stream, procDescr.processId);
writeString(stream, procDescr.computerId);
}
@@ -276,7 +280,7 @@ struct LockInformation
typedef pid_t ProcessId;
#endif
- util::UniqueId lockId; //16 byte portable construct
+ std::string lockId; //16 byte UUID
struct ProcessDescription
{
@@ -314,7 +318,6 @@ ProcessStatus getProcessStatus(const LockInformation::ProcessDescription& procDe
if (!::Process32First(snapshot, //__in HANDLE hSnapshot,
&processEntry)) //__inout LPPROCESSENTRY32 lppe
return PROC_STATUS_NO_IDEA;
-
do
{
if (processEntry.th32ProcessID == procDescr.processId)
@@ -335,7 +338,7 @@ ProcessStatus getProcessStatus(const LockInformation::ProcessDescription& procDe
void writeLockInfo(const Zstring& lockfilename) //throw (FileError)
{
- //write GUID at the beginning of the file: this ID is a universal identifier for this lock (no matter what the path is, considering symlinks ,etc.)
+ //write GUID at the beginning of the file: this ID is a universal identifier for this lock (no matter what the path is, considering symlinks, distributed network, etc.)
FileOutputStream lockFile(lockfilename); //throw FileError()
LockInformation().toStream(lockFile);
}
@@ -349,7 +352,7 @@ LockInformation retrieveLockInfo(const Zstring& lockfilename) //throw (FileError
}
-util::UniqueId retrieveLockId(const Zstring& lockfilename) //throw (FileError, ErrorNotExisting)
+std::string retrieveLockId(const Zstring& lockfilename) //throw (FileError, ErrorNotExisting)
{
return retrieveLockInfo(lockfilename).lockId;
}
@@ -541,7 +544,7 @@ public:
try //actual check based on lock UUID, deadlock prevention: "lockfilename" may be an alternative name for an already active lock
{
- const util::UniqueId lockId = retrieveLockId(lockfilename); //throw (FileError, ErrorNotExisting)
+ const std::string lockId = retrieveLockId(lockfilename); //throw (FileError, ErrorNotExisting)
const boost::shared_ptr<SharedDirLock>& activeLock = findActive(lockId); //returns null-lock if not found
if (activeLock)
@@ -554,7 +557,7 @@ public:
//not yet in buffer, so create a new directory lock
boost::shared_ptr<SharedDirLock> newLock(new SharedDirLock(lockfilename, callback)); //throw (FileError)
- const util::UniqueId newLockId = retrieveLockId(lockfilename); //throw (FileError, ErrorNotExisting)
+ const std::string newLockId = retrieveLockId(lockfilename); //throw (FileError, ErrorNotExisting)
//update registry
fileToUuid[lockfilename] = newLockId; //throw()
@@ -566,7 +569,7 @@ public:
private:
LockAdmin() {}
- boost::shared_ptr<SharedDirLock> findActive(const util::UniqueId& lockId) //returns null-lock if not found
+ boost::shared_ptr<SharedDirLock> findActive(const std::string& lockId) //returns null-lock if not found
{
UuidToLockMap::const_iterator iterLock = uuidToLock.find(lockId);
return iterLock != uuidToLock.end() ?
@@ -576,8 +579,9 @@ private:
typedef boost::weak_ptr<SharedDirLock> SharedLock;
- typedef std::map<Zstring, util::UniqueId, LessFilename> FileToUuidMap; //n:1 handle uppper/lower case correctly
- typedef std::map<util::UniqueId, SharedLock> UuidToLockMap; //1:1
+ typedef std::string UniqueId;
+ typedef std::map<Zstring, UniqueId, LessFilename> FileToUuidMap; //n:1 handle uppper/lower case correctly
+ typedef std::map<UniqueId, SharedLock> UuidToLockMap; //1:1
FileToUuidMap fileToUuid; //lockname |-> UUID; locks can be referenced by a lockfilename or alternatively a UUID
UuidToLockMap uuidToLock; //UUID |-> "shared lock ownership"
diff --git a/library/dir_lock.h b/library/dir_lock.h
index fba65d2b..9ae4da08 100644
--- a/library/dir_lock.h
+++ b/library/dir_lock.h
@@ -19,7 +19,7 @@ RAII structure to place a directory lock against other FFS processes:
- ownership shared between all object instances refering to a specific lock location(= UUID)
- can be copied safely and efficiently! (ref-counting)
- detects and resolves abandoned locks (instantly if lock is associated with local pc, else after 30 seconds)
- - race-free (Windows, almost on Linux)
+ - race-free (Windows, almost on Linux(NFS))
*/
class DirLock
{
diff --git a/library/error_log.cpp b/library/error_log.cpp
index 9936a2ea..4f7c5847 100644
--- a/library/error_log.cpp
+++ b/library/error_log.cpp
@@ -1,7 +1,7 @@
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
#include "error_log.h"
diff --git a/library/error_log.h b/library/error_log.h
index 876f78b9..d5696f80 100644
--- a/library/error_log.h
+++ b/library/error_log.h
@@ -1,7 +1,7 @@
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
#ifndef ERRORLOGGING_H_INCLUDED
diff --git a/library/filter.cpp b/library/filter.cpp
index 7697ea4b..789a5d81 100644
--- a/library/filter.cpp
+++ b/library/filter.cpp
@@ -1,7 +1,7 @@
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
#include "filter.h"
diff --git a/library/filter.h b/library/filter.h
index 91caff7d..c1be61eb 100644
--- a/library/filter.h
+++ b/library/filter.h
@@ -1,7 +1,7 @@
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
#ifndef FFS_FILTER_H_INCLUDED
@@ -55,8 +55,8 @@ public:
static FilterRef loadFilter(wxInputStream& stream); //CAVEAT!!! adapt this method for each new derivation!!!
private:
- virtual Zstring uniqueClassIdentifier() const = 0; //get identifier, used for serialization
virtual void save(wxOutputStream& stream) const = 0; //serialization
+ virtual Zstring uniqueClassIdentifier() const = 0; //get identifier, used for serialization
virtual bool cmpLessSameType(const BaseFilter& other) const = 0; //typeid(*this) == typeid(other) in this context!
};
@@ -64,14 +64,15 @@ private:
class NullFilter : public BaseFilter //no filtering at all
{
public:
- static FilterRef load(wxInputStream& stream); //"serial constructor"
virtual bool passFileFilter(const Zstring& relFilename) const;
virtual bool passDirFilter(const Zstring& relDirname, bool* subObjMightMatch) const;
virtual bool isNull() const;
private:
- virtual Zstring uniqueClassIdentifier() const;
+ friend class BaseFilter;
virtual void save(wxOutputStream& stream) const {}
+ virtual Zstring uniqueClassIdentifier() const;
+ static FilterRef load(wxInputStream& stream); //"serial constructor"
virtual bool cmpLessSameType(const BaseFilter& other) const;
};
@@ -80,15 +81,16 @@ class NameFilter : public BaseFilter //standard filter by filename
{
public:
NameFilter(const Zstring& includeFilter, const Zstring& excludeFilter);
- static FilterRef load(wxInputStream& stream); //"serial constructor"
virtual bool passFileFilter(const Zstring& relFilename) const;
virtual bool passDirFilter(const Zstring& relDirname, bool* subObjMightMatch) const;
virtual bool isNull() const;
private:
- virtual Zstring uniqueClassIdentifier() const;
+ friend class BaseFilter;
virtual void save(wxOutputStream& stream) const;
+ virtual Zstring uniqueClassIdentifier() const;
+ static FilterRef load(wxInputStream& stream); //"serial constructor"
virtual bool cmpLessSameType(const BaseFilter& other) const;
std::set<Zstring> filterFileIn; //upper case (windows)
@@ -105,15 +107,16 @@ class CombinedFilter : public BaseFilter //combine two filters to match if and
{
public:
CombinedFilter(const FilterRef& first, const FilterRef& second) : first_(first), second_(second) {}
- static FilterRef load(wxInputStream& stream); //"serial constructor"
virtual bool passFileFilter(const Zstring& relFilename) const;
virtual bool passDirFilter(const Zstring& relDirname, bool* subObjMightMatch) const;
virtual bool isNull() const;
private:
- virtual Zstring uniqueClassIdentifier() const;
+ friend class BaseFilter;
virtual void save(wxOutputStream& stream) const;
+ virtual Zstring uniqueClassIdentifier() const;
+ static FilterRef load(wxInputStream& stream); //"serial constructor"
virtual bool cmpLessSameType(const BaseFilter& other) const;
const FilterRef first_;
diff --git a/library/icon_buffer.cpp b/library/icon_buffer.cpp
index 20ff60f7..e03ec8c4 100644
--- a/library/icon_buffer.cpp
+++ b/library/icon_buffer.cpp
@@ -1,7 +1,7 @@
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
#include "icon_buffer.h"
@@ -9,6 +9,7 @@
#include <map>
#include <queue>
#include <set>
+#include <wx/log.h>
#ifdef FFS_WIN
#include <wx/msw/wrapwin.h> //includes "windows.h"
@@ -321,7 +322,7 @@ void IconBuffer::WorkerThread::operator()() //thread entry
}
catch (const std::exception& e) //exceptions must be catched per thread
{
- wxMessageBox(wxString::FromAscii(e.what()), wxString(_("An exception occurred!")) + wxT("(Icon buffer)"), wxOK | wxICON_ERROR);
+ wxSafeShowMessage(wxString(_("An exception occurred!")) + wxT("(Icon buffer)"), wxString::FromAscii(e.what())); //simple wxMessageBox won't do for threads
}
}
@@ -364,7 +365,7 @@ void IconBuffer::WorkerThread::doWork()
//---------------------------------------------------------------------------------------------------
-class IconBuffer::IconDB : public std::map<BasicString, IconBuffer::IconHolder> {}; //entryName/icon -> ATTENTION: avoid ref-counting for this shared data structure!
+class IconBuffer::IconDB : public std::map<BasicString, IconBuffer::IconHolder, LessFilename> {}; //entryName/icon -> ATTENTION: avoid ref-counting for this shared data structure!
class IconBuffer::IconDbSequence : public std::queue<BasicString> {}; //entryName
//---------------------------------------------------------------------------------------------------
@@ -427,7 +428,7 @@ void IconBuffer::insertIntoBuffer(const BasicString& entryName, const IconHolder
assert(buffer->size() == bufSequence->size());
//remove elements if buffer becomes too big:
- if (buffer->size() > BUFFER_SIZE) //limit buffer size: critical because GDI resources are limited (e.g. 10000 on XP per process)
+ if (buffer->size() > BUFFER_SIZE_MAX) //limit buffer size: critical because GDI resources are limited (e.g. 10000 on XP per process)
{
//remove oldest element
buffer->erase(bufSequence->front());
diff --git a/library/icon_buffer.h b/library/icon_buffer.h
index 3e021445..d273a970 100644
--- a/library/icon_buffer.h
+++ b/library/icon_buffer.h
@@ -1,7 +1,7 @@
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
#ifndef ICONBUFFER_H_INCLUDED
@@ -36,14 +36,14 @@ private:
IconBuffer();
~IconBuffer();
- static const size_t BUFFER_SIZE = 800; //maximum number of icons to buffer
+ static const size_t BUFFER_SIZE_MAX = 800; //maximum number of icons to buffer
class IconDB;
class IconHolder;
class IconDbSequence;
//---------------------------------------------------------------------------------------------------
-typedef Zbase<Zchar, StorageDeepCopy> BasicString; //thread safe string class
+ typedef Zbase<Zchar, StorageDeepCopy> BasicString; //thread safe string class
//avoid reference-counted objects for shared data: NOT THREADSAFE!!! (implicitly shared variable: ref-count)
//---------------------------------------------------------------------------------------------------
@@ -54,8 +54,8 @@ typedef Zbase<Zchar, StorageDeepCopy> BasicString; //thread safe string class
static IconHolder getAssociatedIconByExt(const BasicString& extension);
#ifdef FFS_WIN
-static BasicString getFileExtension(const BasicString& filename);
-static bool isPriceyExtension(const BasicString& extension);
+ static BasicString getFileExtension(const BasicString& filename);
+ static bool isPriceyExtension(const BasicString& extension);
#endif
//---------------------- Shared Data -------------------------
diff --git a/library/pch.h b/library/pch.h
index f7ff59ab..a8d6ae30 100644
--- a/library/pch.h
+++ b/library/pch.h
@@ -1,7 +1,7 @@
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
#ifndef FFS_PRECOMPILED_HEADER
diff --git a/library/process_xml.cpp b/library/process_xml.cpp
index bccd8e3a..c4e80d17 100644
--- a/library/process_xml.cpp
+++ b/library/process_xml.cpp
@@ -1,7 +1,7 @@
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
#include "process_xml.h"
@@ -432,6 +432,10 @@ void FfsXmlParser::readXmlGlobalSettings(xmlAccess::XmlGlobalSettings& outputCfg
//folder dependency check
readXmlElementLogging("CheckForDependentFolders", optionalDialogs, outputCfg.optDialogs.warningDependentFolders);
+
+ //check for multi write access for directory as part of multiple pairs
+ readXmlElementLogging("CheckForMultipleWriteAccess", optionalDialogs, outputCfg.optDialogs.warningMultiFolderWriteAccess);
+
//significant difference check
readXmlElementLogging("CheckForSignificantDifference", optionalDialogs, outputCfg.optDialogs.warningSignificantDifference);
//check free disk space
@@ -517,9 +521,7 @@ void FfsXmlParser::readXmlGlobalSettings(xmlAccess::XmlGlobalSettings& outputCfg
//load config history elements
readXmlElementLogging("Folder", historyRight, outputCfg.gui.folderHistoryRight);
-
- readXmlElementLogging("SelectedTabBottomLeft", mainWindow, outputCfg.gui.selectedTabBottomLeft);
-
+ readXmlElementLogging("Perspective", mainWindow, outputCfg.gui.guiPerspectiveLast);
//external applications
const TiXmlElement* extApps = TiXmlHandleConst(gui).FirstChild("ExternalApplications").FirstChild("Commandline").ToElement();
@@ -542,9 +544,6 @@ void FfsXmlParser::readXmlGlobalSettings(xmlAccess::XmlGlobalSettings& outputCfg
//load config file history
const TiXmlElement* cfgHistory = TiXmlHandleConst(gui).FirstChild("ConfigHistory").ToElement();
- //load max. history size
- readXmlAttributeLogging("MaximumSize", cfgHistory, outputCfg.gui.cfgHistoryMax);
-
//load config history elements
readXmlElementLogging("File", cfgHistory, outputCfg.gui.cfgFileHistory);
@@ -846,6 +845,9 @@ bool writeXmlGlobalSettings(const xmlAccess::XmlGlobalSettings& inputCfg, TiXmlD
//warning: dependent folders
addXmlElement("CheckForDependentFolders", inputCfg.optDialogs.warningDependentFolders, optionalDialogs);
+ //check for multi write access for directory as part of multiple pairs
+ addXmlElement("CheckForMultipleWriteAccess", inputCfg.optDialogs.warningMultiFolderWriteAccess, optionalDialogs);
+
//significant difference check
addXmlElement("CheckForSignificantDifference", inputCfg.optDialogs.warningSignificantDifference, optionalDialogs);
@@ -941,7 +943,7 @@ bool writeXmlGlobalSettings(const xmlAccess::XmlGlobalSettings& inputCfg, TiXmlD
addXmlElement("Folder", inputCfg.gui.folderHistoryLeft, historyLeft);
addXmlElement("Folder", inputCfg.gui.folderHistoryRight, historyRight);
- addXmlElement("SelectedTabBottomLeft", inputCfg.gui.selectedTabBottomLeft, mainWindow);
+ addXmlElement("Perspective", inputCfg.gui.guiPerspectiveLast, mainWindow);
//external applications
TiXmlElement* extApp = new TiXmlElement("ExternalApplications");
@@ -960,7 +962,6 @@ bool writeXmlGlobalSettings(const xmlAccess::XmlGlobalSettings& inputCfg, TiXmlD
TiXmlElement* cfgHistory = new TiXmlElement("ConfigHistory");
gui->LinkEndChild(cfgHistory);
- addXmlAttribute("MaximumSize", inputCfg.gui.cfgHistoryMax, cfgHistory);
addXmlElement("File", inputCfg.gui.cfgFileHistory, cfgHistory);
@@ -992,6 +993,7 @@ wxString xmlAccess::getGlobalConfigFile()
void xmlAccess::OptionalDialogs::resetDialogs()
{
warningDependentFolders = true;
+ warningMultiFolderWriteAccess = true;
warningSignificantDifference = true;
warningNotEnoughDiskSpace = true;
warningUnresolvedConflicts = true;
diff --git a/library/process_xml.h b/library/process_xml.h
index 24a2fe9b..92d94d14 100644
--- a/library/process_xml.h
+++ b/library/process_xml.h
@@ -1,7 +1,7 @@
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
#ifndef PROCESSXML_H_INCLUDED
@@ -100,6 +100,7 @@ struct OptionalDialogs
void resetDialogs();
bool warningDependentFolders;
+ bool warningMultiFolderWriteAccess;
bool warningSignificantDifference;
bool warningNotEnoughDiskSpace;
bool warningUnresolvedConflicts;
@@ -142,10 +143,8 @@ struct XmlGlobalSettings
isMaximized(false),
autoAdjustColumnsLeft(false),
autoAdjustColumnsRight(false),
- cfgHistoryMax(10),
folderHistLeftMax(12),
folderHistRightMax(12),
- selectedTabBottomLeft(0),
deleteOnBothSides(false),
useRecyclerForManualDeletion(true), //enable if OS supports it; else user will have to activate first and then get an error message
#ifdef FFS_WIN
@@ -187,7 +186,6 @@ struct XmlGlobalSettings
ExternalApps externelApplications;
std::vector<wxString> cfgFileHistory;
- unsigned int cfgHistoryMax;
std::vector<wxString> folderHistoryLeft;
unsigned int folderHistLeftMax;
@@ -195,8 +193,6 @@ struct XmlGlobalSettings
std::vector<wxString> folderHistoryRight;
unsigned int folderHistRightMax;
- int selectedTabBottomLeft;
-
bool deleteOnBothSides;
bool useRecyclerForManualDeletion;
bool textSearchRespectCase;
@@ -205,6 +201,8 @@ struct XmlGlobalSettings
size_t addFolderPairCountMax;
long lastUpdateCheck; //time of last update check
+
+ wxString guiPerspectiveLast; //used by wxAuiManager
} gui;
//---------------------------------------------------------------------
diff --git a/library/resources.cpp b/library/resources.cpp
index 637dfea3..5ef33826 100644
--- a/library/resources.cpp
+++ b/library/resources.cpp
@@ -1,7 +1,7 @@
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
#include "resources.h"
diff --git a/library/resources.h b/library/resources.h
index d2e7ce49..776fe785 100644
--- a/library/resources.h
+++ b/library/resources.h
@@ -1,7 +1,7 @@
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
#ifndef RESOURCES_H_INCLUDED
diff --git a/library/soft_filter.cpp b/library/soft_filter.cpp
index 18dcfd54..1c191b98 100644
--- a/library/soft_filter.cpp
+++ b/library/soft_filter.cpp
@@ -1,7 +1,7 @@
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
#include "soft_filter.h"
diff --git a/library/soft_filter.h b/library/soft_filter.h
index dc889245..ad81ea44 100644
--- a/library/soft_filter.h
+++ b/library/soft_filter.h
@@ -1,7 +1,7 @@
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
#ifndef SOFTFILTER_H_INCLUDED
diff --git a/library/statistics.cpp b/library/statistics.cpp
index d246a7cc..7a77740c 100644
--- a/library/statistics.cpp
+++ b/library/statistics.cpp
@@ -1,7 +1,7 @@
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
#include "statistics.h"
@@ -29,7 +29,7 @@ RetrieveStatistics::~RetrieveStatistics()
outputFile.Write(wxT("Time(ms);Objects;Data\n"));
- for (std::vector<statEntry>::const_iterator i = data.begin(); i != data.end(); ++i)
+ for (std::vector<StatEntry>::const_iterator i = data.begin(); i != data.end(); ++i)
{
using common::numberToString;
outputFile.Write(numberToString(i->time));
@@ -44,7 +44,7 @@ RetrieveStatistics::~RetrieveStatistics()
void RetrieveStatistics::writeEntry(const double value, const int objects)
{
- statEntry newEntry;
+ StatEntry newEntry;
newEntry.value = value;
newEntry.objects = objects;
newEntry.time = timer->Time();
@@ -104,7 +104,7 @@ wxString Statistics::formatRemainingTime(double timeInMs) const
formattedTime -= formattedTime % 5; //"floor"
}
else
- formattedTime = int(remainingTime); //"floor"
+ formattedTime = static_cast<int>(remainingTime); //"floor"
}
remainingTimeLast = formattedTime;
@@ -115,10 +115,10 @@ wxString Statistics::formatRemainingTime(double timeInMs) const
}
-Statistics::Statistics(const int totalObjectCount,
- const double totalDataAmount,
- const unsigned windowSizeRemainingTime,
- const unsigned windowSizeBytesPerSecond) :
+Statistics::Statistics(int totalObjectCount,
+ double totalDataAmount,
+ unsigned windowSizeRemainingTime,
+ unsigned windowSizeBytesPerSecond) :
objectsTotal(totalObjectCount),
dataTotal(totalDataAmount),
windowSizeRemTime(windowSizeRemainingTime),
@@ -132,20 +132,27 @@ Statistics::~Statistics()
delete timer;
}
-void Statistics::addMeasurement(const int objectsCurrent, const double dataCurrent)
+void Statistics::addMeasurement(int objectsCurrent, double dataCurrent)
{
- record newEntry;
- newEntry.objects = objectsCurrent;
- newEntry.data = dataCurrent;
- newEntry.time = timer->Time();
+ Record newRecord;
+ newRecord.objects = objectsCurrent;
+ newRecord.data = dataCurrent;
+
+ const long currentTime = timer->Time();
+
+ const TimeRecordMap::value_type newEntry(currentTime, newRecord);
//insert new record
- measurements.push_back(newEntry);
+ if (!measurements.empty())
+ measurements.insert(--measurements.end(), newEntry); //use fact that time is monotonously ascending
+ else
+ measurements.insert(newEntry);
//remove all records earlier than "currentTime - windowSize"
- const long newBegin = newEntry.time - windowMax;
- while (!measurements.empty() && measurements.front().time < newBegin)
- measurements.pop_front();
+ const long newBegin = currentTime - windowMax;
+ TimeRecordMap::iterator windowBegin = measurements.upper_bound(newBegin);
+ if (windowBegin != measurements.begin())
+ measurements.erase(measurements.begin(), --windowBegin); //retain one point before newBegin in order to handle "measurement holes"
}
@@ -153,20 +160,19 @@ wxString Statistics::getRemainingTime() const
{
if (!measurements.empty())
{
+ const TimeRecordMap::value_type& backRecord = *measurements.rbegin();
//find start of records "window"
- const record backElement = measurements.back();
- const long frontTime = backElement.time - windowSizeRemTime;
- std::list<record>::const_iterator frontElement = measurements.end();
- do
- {
- --frontElement;
- }
- while (frontElement != measurements.begin() && frontElement->time > frontTime);
+ const long frontTime = backRecord.first - windowSizeRemTime;
+ TimeRecordMap::const_iterator windowBegin = measurements.upper_bound(frontTime);
+ if (windowBegin != measurements.begin())
+ --windowBegin; //one point before window begin in order to handle "measurement holes"
- const double timeDelta = backElement.time - frontElement->time;
- const double dataDelta = backElement.data - frontElement->data;
+ const TimeRecordMap::value_type& frontRecord = *windowBegin;
+//-----------------------------------------------------------------------------------------------
+ const double timeDelta = backRecord.first - frontRecord.first;
+ const double dataDelta = backRecord.second.data - frontRecord.second.data;
- const double dataRemaining = dataTotal - backElement.data;
+ const double dataRemaining = dataTotal - backRecord.second.data;
if (!isNull(dataDelta))
return formatRemainingTime(dataRemaining * timeDelta / dataDelta);
@@ -180,17 +186,17 @@ wxString Statistics::getBytesPerSecond() const
{
if (!measurements.empty())
{
+ const TimeRecordMap::value_type& backRecord = *measurements.rbegin();
//find start of records "window"
- const long frontTime = measurements.back().time - windowSizeBPS;
- std::list<record>::const_iterator frontElement = measurements.end();
- do
- {
- --frontElement;
- }
- while (frontElement != measurements.begin() && frontElement->time > frontTime);
-
- const double timeDelta = measurements.back().time - frontElement->time;
- const double dataDelta = measurements.back().data - frontElement->data;
+ const long frontTime = backRecord.first - windowSizeBPS;
+ TimeRecordMap::const_iterator windowBegin = measurements.upper_bound(frontTime);
+ if (windowBegin != measurements.begin())
+ --windowBegin; //one point before window begin in order to handle "measurement holes"
+
+ const TimeRecordMap::value_type& frontRecord = *windowBegin;
+//-----------------------------------------------------------------------------------------------
+ const double timeDelta = backRecord.first - frontRecord.first;
+ const double dataDelta = backRecord.second.data - frontRecord.second.data;
if (!isNull(timeDelta))
return ffs3::formatFilesizeToShortString(dataDelta * 1000 / timeDelta) + _("/sec");
diff --git a/library/statistics.h b/library/statistics.h
index 26e8c196..a9692d77 100644
--- a/library/statistics.h
+++ b/library/statistics.h
@@ -1,14 +1,14 @@
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
#ifndef STATISTICS_H_INCLUDED
#define STATISTICS_H_INCLUDED
#include <vector>
-#include <list>
+#include <map>
#include <memory>
#include <wx/defs.h>
@@ -27,14 +27,14 @@ public:
void writeEntry(const double value, const int objects);
private:
- struct statEntry
+ struct StatEntry
{
long time;
int objects;
double value;
};
- std::vector<statEntry> data;
+ std::vector<StatEntry> data;
std::auto_ptr<wxStopWatch> timer;
};
@@ -42,14 +42,14 @@ private:
class Statistics
{
public:
- Statistics(const int totalObjectCount,
- const double totalDataAmount,
- const unsigned windowSizeRemainingTime, //time in ms
- const unsigned windowSizeBytesPerSecond); //time in ms
+ Statistics(int totalObjectCount,
+ double totalDataAmount,
+ unsigned windowSizeRemainingTime, //time in ms
+ unsigned windowSizeBytesPerSecond); //time in ms
~Statistics();
- void addMeasurement(const int objectsCurrent, const double dataCurrent);
+ void addMeasurement(int objectsCurrent, double dataCurrent);
wxString getRemainingTime() const; //returns the remaining time in milliseconds
wxString getBytesPerSecond() const;
@@ -57,7 +57,7 @@ public:
void resumeTimer();
private:
- wxString formatRemainingTime(const double timeInMs) const;
+ wxString formatRemainingTime(double timeInMs) const;
const int objectsTotal;
const double dataTotal;
@@ -68,14 +68,15 @@ private:
mutable int remainingTimeLast; //used for "smoothening" remaining time
- struct record
+ struct Record
{
- int objects;
+ int objects; //object count
double data; //unit: bytes
- long time; //unit: milliseconds
};
- std::list<record> measurements;
+ typedef std::multimap<long, Record> TimeRecordMap; //time, unit: milliseconds
+ TimeRecordMap measurements; //
+
wxStopWatch* timer;
};
diff --git a/library/status_handler.cpp b/library/status_handler.cpp
index 0f953a32..e81746a4 100644
--- a/library/status_handler.cpp
+++ b/library/status_handler.cpp
@@ -1,7 +1,7 @@
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
#include "status_handler.h"
diff --git a/library/status_handler.h b/library/status_handler.h
index c15a80ba..d89c4f5b 100644
--- a/library/status_handler.h
+++ b/library/status_handler.h
@@ -1,7 +1,7 @@
// **************************************************************************
// * This file is part of the FreeFileSync project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
-// * Copyright (C) 2008-2010 ZenJu (zhnmju123 AT gmx.de) *
+// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) *
// **************************************************************************
//
#ifndef STATUSHANDLER_H_INCLUDED
bgstack15