summaryrefslogtreecommitdiff
path: root/zen
diff options
context:
space:
mode:
Diffstat (limited to 'zen')
-rw-r--r--zen/file_handling.cpp2
-rw-r--r--zen/file_handling.h3
-rw-r--r--zen/file_traverser.h4
-rw-r--r--zen/format_unit.cpp16
-rw-r--r--zen/serialize.h34
-rw-r--r--zen/string_base.h6
-rw-r--r--zen/string_traits.h1
-rw-r--r--zen/tick_count.h41
-rw-r--r--zen/type_traits.h7
-rw-r--r--zen/utf.h19
10 files changed, 64 insertions, 69 deletions
diff --git a/zen/file_handling.cpp b/zen/file_handling.cpp
index cf92f346..cecebff1 100644
--- a/zen/file_handling.cpp
+++ b/zen/file_handling.cpp
@@ -2285,7 +2285,7 @@ void zen::copyFile(const Zstring& sourceFile, //throw FileError, ErrorTargetPath
4. copy file from USB to local drive via explorer
=>
NTFS <-> FAT, file exists on both sides; mod times match, DST hack on USB stick causes 1-hour offset when comparing in FFS.
- When syncing modification time is copied correctly, but new DST hack fails to apply and old creation time is reused (see above).
+ When syncing, modification time is copied correctly, but new DST hack fails to apply and old creation time is reused (see above).
Unfortunately, the old DST hash matches mod time! => On next comparison FFS will *still* see both sides as different!!!!!!!!!
*/
diff --git a/zen/file_handling.h b/zen/file_handling.h
index d14ed27f..c3ce1d83 100644
--- a/zen/file_handling.h
+++ b/zen/file_handling.h
@@ -32,7 +32,6 @@ void setFileTime(const Zstring& filename, const Int64& modificationTime, ProcSym
UInt64 getFilesize(const Zstring& filename); //throw FileError
UInt64 getFreeDiskSpace(const Zstring& path); //throw FileError
-//file handling
bool removeFile(const Zstring& filename); //throw FileError; return "false" if file is not existing
void removeDirectory(const Zstring& directory, //throw FileError
const std::function<void (const Zstring& filename)>& onBeforeFileDeletion = nullptr, //optional;
@@ -41,7 +40,7 @@ void removeDirectory(const Zstring& directory, //throw FileError
//rename file or directory: no copying!!!
void renameFile(const Zstring& oldName, const Zstring& newName); //throw FileError, ErrorDifferentVolume, ErrorTargetExisting
-bool supportsPermissions(const Zstring& dirname); //throw FileError, derefernces symlinks
+bool supportsPermissions(const Zstring& dirname); //throw FileError, dereferences symlinks
//if parent directory not existing: create recursively:
void makeDirectory(const Zstring& directory, bool failIfExists = false); //throw FileError, ErrorTargetExisting
diff --git a/zen/file_traverser.h b/zen/file_traverser.h
index 2944c5ba..db93a688 100644
--- a/zen/file_traverser.h
+++ b/zen/file_traverser.h
@@ -67,8 +67,8 @@ struct DstHackCallback; //DST hack not required on Unix
#endif
//custom traverser with detail information about files
-//Win: client needs to handle duplicate file notifications! (FilePlusTraverser fallback)
-//directory may end with PATH_SEPARATOR
+//- client needs to handle duplicate file reports! (FilePlusTraverser fallback, retrying to read directory contents, ...)
+//- directory may end with PATH_SEPARATOR
void traverseFolder(const Zstring& dirname, //throw()
TraverseCallback& sink,
DstHackCallback* dstCallback = nullptr); //apply DST hack if callback is supplied
diff --git a/zen/format_unit.cpp b/zen/format_unit.cpp
index 1568b616..bcf318d9 100644
--- a/zen/format_unit.cpp
+++ b/zen/format_unit.cpp
@@ -96,22 +96,22 @@ std::wstring formatUnitTime(int val, UnitRemTime unit)
template <int M, int N>
-std::wstring roundToBlock(double timeHigh,
+std::wstring roundToBlock(double timeInHigh,
UnitRemTime unitHigh, const int (&stepsHigh)[M],
int unitLowPerHigh,
UnitRemTime unitLow, const int (&stepsLow)[N])
{
assert(unitLowPerHigh > 0);
const double granularity = 0.1;
- const double timeLow = timeHigh * unitLowPerHigh;
- const int blockSizeLow = granularity * timeHigh < 1 ?
- numeric::nearMatch(granularity * timeLow, std::begin(stepsLow), std::end(stepsLow)):
- numeric::nearMatch(granularity * timeHigh, std::begin(stepsHigh), std::end(stepsHigh)) * unitLowPerHigh;
- const int roundedTimeLow = numeric::round(timeLow / blockSizeLow) * blockSizeLow;
+ const double timeInLow = timeInHigh * unitLowPerHigh;
+ const int blockSizeLow = granularity * timeInHigh < 1 ?
+ numeric::nearMatch(granularity * timeInLow, std::begin(stepsLow), std::end(stepsLow)):
+ numeric::nearMatch(granularity * timeInHigh, std::begin(stepsHigh), std::end(stepsHigh)) * unitLowPerHigh;
+ const int roundedtimeInLow = numeric::round(timeInLow / blockSizeLow) * blockSizeLow;
- std::wstring output = formatUnitTime(roundedTimeLow / unitLowPerHigh, unitHigh);
+ std::wstring output = formatUnitTime(roundedtimeInLow / unitLowPerHigh, unitHigh);
if (unitLowPerHigh > blockSizeLow)
- output += L" " + formatUnitTime(roundedTimeLow % unitLowPerHigh, unitLow);
+ output += L" " + formatUnitTime(roundedtimeInLow % unitLowPerHigh, unitLow);
return output;
};
}
diff --git a/zen/serialize.h b/zen/serialize.h
index 14d0cdf7..9a14e6af 100644
--- a/zen/serialize.h
+++ b/zen/serialize.h
@@ -4,14 +4,13 @@
// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved *
// **************************************************************************
-#ifndef SERIALIZE_H_INCLUDED
-#define SERIALIZE_H_INCLUDED
+#ifndef SERIALIZE_H_INCLUDED_83940578357
+#define SERIALIZE_H_INCLUDED_83940578357
#include <cstdint>
#include <zen/string_base.h>
#include <zen/file_io.h>
-
namespace zen
{
//high-performance unformatted serialization (avoiding wxMemoryOutputStream/wxMemoryInputStream inefficiencies)
@@ -134,16 +133,6 @@ template < class BinInputStream> void readArray (BinInputStream& stre
-
-
-
-
-
-
-
-
-
-
//-----------------------implementation-------------------------------
template <class BinContainer> inline
void saveBinStream(const Zstring& filename, const BinContainer& cont) //throw FileError
@@ -207,40 +196,43 @@ void writeContainer(BinOutputStream& stream, const C& cont) //don't even conside
template <class BinInputStream> inline
-void readArray(BinInputStream& stream, void* data, size_t len)
+void readArray(BinInputStream& stream, void* data, size_t len) //throw UnexpectedEndOfStreamError
{
- const char* const src = static_cast<const char*>(stream.requestRead(len)); //expect external write of len bytes
+ //expect external write of len bytes:
+ const char* const src = static_cast<const char*>(stream.requestRead(len)); //throw UnexpectedEndOfStreamError
std::copy(src, src + len, static_cast<char*>(data));
}
template <class N, class BinInputStream> inline
-N readNumber(BinInputStream& stream)
+N readNumber(BinInputStream& stream) //throw UnexpectedEndOfStreamError
{
assert_static((IsArithmetic<N>::value || IsSameType<N, bool>::value));
N num = 0;
- readArray(stream, &num, sizeof(N));
+ readArray(stream, &num, sizeof(N)); //throw UnexpectedEndOfStreamError
return num;
}
template <class C, class BinInputStream> inline
-C readContainer(BinInputStream& stream)
+C readContainer(BinInputStream& stream) //throw UnexpectedEndOfStreamError
{
C cont;
auto strLength = readNumber<std::uint32_t>(stream);
- if (strLength > 0)
+ if (strLength > 0)
+ {
try
{
cont.resize(strLength); //throw std::bad_alloc
- readArray(stream, &*cont.begin(), sizeof(typename C::value_type) * strLength);
}
catch (std::bad_alloc&) //most likely this is due to data corruption!
{
throw UnexpectedEndOfStreamError();
}
+ readArray(stream, &*cont.begin(), sizeof(typename C::value_type) * strLength); //throw UnexpectedEndOfStreamError
+ }
return cont;
}
}
-#endif //SERIALIZE_H_INCLUDED
+#endif //SERIALIZE_H_INCLUDED_83940578357
diff --git a/zen/string_base.h b/zen/string_base.h
index 2d16e669..a458ef15 100644
--- a/zen/string_base.h
+++ b/zen/string_base.h
@@ -196,11 +196,11 @@ public:
Zbase(const Char* source); //implicit conversion from a C-string
Zbase(const Char* source, size_t length);
Zbase(const Zbase& source);
- Zbase(Zbase&& tmp);
+ Zbase(Zbase&& tmp); //make noexcept in C++11
explicit Zbase(Char source); //dangerous if implicit: Char buffer[]; return buffer[0]; ups... forgot &, but not a compiler error!
//allow explicit construction from different string type, prevent ambiguity via SFINAE
template <class S> explicit Zbase(const S& other, typename S::value_type = 0);
- ~Zbase();
+ ~Zbase(); //make noexcept in C++11
//operator const Char* () const; //NO implicit conversion to a C-string!! Many problems... one of them: if we forget to provide operator overloads, it'll just work with a Char*...
@@ -241,7 +241,7 @@ public:
void push_back(Char val) { operator+=(val); } //STL access
Zbase& operator=(const Zbase& source);
- Zbase& operator=(Zbase&& tmp);
+ Zbase& operator=(Zbase&& tmp); //make noexcept in C++11
Zbase& operator=(const Char* source);
Zbase& operator=(Char source);
Zbase& operator+=(const Zbase& other);
diff --git a/zen/string_traits.h b/zen/string_traits.h
index f192e045..69c1fbc8 100644
--- a/zen/string_traits.h
+++ b/zen/string_traits.h
@@ -81,6 +81,7 @@ public:
template <class S, bool isStringClass> struct GetCharTypeImpl : ResultType<NullType> {};
+
template <class S>
struct GetCharTypeImpl<S, true> :
ResultType<
diff --git a/zen/tick_count.h b/zen/tick_count.h
index 893d8e80..cb15fe20 100644
--- a/zen/tick_count.h
+++ b/zen/tick_count.h
@@ -10,6 +10,7 @@
#include <cstdint>
#include "type_traits.h"
#include "basic_math.h"
+
#ifdef ZEN_WIN
#include "win.h" //includes "windows.h"
@@ -19,31 +20,20 @@
#elif defined ZEN_MAC
#include <mach/mach_time.h>
#endif
-//#include <algorithm>
-//#include "assert_static.h"
-//#include <cmath>
//template <class T> inline
//T dist(T a, T b)
//{
// return a > b ? a - b : b - a;
//}
-
-
namespace zen
{
//a portable "GetTickCount()" using "wall time equivalent" - e.g. no jumps due to ntp time corrections
class TickVal;
-std::int64_t dist(const TickVal& lhs, const TickVal& rhs); //use absolute difference for paranoid security: even QueryPerformanceCounter "wraps-around" at *some* time
-
-std::int64_t ticksPerSec(); //return 0 on error
-TickVal getTicks(); //return invalid value on error: !TickVal::isValid()
-
-
-
-
-
+int64_t dist(const TickVal& lhs, const TickVal& rhs); //use absolute difference for paranoid security: even QueryPerformanceCounter "wraps-around" at *some* time
+int64_t ticksPerSec(); //return 0 on error
+TickVal getTicks(); //return invalid value on error: !TickVal::isValid()
@@ -69,17 +59,17 @@ public:
explicit TickVal(const NativeVal& val) : val_(val) {}
inline friend
- std::int64_t dist(const TickVal& lhs, const TickVal& rhs)
+ int64_t dist(const TickVal& lhs, const TickVal& rhs)
{
#ifdef ZEN_WIN
return numeric::dist(lhs.val_.QuadPart, rhs.val_.QuadPart); //std::abs(a - b) can lead to overflow!
#elif defined ZEN_LINUX
- const auto distSec = numeric::dist(lhs.val_.tv_sec, rhs.val_.tv_sec);
- const auto distNsec = numeric::dist(lhs.val_.tv_nsec, rhs.val_.tv_nsec);
-
- if (distSec > (std::numeric_limits<std::int64_t>::max() - distNsec) / 1000000000) //truncate instead of overflow!
- return std::numeric_limits<std::int64_t>::max();
- return distSec * 1000000000 + distNsec;
+//structure timespec documented with members:
+// time_t tv_sec seconds
+// long tv_nsec nanoseconds
+ const int64_t deltaSec = lhs.val_.tv_sec - rhs.val_.tv_sec;
+ const int64_t deltaNsec = lhs.val_.tv_nsec - rhs.val_.tv_nsec;
+ return numeric::abs(deltaSec * 1000000000 + deltaNsec);
#elif defined ZEN_MAC
return numeric::dist(lhs.val_, rhs.val_);
#endif
@@ -107,13 +97,13 @@ private:
inline
-std::int64_t ticksPerSec() //return 0 on error
+int64_t ticksPerSec() //return 0 on error
{
#ifdef ZEN_WIN
LARGE_INTEGER frequency = {};
if (!::QueryPerformanceFrequency(&frequency)) //MSDN promises: "The frequency cannot change while the system is running."
return 0;
- static_assert(sizeof(std::int64_t) >= sizeof(frequency.QuadPart), "");
+ static_assert(sizeof(int64_t) >= sizeof(frequency.QuadPart), "");
return frequency.QuadPart;
#elif defined ZEN_LINUX
@@ -123,7 +113,10 @@ std::int64_t ticksPerSec() //return 0 on error
mach_timebase_info_data_t tbi = {};
if (::mach_timebase_info(&tbi) != KERN_SUCCESS)
return 0;
- return 1000000000 * tbi.denom / tbi.numer;
+//structure mach_timebase_info_data_t documented with members:
+// uint32_t numer;
+// uint32_t denom;
+ return static_cast<int64_t>(1000000000) * tbi.denom / tbi.numer;
#endif
}
diff --git a/zen/type_traits.h b/zen/type_traits.h
index f69c155a..1c2da5eb 100644
--- a/zen/type_traits.h
+++ b/zen/type_traits.h
@@ -36,6 +36,13 @@ struct ResultType
typedef T Type;
};
+//Herb Sutter's signedness conversion helpers: http://herbsutter.com/2013/06/13/gotw-93-solution-auto-variables-part-2/
+template<class T> inline
+typename std::make_signed<T>::type makeSigned(T t) { return std::make_signed<T>::type(t); }
+
+template<class T> inline
+typename std::make_unsigned<T>::type makeUnsigned(T t) { return std::make_unsigned<T>::type(t); }
+
//################# Built-in Types ########################
//Example: "IsSignedInt<int>::value" evaluates to "true"
diff --git a/zen/utf.h b/zen/utf.h
index a50466f2..281185d3 100644
--- a/zen/utf.h
+++ b/zen/utf.h
@@ -247,7 +247,6 @@ size_t unicodeLength(const CharString& str, char) //utf8
while (strFirst < strLast) //[!]
{
++len;
-
size_t utf8len = getUtf8Len(*strFirst);
if (utf8len == 0) ++utf8len; //invalid utf8 character
strFirst += utf8len;
@@ -311,13 +310,15 @@ size_t findUnicodePos(const CharString& str, size_t unicodePos, char) //utf8-cha
size_t utfPos = 0;
while (unicodePos-- > 0)
{
+ if (utfPos >= strLen)
+ return strLen;
+
size_t utf8len = getUtf8Len(strFirst[utfPos]);
if (utf8len == 0) ++utf8len; //invalid utf8 character
utfPos += utf8len;
-
- if (utfPos >= strLen)
- return strLen;
}
+ if (utfPos >= strLen)
+ return strLen;
return utfPos;
}
@@ -333,13 +334,15 @@ size_t findUnicodePosWide(const WideString& str, size_t unicodePos, Int2Type<2>)
size_t utfPos = 0;
while (unicodePos-- > 0)
{
- size_t utf16len = getUtf16Len(strFirst[utfPos]);
- if (utf16len == 0) ++utf16len; //invalid utf16 character
- utfPos += utf16len;
-
if (utfPos >= strLen)
return strLen;
+
+ size_t utf16len = getUtf16Len(strFirst[utfPos]);
+ if (utf16len == 0) ++utf16len; //invalid utf16 character
+ utfPos += utf16len;
}
+ if (utfPos >= strLen)
+ return strLen;
return utfPos;
}
bgstack15