Petr Onderka has submitted this change and it was merged.
Change subject: Handle progress reporting even when tellg() doesn't work
......................................................................
Handle progress reporting even when tellg() doesn't work
Change-Id: Ib57e9694a3656a161cf33f3b730981668fb462da
---
M Dump.cpp
M DumpException.cpp
M DumpException.h
M Objects/IpV4User.cpp
M StringHelpers.cpp
M XmlInput/WrapperInputStream.h
M main.cpp
7 files changed, 69 insertions(+), 30 deletions(-)
Approvals:
Petr Onderka: Verified; Looks good to me, approved
diff --git a/Dump.cpp b/Dump.cpp
index 46d2d31..7afad41 100644
--- a/Dump.cpp
+++ b/Dump.cpp
@@ -34,6 +34,7 @@
if (!stream->is_open())
{
+ errno = 0;
// this feels dangerous, isn't there a better way?
stream = new fstream(fileName, ios::in | ios::out | ios::binary |
ios::trunc);
}
@@ -193,4 +194,4 @@
return std::make_pair(WikitextModel, WikitextFormat);
return modelFormatIndex->Get(id);
-}
\ No newline at end of file
+}
diff --git a/DumpException.cpp b/DumpException.cpp
index 761cc94..f2dfec7 100644
--- a/DumpException.cpp
+++ b/DumpException.cpp
@@ -1,14 +1,22 @@
#include "DumpException.h"
-UserException::UserException(const std::string &message)
+CustomException::CustomException(const std::string& message)
: message(message)
{}
-const char* UserException::what() const NOEXCEPT
+const char* CustomException::what() const NOEXCEPT
{
return message.c_str();
}
-ParametersException::ParametersException(const std::string &message)
+DumpException::DumpException(const std::string& message)
+ : CustomException(message)
+{}
+
+UserException::UserException(const std::string& message)
+ : CustomException(message)
+{}
+
+ParametersException::ParametersException(const std::string& message)
: UserException(message)
{}
diff --git a/DumpException.h b/DumpException.h
index 3c11e6c..b22ef21 100644
--- a/DumpException.h
+++ b/DumpException.h
@@ -4,23 +4,32 @@
#include <string>
#include "common.h"
-class DumpException : public std::exception
-{};
-
-// exception that was most likely caused by user error
-// and should be shown directly to the user
-class UserException : public std::exception
+class CustomException : public std::exception
{
private:
const std::string message;
public:
- UserException(const std::string &message);
+ CustomException(const std::string& message);
virtual const char* what() const NOEXCEPT OVERRIDE;
// GCC 4.6 seems to require this
- virtual ~UserException() NOEXCEPT
+ virtual ~CustomException() NOEXCEPT
{}
+};
+
+class DumpException : public CustomException
+{
+public:
+ DumpException(const std::string& message = std::string());
+};
+
+// exception that was most likely caused by user error
+// and should be shown directly to the user
+class UserException : public CustomException
+{
+public:
+ UserException(const std::string& message);
};
// user exception that was caused by invalid parameters,
@@ -28,5 +37,5 @@
class ParametersException : public UserException
{
public:
- ParametersException(const std::string &message);
+ ParametersException(const std::string& message);
};
diff --git a/Objects/IpV4User.cpp b/Objects/IpV4User.cpp
index 54201ec..a426aae 100644
--- a/Objects/IpV4User.cpp
+++ b/Objects/IpV4User.cpp
@@ -19,9 +19,10 @@
for (int i = 0; i < 4; i++)
{
- bool success;
- long intPart = tryParseLong(stringParts.at(i), success);
- if (!success || intPart > 255 || intPart < 0)
+ bool parseSuccess;
+ long intPart = tryParseLong(stringParts.at(i), parseSuccess);
+
+ if (!parseSuccess || intPart > 255 || intPart < 0)
return 0;
result |= (uint32_t)(uint8_t)intPart << (8 * i);
@@ -82,4 +83,4 @@
RevisionFlags IpV4User::UserKind() const
{
return RevisionFlags::IpV4User;
-}
\ No newline at end of file
+}
diff --git a/StringHelpers.cpp b/StringHelpers.cpp
index 3995c38..5e1cbe0 100644
--- a/StringHelpers.cpp
+++ b/StringHelpers.cpp
@@ -1,4 +1,6 @@
#include "StringHelpers.h"
+#include "DumpException.h"
+#include "format.h"
#include <sstream>
// http://stackoverflow.com/a/236803/41071
@@ -20,6 +22,12 @@
long tryParseLong(const std::string &s, bool &success, int radix)
{
+ if (errno != 0)
+ {
+ throw DumpException(
+ str(fmt::Format("errno was already set ({0}: {1})") << errno <<
strerror(errno)));
+ }
+
char* end;
const char* start = s.c_str();
long result = strtol(start, &end, radix);
@@ -31,7 +39,8 @@
}
else
{
+ errno = 0;
success = false;
return 0;
}
-}
\ No newline at end of file
+}
diff --git a/XmlInput/WrapperInputStream.h b/XmlInput/WrapperInputStream.h
index 2cecc3e..ea11593 100644
--- a/XmlInput/WrapperInputStream.h
+++ b/XmlInput/WrapperInputStream.h
@@ -6,18 +6,24 @@
{
private:
std::istream &wrapped;
- std::function<void()> sideAction;
+ std::function<void(int)> sideAction;
public:
- WrapperInputStream(std::istream &wrapped, std::function<void()> sideAction
= nullptr)
+ WrapperInputStream(std::istream &wrapped, std::function<void()> sideAction)
+ : wrapped(wrapped), sideAction([=](int){ sideAction(); })
+ {}
+
+ WrapperInputStream(std::istream &wrapped, std::function<void(int)>
sideAction = nullptr)
: wrapped(wrapped), sideAction(sideAction)
{}
virtual int read(XML_Char *buf, size_t bufLen) OVERRIDE
{
- if (sideAction != nullptr)
- sideAction();
-
wrapped.read(buf, bufLen);
- return wrapped.gcount();
+ auto count = wrapped.gcount();
+
+ if (sideAction != nullptr)
+ sideAction(count);
+
+ return count;
}
};
\ No newline at end of file
diff --git a/main.cpp b/main.cpp
index affbd95..62cb24e 100644
--- a/main.cpp
+++ b/main.cpp
@@ -149,10 +149,13 @@
void createDumpCore(ProgressWriterWrapper& writer, std::istream& inputStream)
{
std::uint64_t i = 0;
- std::function<void ()> offsetReportingFunction = [&]()
+ std::uint64_t totalRead = 0;
+ std::function<void(int)> offsetReportingFunction = [&](int read)
{
+ totalRead += read;
+
if (i % 100 == 0)
- writer.ReportOffset(inputStream.tellg());
+ writer.ReportOffset(totalRead);
i++;
};
@@ -185,11 +188,13 @@
if (inputFileName == "-")
{
+ std::cin.exceptions(std::ios::failbit | std::ios::badbit);
createDumpCore(progressWriter, std::cin);
}
else
{
std::ifstream stream(inputFileName, std::ios::binary);
+ stream.exceptions(std::ios::failbit | std::ios::badbit);
createDumpCore(progressWriter, stream);
}
}
@@ -223,8 +228,7 @@
dumpBackupProcess.set_buffer_limit(exec_stream_t::s_out, 8192);
dumpBackupProcess.start(phpPath, dumpBackupParameters + " --full --stub");
- WrapperInputStream dumpBackupStream(dumpBackupProcess.out(),
- [&]()
+ std::function<void()> progressForwardingFunction = [&]()
{
auto &stream = dumpBackupProcess.err();
char buffer[1024];
@@ -234,7 +238,8 @@
count = stream.readsome(buffer, 1024);
std::cerr.write(buffer, count);
} while (count != 0);
- });
+ };
+ WrapperInputStream dumpBackupStream(dumpBackupProcess.out(),
progressForwardingFunction);
XmlMediawikiProcessor::Process(&writer, dumpBackupStream);
@@ -317,4 +322,4 @@
{
std::cerr << "Error: " << ex.what() << "\n";
}
-}
\ No newline at end of file
+}
--
To view, visit https://gerrit.wikimedia.org/r/84748
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Ib57e9694a3656a161cf33f3b730981668fb462da
Gerrit-PatchSet: 2
Gerrit-Project: operations/dumps/incremental
Gerrit-Branch: gsoc
Gerrit-Owner: Petr Onderka <[email protected]>
Gerrit-Reviewer: Petr Onderka <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits