forked from lix-project/lix
Sink: Use std::string_view
This commit is contained in:
parent
aa68486112
commit
faa31f4084
|
@ -86,8 +86,7 @@ void BinaryCacheStore::getFile(const std::string & path, Sink & sink)
|
||||||
promise.set_exception(std::current_exception());
|
promise.set_exception(std::current_exception());
|
||||||
}
|
}
|
||||||
}});
|
}});
|
||||||
auto data = promise.get_future().get();
|
sink(*promise.get_future().get());
|
||||||
sink((unsigned char *) data->data(), data->size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<std::string> BinaryCacheStore::getFile(const std::string & path)
|
std::shared_ptr<std::string> BinaryCacheStore::getFile(const std::string & path)
|
||||||
|
|
|
@ -916,10 +916,8 @@ void DerivationGoal::buildDone()
|
||||||
|
|
||||||
LogSink(Activity & act) : act(act) { }
|
LogSink(Activity & act) : act(act) { }
|
||||||
|
|
||||||
void operator() (const unsigned char * data, size_t len) override {
|
void operator() (std::string_view data) override {
|
||||||
for (size_t i = 0; i < len; i++) {
|
for (auto c : data) {
|
||||||
auto c = data[i];
|
|
||||||
|
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
flushLine();
|
flushLine();
|
||||||
} else {
|
} else {
|
||||||
|
@ -3127,7 +3125,7 @@ void DerivationGoal::registerOutputs()
|
||||||
StringSink sink;
|
StringSink sink;
|
||||||
dumpPath(actualPath, sink);
|
dumpPath(actualPath, sink);
|
||||||
RewritingSink rsink2(oldHashPart, std::string(newInfo0.path.hashPart()), nextSink);
|
RewritingSink rsink2(oldHashPart, std::string(newInfo0.path.hashPart()), nextSink);
|
||||||
rsink2((unsigned char *) sink.s->data(), sink.s->size());
|
rsink2(*sink.s);
|
||||||
rsink2.flush();
|
rsink2.flush();
|
||||||
});
|
});
|
||||||
Path tmpPath = actualPath + ".tmp";
|
Path tmpPath = actualPath + ".tmp";
|
||||||
|
|
|
@ -153,10 +153,10 @@ struct TunnelSink : Sink
|
||||||
{
|
{
|
||||||
Sink & to;
|
Sink & to;
|
||||||
TunnelSink(Sink & to) : to(to) { }
|
TunnelSink(Sink & to) : to(to) { }
|
||||||
virtual void operator () (const unsigned char * data, size_t len)
|
void operator () (std::string_view data)
|
||||||
{
|
{
|
||||||
to << STDERR_WRITE;
|
to << STDERR_WRITE;
|
||||||
writeString(data, len, to);
|
writeString(data, to);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -95,18 +95,18 @@ struct curlFileTransfer : public FileTransfer
|
||||||
fmt(request.data ? "uploading '%s'" : "downloading '%s'", request.uri),
|
fmt(request.data ? "uploading '%s'" : "downloading '%s'", request.uri),
|
||||||
{request.uri}, request.parentAct)
|
{request.uri}, request.parentAct)
|
||||||
, callback(std::move(callback))
|
, callback(std::move(callback))
|
||||||
, finalSink([this](const unsigned char * data, size_t len) {
|
, finalSink([this](std::string_view data) {
|
||||||
if (this->request.dataCallback) {
|
if (this->request.dataCallback) {
|
||||||
auto httpStatus = getHTTPStatus();
|
auto httpStatus = getHTTPStatus();
|
||||||
|
|
||||||
/* Only write data to the sink if this is a
|
/* Only write data to the sink if this is a
|
||||||
successful response. */
|
successful response. */
|
||||||
if (successfulStatuses.count(httpStatus)) {
|
if (successfulStatuses.count(httpStatus)) {
|
||||||
writtenToSink += len;
|
writtenToSink += data.size();
|
||||||
this->request.dataCallback((char *) data, len);
|
this->request.dataCallback(data);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
this->result.data->append((char *) data, len);
|
this->result.data->append(data);
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
if (!request.expectedETag.empty())
|
if (!request.expectedETag.empty())
|
||||||
|
@ -171,8 +171,8 @@ struct curlFileTransfer : public FileTransfer
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errorSink)
|
if (errorSink)
|
||||||
(*errorSink)((unsigned char *) contents, realSize);
|
(*errorSink)({(char *) contents, realSize});
|
||||||
(*decompressionSink)((unsigned char *) contents, realSize);
|
(*decompressionSink)({(char *) contents, realSize});
|
||||||
|
|
||||||
return realSize;
|
return realSize;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
@ -776,7 +776,7 @@ void FileTransfer::download(FileTransferRequest && request, Sink & sink)
|
||||||
state->request.notify_one();
|
state->request.notify_one();
|
||||||
});
|
});
|
||||||
|
|
||||||
request.dataCallback = [_state](char * buf, size_t len) {
|
request.dataCallback = [_state](std::string_view data) {
|
||||||
|
|
||||||
auto state(_state->lock());
|
auto state(_state->lock());
|
||||||
|
|
||||||
|
@ -794,7 +794,7 @@ void FileTransfer::download(FileTransferRequest && request, Sink & sink)
|
||||||
|
|
||||||
/* Append data to the buffer and wake up the calling
|
/* Append data to the buffer and wake up the calling
|
||||||
thread. */
|
thread. */
|
||||||
state->data.append(buf, len);
|
state->data.append(data);
|
||||||
state->avail.notify_one();
|
state->avail.notify_one();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -840,7 +840,7 @@ void FileTransfer::download(FileTransferRequest && request, Sink & sink)
|
||||||
if it's blocked on a full buffer. We don't hold the state
|
if it's blocked on a full buffer. We don't hold the state
|
||||||
lock while doing this to prevent blocking the download
|
lock while doing this to prevent blocking the download
|
||||||
thread if sink() takes a long time. */
|
thread if sink() takes a long time. */
|
||||||
sink((unsigned char *) chunk.data(), chunk.size());
|
sink(chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ struct FileTransferRequest
|
||||||
bool decompress = true;
|
bool decompress = true;
|
||||||
std::shared_ptr<std::string> data;
|
std::shared_ptr<std::string> data;
|
||||||
std::string mimeType;
|
std::string mimeType;
|
||||||
std::function<void(char *, size_t)> dataCallback;
|
std::function<void(std::string_view data)> dataCallback;
|
||||||
|
|
||||||
FileTransferRequest(const std::string & uri)
|
FileTransferRequest(const std::string & uri)
|
||||||
: uri(uri), parentAct(getCurActivity()) { }
|
: uri(uri), parentAct(getCurActivity()) { }
|
||||||
|
|
|
@ -87,7 +87,7 @@ struct NarAccessor : public FSAccessor
|
||||||
parents.top()->start = pos;
|
parents.top()->start = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void receiveContents(unsigned char * data, size_t len) override
|
void receiveContents(std::string_view data) override
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void createSymlink(const Path & path, const string & target) override
|
void createSymlink(const Path & path, const string & target) override
|
||||||
|
|
|
@ -55,25 +55,21 @@ struct RefScanSink : Sink
|
||||||
|
|
||||||
RefScanSink() { }
|
RefScanSink() { }
|
||||||
|
|
||||||
void operator () (const unsigned char * data, size_t len);
|
void operator () (std::string_view data) override
|
||||||
};
|
{
|
||||||
|
|
||||||
|
|
||||||
void RefScanSink::operator () (const unsigned char * data, size_t len)
|
|
||||||
{
|
|
||||||
/* It's possible that a reference spans the previous and current
|
/* It's possible that a reference spans the previous and current
|
||||||
fragment, so search in the concatenation of the tail of the
|
fragment, so search in the concatenation of the tail of the
|
||||||
previous fragment and the start of the current fragment. */
|
previous fragment and the start of the current fragment. */
|
||||||
string s = tail + string((const char *) data, len > refLength ? refLength : len);
|
string s = tail + std::string(data, 0, refLength);
|
||||||
search((const unsigned char *) s.data(), s.size(), hashes, seen);
|
search((const unsigned char *) s.data(), s.size(), hashes, seen);
|
||||||
|
|
||||||
search(data, len, hashes, seen);
|
search((const unsigned char *) data.data(), data.size(), hashes, seen);
|
||||||
|
|
||||||
size_t tailLen = len <= refLength ? len : refLength;
|
size_t tailLen = data.size() <= refLength ? data.size() : refLength;
|
||||||
tail =
|
tail = std::string(tail, tail.size() < refLength - tailLen ? 0 : tail.size() - (refLength - tailLen));
|
||||||
string(tail, tail.size() < refLength - tailLen ? 0 : tail.size() - (refLength - tailLen)) +
|
tail.append({data.data() + data.size() - tailLen, tailLen});
|
||||||
string((const char *) data + len - tailLen, tailLen);
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
std::pair<PathSet, HashResult> scanForReferences(const string & path,
|
std::pair<PathSet, HashResult> scanForReferences(const string & path,
|
||||||
|
@ -129,10 +125,10 @@ RewritingSink::RewritingSink(const std::string & from, const std::string & to, S
|
||||||
assert(from.size() == to.size());
|
assert(from.size() == to.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RewritingSink::operator () (const unsigned char * data, size_t len)
|
void RewritingSink::operator () (std::string_view data)
|
||||||
{
|
{
|
||||||
std::string s(prev);
|
std::string s(prev);
|
||||||
s.append((const char *) data, len);
|
s.append(data);
|
||||||
|
|
||||||
size_t j = 0;
|
size_t j = 0;
|
||||||
while ((j = s.find(from, j)) != string::npos) {
|
while ((j = s.find(from, j)) != string::npos) {
|
||||||
|
@ -146,14 +142,14 @@ void RewritingSink::operator () (const unsigned char * data, size_t len)
|
||||||
|
|
||||||
pos += consumed;
|
pos += consumed;
|
||||||
|
|
||||||
if (consumed) nextSink((unsigned char *) s.data(), consumed);
|
if (consumed) nextSink(s.substr(0, consumed));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RewritingSink::flush()
|
void RewritingSink::flush()
|
||||||
{
|
{
|
||||||
if (prev.empty()) return;
|
if (prev.empty()) return;
|
||||||
pos += prev.size();
|
pos += prev.size();
|
||||||
nextSink((unsigned char *) prev.data(), prev.size());
|
nextSink(prev);
|
||||||
prev.clear();
|
prev.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,9 +159,9 @@ HashModuloSink::HashModuloSink(HashType ht, const std::string & modulus)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void HashModuloSink::operator () (const unsigned char * data, size_t len)
|
void HashModuloSink::operator () (std::string_view data)
|
||||||
{
|
{
|
||||||
rewritingSink(data, len);
|
rewritingSink(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
HashResult HashModuloSink::finish()
|
HashResult HashModuloSink::finish()
|
||||||
|
@ -176,10 +172,8 @@ HashResult HashModuloSink::finish()
|
||||||
NAR with self-references and a NAR with some of the
|
NAR with self-references and a NAR with some of the
|
||||||
self-references already zeroed out do not produce a hash
|
self-references already zeroed out do not produce a hash
|
||||||
collision. FIXME: proof. */
|
collision. FIXME: proof. */
|
||||||
for (auto & pos : rewritingSink.matches) {
|
for (auto & pos : rewritingSink.matches)
|
||||||
auto s = fmt("|%d", pos);
|
hashSink(fmt("|%d", pos));
|
||||||
hashSink((unsigned char *) s.data(), s.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
auto h = hashSink.finish();
|
auto h = hashSink.finish();
|
||||||
return {h.first, rewritingSink.pos};
|
return {h.first, rewritingSink.pos};
|
||||||
|
|
|
@ -19,7 +19,7 @@ struct RewritingSink : Sink
|
||||||
|
|
||||||
RewritingSink(const std::string & from, const std::string & to, Sink & nextSink);
|
RewritingSink(const std::string & from, const std::string & to, Sink & nextSink);
|
||||||
|
|
||||||
void operator () (const unsigned char * data, size_t len) override;
|
void operator () (std::string_view data) override;
|
||||||
|
|
||||||
void flush();
|
void flush();
|
||||||
};
|
};
|
||||||
|
@ -31,7 +31,7 @@ struct HashModuloSink : AbstractHashSink
|
||||||
|
|
||||||
HashModuloSink(HashType ht, const std::string & modulus);
|
HashModuloSink(HashType ht, const std::string & modulus);
|
||||||
|
|
||||||
void operator () (const unsigned char * data, size_t len) override;
|
void operator () (std::string_view data) override;
|
||||||
|
|
||||||
HashResult finish() override;
|
HashResult finish() override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -857,7 +857,7 @@ std::exception_ptr RemoteStore::Connection::processStderr(Sink * sink, Source *
|
||||||
if (!source) throw Error("no source");
|
if (!source) throw Error("no source");
|
||||||
size_t len = readNum<size_t>(from);
|
size_t len = readNum<size_t>(from);
|
||||||
auto buf = std::make_unique<unsigned char[]>(len);
|
auto buf = std::make_unique<unsigned char[]>(len);
|
||||||
writeString(buf.get(), source->read(buf.get(), len), to);
|
writeString({(const char *) buf.get(), source->read(buf.get(), len)}, to);
|
||||||
to.flush();
|
to.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -398,7 +398,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore, virtual S3BinaryCache
|
||||||
printTalkative("downloaded 's3://%s/%s' (%d bytes) in %d ms",
|
printTalkative("downloaded 's3://%s/%s' (%d bytes) in %d ms",
|
||||||
bucketName, path, res.data->size(), res.durationMs);
|
bucketName, path, res.data->size(), res.durationMs);
|
||||||
|
|
||||||
sink((unsigned char *) res.data->data(), res.data->size());
|
sink(*res.data);
|
||||||
} else
|
} else
|
||||||
throw NoSuchBinaryCacheFile("file '%s' does not exist in binary cache '%s'", path, getUri());
|
throw NoSuchBinaryCacheFile("file '%s' does not exist in binary cache '%s'", path, getUri());
|
||||||
}
|
}
|
||||||
|
|
|
@ -772,8 +772,8 @@ void copyStorePath(ref<Store> srcStore, ref<Store> dstStore,
|
||||||
}
|
}
|
||||||
|
|
||||||
auto source = sinkToSource([&](Sink & sink) {
|
auto source = sinkToSource([&](Sink & sink) {
|
||||||
LambdaSink progressSink([&](const unsigned char * data, size_t len) {
|
LambdaSink progressSink([&](std::string_view data) {
|
||||||
total += len;
|
total += data.size();
|
||||||
act.progress(total, info->narSize);
|
act.progress(total, info->narSize);
|
||||||
});
|
});
|
||||||
TeeSink tee { sink, progressSink };
|
TeeSink tee { sink, progressSink };
|
||||||
|
|
|
@ -57,7 +57,7 @@ static void dumpContents(const Path & path, size_t size,
|
||||||
auto n = std::min(left, buf.size());
|
auto n = std::min(left, buf.size());
|
||||||
readFull(fd.get(), buf.data(), n);
|
readFull(fd.get(), buf.data(), n);
|
||||||
left -= n;
|
left -= n;
|
||||||
sink(buf.data(), n);
|
sink({(char *) buf.data(), n});
|
||||||
}
|
}
|
||||||
|
|
||||||
writePadding(size, sink);
|
writePadding(size, sink);
|
||||||
|
@ -162,7 +162,7 @@ static void parseContents(ParseSink & sink, Source & source, const Path & path)
|
||||||
auto n = buf.size();
|
auto n = buf.size();
|
||||||
if ((uint64_t)n > left) n = left;
|
if ((uint64_t)n > left) n = left;
|
||||||
source(buf.data(), n);
|
source(buf.data(), n);
|
||||||
sink.receiveContents(buf.data(), n);
|
sink.receiveContents({(char *) buf.data(), n});
|
||||||
left -= n;
|
left -= n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,21 +300,21 @@ struct RestoreSink : ParseSink
|
||||||
Path dstPath;
|
Path dstPath;
|
||||||
AutoCloseFD fd;
|
AutoCloseFD fd;
|
||||||
|
|
||||||
void createDirectory(const Path & path)
|
void createDirectory(const Path & path) override
|
||||||
{
|
{
|
||||||
Path p = dstPath + path;
|
Path p = dstPath + path;
|
||||||
if (mkdir(p.c_str(), 0777) == -1)
|
if (mkdir(p.c_str(), 0777) == -1)
|
||||||
throw SysError("creating directory '%1%'", p);
|
throw SysError("creating directory '%1%'", p);
|
||||||
};
|
};
|
||||||
|
|
||||||
void createRegularFile(const Path & path)
|
void createRegularFile(const Path & path) override
|
||||||
{
|
{
|
||||||
Path p = dstPath + path;
|
Path p = dstPath + path;
|
||||||
fd = open(p.c_str(), O_CREAT | O_EXCL | O_WRONLY | O_CLOEXEC, 0666);
|
fd = open(p.c_str(), O_CREAT | O_EXCL | O_WRONLY | O_CLOEXEC, 0666);
|
||||||
if (!fd) throw SysError("creating file '%1%'", p);
|
if (!fd) throw SysError("creating file '%1%'", p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void isExecutable()
|
void isExecutable() override
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (fstat(fd.get(), &st) == -1)
|
if (fstat(fd.get(), &st) == -1)
|
||||||
|
@ -323,7 +323,7 @@ struct RestoreSink : ParseSink
|
||||||
throw SysError("fchmod");
|
throw SysError("fchmod");
|
||||||
}
|
}
|
||||||
|
|
||||||
void preallocateContents(uint64_t len)
|
void preallocateContents(uint64_t len) override
|
||||||
{
|
{
|
||||||
if (!archiveSettings.preallocateContents)
|
if (!archiveSettings.preallocateContents)
|
||||||
return;
|
return;
|
||||||
|
@ -341,12 +341,12 @@ struct RestoreSink : ParseSink
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void receiveContents(unsigned char * data, size_t len)
|
void receiveContents(std::string_view data) override
|
||||||
{
|
{
|
||||||
writeFull(fd.get(), data, len);
|
writeFull(fd.get(), data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void createSymlink(const Path & path, const string & target)
|
void createSymlink(const Path & path, const string & target) override
|
||||||
{
|
{
|
||||||
Path p = dstPath + path;
|
Path p = dstPath + path;
|
||||||
nix::createSymlink(target, p);
|
nix::createSymlink(target, p);
|
||||||
|
|
|
@ -58,7 +58,7 @@ struct ParseSink
|
||||||
virtual void createRegularFile(const Path & path) { };
|
virtual void createRegularFile(const Path & path) { };
|
||||||
virtual void isExecutable() { };
|
virtual void isExecutable() { };
|
||||||
virtual void preallocateContents(uint64_t size) { };
|
virtual void preallocateContents(uint64_t size) { };
|
||||||
virtual void receiveContents(unsigned char * data, size_t len) { };
|
virtual void receiveContents(std::string_view data) { };
|
||||||
|
|
||||||
virtual void createSymlink(const Path & path, const string & target) { };
|
virtual void createSymlink(const Path & path, const string & target) { };
|
||||||
};
|
};
|
||||||
|
@ -72,14 +72,14 @@ struct RetrieveRegularNARSink : ParseSink
|
||||||
|
|
||||||
RetrieveRegularNARSink(Sink & sink) : sink(sink) { }
|
RetrieveRegularNARSink(Sink & sink) : sink(sink) { }
|
||||||
|
|
||||||
void createDirectory(const Path & path)
|
void createDirectory(const Path & path) override
|
||||||
{
|
{
|
||||||
regular = false;
|
regular = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void receiveContents(unsigned char * data, size_t len)
|
void receiveContents(std::string_view data) override
|
||||||
{
|
{
|
||||||
sink(data, len);
|
sink(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void createSymlink(const Path & path, const string & target)
|
void createSymlink(const Path & path, const string & target)
|
||||||
|
|
|
@ -22,18 +22,17 @@ struct ChunkedCompressionSink : CompressionSink
|
||||||
{
|
{
|
||||||
uint8_t outbuf[32 * 1024];
|
uint8_t outbuf[32 * 1024];
|
||||||
|
|
||||||
void write(const unsigned char * data, size_t len) override
|
void write(std::string_view data) override
|
||||||
{
|
{
|
||||||
const size_t CHUNK_SIZE = sizeof(outbuf) << 2;
|
const size_t CHUNK_SIZE = sizeof(outbuf) << 2;
|
||||||
while (len) {
|
while (!data.empty()) {
|
||||||
size_t n = std::min(CHUNK_SIZE, len);
|
size_t n = std::min(CHUNK_SIZE, data.size());
|
||||||
writeInternal(data, n);
|
writeInternal(data);
|
||||||
data += n;
|
data.remove_prefix(n);
|
||||||
len -= n;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void writeInternal(const unsigned char * data, size_t len) = 0;
|
virtual void writeInternal(std::string_view data) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NoneSink : CompressionSink
|
struct NoneSink : CompressionSink
|
||||||
|
@ -41,7 +40,7 @@ struct NoneSink : CompressionSink
|
||||||
Sink & nextSink;
|
Sink & nextSink;
|
||||||
NoneSink(Sink & nextSink) : nextSink(nextSink) { }
|
NoneSink(Sink & nextSink) : nextSink(nextSink) { }
|
||||||
void finish() override { flush(); }
|
void finish() override { flush(); }
|
||||||
void write(const unsigned char * data, size_t len) override { nextSink(data, len); }
|
void write(std::string_view data) override { nextSink(data); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GzipDecompressionSink : CompressionSink
|
struct GzipDecompressionSink : CompressionSink
|
||||||
|
@ -75,28 +74,28 @@ struct GzipDecompressionSink : CompressionSink
|
||||||
void finish() override
|
void finish() override
|
||||||
{
|
{
|
||||||
CompressionSink::flush();
|
CompressionSink::flush();
|
||||||
write(nullptr, 0);
|
write({});
|
||||||
}
|
}
|
||||||
|
|
||||||
void write(const unsigned char * data, size_t len) override
|
void write(std::string_view data) override
|
||||||
{
|
{
|
||||||
assert(len <= std::numeric_limits<decltype(strm.avail_in)>::max());
|
assert(data.size() <= std::numeric_limits<decltype(strm.avail_in)>::max());
|
||||||
|
|
||||||
strm.next_in = (Bytef *) data;
|
strm.next_in = (Bytef *) data.data();
|
||||||
strm.avail_in = len;
|
strm.avail_in = data.size();
|
||||||
|
|
||||||
while (!finished && (!data || strm.avail_in)) {
|
while (!finished && (!data.data() || strm.avail_in)) {
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
|
|
||||||
int ret = inflate(&strm,Z_SYNC_FLUSH);
|
int ret = inflate(&strm,Z_SYNC_FLUSH);
|
||||||
if (ret != Z_OK && ret != Z_STREAM_END)
|
if (ret != Z_OK && ret != Z_STREAM_END)
|
||||||
throw CompressionError("error while decompressing gzip file: %d (%d, %d)",
|
throw CompressionError("error while decompressing gzip file: %d (%d, %d)",
|
||||||
zError(ret), len, strm.avail_in);
|
zError(ret), data.size(), strm.avail_in);
|
||||||
|
|
||||||
finished = ret == Z_STREAM_END;
|
finished = ret == Z_STREAM_END;
|
||||||
|
|
||||||
if (strm.avail_out < sizeof(outbuf) || strm.avail_in == 0) {
|
if (strm.avail_out < sizeof(outbuf) || strm.avail_in == 0) {
|
||||||
nextSink(outbuf, sizeof(outbuf) - strm.avail_out);
|
nextSink({(char *) outbuf, sizeof(outbuf) - strm.avail_out});
|
||||||
strm.next_out = (Bytef *) outbuf;
|
strm.next_out = (Bytef *) outbuf;
|
||||||
strm.avail_out = sizeof(outbuf);
|
strm.avail_out = sizeof(outbuf);
|
||||||
}
|
}
|
||||||
|
@ -130,25 +129,25 @@ struct XzDecompressionSink : CompressionSink
|
||||||
void finish() override
|
void finish() override
|
||||||
{
|
{
|
||||||
CompressionSink::flush();
|
CompressionSink::flush();
|
||||||
write(nullptr, 0);
|
write({});
|
||||||
}
|
}
|
||||||
|
|
||||||
void write(const unsigned char * data, size_t len) override
|
void write(std::string_view data) override
|
||||||
{
|
{
|
||||||
strm.next_in = data;
|
strm.next_in = (const unsigned char *) data.data();
|
||||||
strm.avail_in = len;
|
strm.avail_in = data.size();
|
||||||
|
|
||||||
while (!finished && (!data || strm.avail_in)) {
|
while (!finished && (!data.data() || strm.avail_in)) {
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
|
|
||||||
lzma_ret ret = lzma_code(&strm, data ? LZMA_RUN : LZMA_FINISH);
|
lzma_ret ret = lzma_code(&strm, data.data() ? LZMA_RUN : LZMA_FINISH);
|
||||||
if (ret != LZMA_OK && ret != LZMA_STREAM_END)
|
if (ret != LZMA_OK && ret != LZMA_STREAM_END)
|
||||||
throw CompressionError("error %d while decompressing xz file", ret);
|
throw CompressionError("error %d while decompressing xz file", ret);
|
||||||
|
|
||||||
finished = ret == LZMA_STREAM_END;
|
finished = ret == LZMA_STREAM_END;
|
||||||
|
|
||||||
if (strm.avail_out < sizeof(outbuf) || strm.avail_in == 0) {
|
if (strm.avail_out < sizeof(outbuf) || strm.avail_in == 0) {
|
||||||
nextSink(outbuf, sizeof(outbuf) - strm.avail_out);
|
nextSink({(char *) outbuf, sizeof(outbuf) - strm.avail_out});
|
||||||
strm.next_out = outbuf;
|
strm.next_out = outbuf;
|
||||||
strm.avail_out = sizeof(outbuf);
|
strm.avail_out = sizeof(outbuf);
|
||||||
}
|
}
|
||||||
|
@ -181,15 +180,15 @@ struct BzipDecompressionSink : ChunkedCompressionSink
|
||||||
void finish() override
|
void finish() override
|
||||||
{
|
{
|
||||||
flush();
|
flush();
|
||||||
write(nullptr, 0);
|
write({});
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeInternal(const unsigned char * data, size_t len) override
|
void writeInternal(std::string_view data) override
|
||||||
{
|
{
|
||||||
assert(len <= std::numeric_limits<decltype(strm.avail_in)>::max());
|
assert(data.size() <= std::numeric_limits<decltype(strm.avail_in)>::max());
|
||||||
|
|
||||||
strm.next_in = (char *) data;
|
strm.next_in = (char *) data.data();
|
||||||
strm.avail_in = len;
|
strm.avail_in = data.size();
|
||||||
|
|
||||||
while (strm.avail_in) {
|
while (strm.avail_in) {
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
|
@ -201,7 +200,7 @@ struct BzipDecompressionSink : ChunkedCompressionSink
|
||||||
finished = ret == BZ_STREAM_END;
|
finished = ret == BZ_STREAM_END;
|
||||||
|
|
||||||
if (strm.avail_out < sizeof(outbuf) || strm.avail_in == 0) {
|
if (strm.avail_out < sizeof(outbuf) || strm.avail_in == 0) {
|
||||||
nextSink(outbuf, sizeof(outbuf) - strm.avail_out);
|
nextSink({(char *) outbuf, sizeof(outbuf) - strm.avail_out});
|
||||||
strm.next_out = (char *) outbuf;
|
strm.next_out = (char *) outbuf;
|
||||||
strm.avail_out = sizeof(outbuf);
|
strm.avail_out = sizeof(outbuf);
|
||||||
}
|
}
|
||||||
|
@ -230,17 +229,17 @@ struct BrotliDecompressionSink : ChunkedCompressionSink
|
||||||
void finish() override
|
void finish() override
|
||||||
{
|
{
|
||||||
flush();
|
flush();
|
||||||
writeInternal(nullptr, 0);
|
writeInternal({});
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeInternal(const unsigned char * data, size_t len) override
|
void writeInternal(std::string_view data) override
|
||||||
{
|
{
|
||||||
const uint8_t * next_in = data;
|
auto next_in = (const uint8_t *) data.data();
|
||||||
size_t avail_in = len;
|
size_t avail_in = data.size();
|
||||||
uint8_t * next_out = outbuf;
|
uint8_t * next_out = outbuf;
|
||||||
size_t avail_out = sizeof(outbuf);
|
size_t avail_out = sizeof(outbuf);
|
||||||
|
|
||||||
while (!finished && (!data || avail_in)) {
|
while (!finished && (!data.data() || avail_in)) {
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
|
|
||||||
if (!BrotliDecoderDecompressStream(state,
|
if (!BrotliDecoderDecompressStream(state,
|
||||||
|
@ -250,7 +249,7 @@ struct BrotliDecompressionSink : ChunkedCompressionSink
|
||||||
throw CompressionError("error while decompressing brotli file");
|
throw CompressionError("error while decompressing brotli file");
|
||||||
|
|
||||||
if (avail_out < sizeof(outbuf) || avail_in == 0) {
|
if (avail_out < sizeof(outbuf) || avail_in == 0) {
|
||||||
nextSink(outbuf, sizeof(outbuf) - avail_out);
|
nextSink({(char *) outbuf, sizeof(outbuf) - avail_out});
|
||||||
next_out = outbuf;
|
next_out = outbuf;
|
||||||
avail_out = sizeof(outbuf);
|
avail_out = sizeof(outbuf);
|
||||||
}
|
}
|
||||||
|
@ -338,25 +337,25 @@ struct XzCompressionSink : CompressionSink
|
||||||
void finish() override
|
void finish() override
|
||||||
{
|
{
|
||||||
CompressionSink::flush();
|
CompressionSink::flush();
|
||||||
write(nullptr, 0);
|
write({});
|
||||||
}
|
}
|
||||||
|
|
||||||
void write(const unsigned char * data, size_t len) override
|
void write(std::string_view data) override
|
||||||
{
|
{
|
||||||
strm.next_in = data;
|
strm.next_in = (const unsigned char *) data.data();
|
||||||
strm.avail_in = len;
|
strm.avail_in = data.size();
|
||||||
|
|
||||||
while (!finished && (!data || strm.avail_in)) {
|
while (!finished && (!data.data() || strm.avail_in)) {
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
|
|
||||||
lzma_ret ret = lzma_code(&strm, data ? LZMA_RUN : LZMA_FINISH);
|
lzma_ret ret = lzma_code(&strm, data.data() ? LZMA_RUN : LZMA_FINISH);
|
||||||
if (ret != LZMA_OK && ret != LZMA_STREAM_END)
|
if (ret != LZMA_OK && ret != LZMA_STREAM_END)
|
||||||
throw CompressionError("error %d while compressing xz file", ret);
|
throw CompressionError("error %d while compressing xz file", ret);
|
||||||
|
|
||||||
finished = ret == LZMA_STREAM_END;
|
finished = ret == LZMA_STREAM_END;
|
||||||
|
|
||||||
if (strm.avail_out < sizeof(outbuf) || strm.avail_in == 0) {
|
if (strm.avail_out < sizeof(outbuf) || strm.avail_in == 0) {
|
||||||
nextSink(outbuf, sizeof(outbuf) - strm.avail_out);
|
nextSink({(const char *) outbuf, sizeof(outbuf) - strm.avail_out});
|
||||||
strm.next_out = outbuf;
|
strm.next_out = outbuf;
|
||||||
strm.avail_out = sizeof(outbuf);
|
strm.avail_out = sizeof(outbuf);
|
||||||
}
|
}
|
||||||
|
@ -389,27 +388,27 @@ struct BzipCompressionSink : ChunkedCompressionSink
|
||||||
void finish() override
|
void finish() override
|
||||||
{
|
{
|
||||||
flush();
|
flush();
|
||||||
writeInternal(nullptr, 0);
|
writeInternal({});
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeInternal(const unsigned char * data, size_t len) override
|
void writeInternal(std::string_view data) override
|
||||||
{
|
{
|
||||||
assert(len <= std::numeric_limits<decltype(strm.avail_in)>::max());
|
assert(data.size() <= std::numeric_limits<decltype(strm.avail_in)>::max());
|
||||||
|
|
||||||
strm.next_in = (char *) data;
|
strm.next_in = (char *) data.data();
|
||||||
strm.avail_in = len;
|
strm.avail_in = data.size();
|
||||||
|
|
||||||
while (!finished && (!data || strm.avail_in)) {
|
while (!finished && (!data.data() || strm.avail_in)) {
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
|
|
||||||
int ret = BZ2_bzCompress(&strm, data ? BZ_RUN : BZ_FINISH);
|
int ret = BZ2_bzCompress(&strm, data.data() ? BZ_RUN : BZ_FINISH);
|
||||||
if (ret != BZ_RUN_OK && ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
|
if (ret != BZ_RUN_OK && ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
|
||||||
throw CompressionError("error %d while compressing bzip2 file", ret);
|
throw CompressionError("error %d while compressing bzip2 file", ret);
|
||||||
|
|
||||||
finished = ret == BZ_STREAM_END;
|
finished = ret == BZ_STREAM_END;
|
||||||
|
|
||||||
if (strm.avail_out < sizeof(outbuf) || strm.avail_in == 0) {
|
if (strm.avail_out < sizeof(outbuf) || strm.avail_in == 0) {
|
||||||
nextSink(outbuf, sizeof(outbuf) - strm.avail_out);
|
nextSink({(const char *) outbuf, sizeof(outbuf) - strm.avail_out});
|
||||||
strm.next_out = (char *) outbuf;
|
strm.next_out = (char *) outbuf;
|
||||||
strm.avail_out = sizeof(outbuf);
|
strm.avail_out = sizeof(outbuf);
|
||||||
}
|
}
|
||||||
|
@ -439,28 +438,28 @@ struct BrotliCompressionSink : ChunkedCompressionSink
|
||||||
void finish() override
|
void finish() override
|
||||||
{
|
{
|
||||||
flush();
|
flush();
|
||||||
writeInternal(nullptr, 0);
|
writeInternal({});
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeInternal(const unsigned char * data, size_t len) override
|
void writeInternal(std::string_view data) override
|
||||||
{
|
{
|
||||||
const uint8_t * next_in = data;
|
auto next_in = (const uint8_t *) data.data();
|
||||||
size_t avail_in = len;
|
size_t avail_in = data.size();
|
||||||
uint8_t * next_out = outbuf;
|
uint8_t * next_out = outbuf;
|
||||||
size_t avail_out = sizeof(outbuf);
|
size_t avail_out = sizeof(outbuf);
|
||||||
|
|
||||||
while (!finished && (!data || avail_in)) {
|
while (!finished && (!data.data() || avail_in)) {
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
|
|
||||||
if (!BrotliEncoderCompressStream(state,
|
if (!BrotliEncoderCompressStream(state,
|
||||||
data ? BROTLI_OPERATION_PROCESS : BROTLI_OPERATION_FINISH,
|
data.data() ? BROTLI_OPERATION_PROCESS : BROTLI_OPERATION_FINISH,
|
||||||
&avail_in, &next_in,
|
&avail_in, &next_in,
|
||||||
&avail_out, &next_out,
|
&avail_out, &next_out,
|
||||||
nullptr))
|
nullptr))
|
||||||
throw CompressionError("error while compressing brotli compression");
|
throw CompressionError("error while compressing brotli compression");
|
||||||
|
|
||||||
if (avail_out < sizeof(outbuf) || avail_in == 0) {
|
if (avail_out < sizeof(outbuf) || avail_in == 0) {
|
||||||
nextSink(outbuf, sizeof(outbuf) - avail_out);
|
nextSink({(const char *) outbuf, sizeof(outbuf) - avail_out});
|
||||||
next_out = outbuf;
|
next_out = outbuf;
|
||||||
avail_out = sizeof(outbuf);
|
avail_out = sizeof(outbuf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -291,12 +291,12 @@ static void start(HashType ht, Ctx & ctx)
|
||||||
|
|
||||||
|
|
||||||
static void update(HashType ht, Ctx & ctx,
|
static void update(HashType ht, Ctx & ctx,
|
||||||
const unsigned char * bytes, size_t len)
|
std::string_view data)
|
||||||
{
|
{
|
||||||
if (ht == htMD5) MD5_Update(&ctx.md5, bytes, len);
|
if (ht == htMD5) MD5_Update(&ctx.md5, data.data(), data.size());
|
||||||
else if (ht == htSHA1) SHA1_Update(&ctx.sha1, bytes, len);
|
else if (ht == htSHA1) SHA1_Update(&ctx.sha1, data.data(), data.size());
|
||||||
else if (ht == htSHA256) SHA256_Update(&ctx.sha256, bytes, len);
|
else if (ht == htSHA256) SHA256_Update(&ctx.sha256, data.data(), data.size());
|
||||||
else if (ht == htSHA512) SHA512_Update(&ctx.sha512, bytes, len);
|
else if (ht == htSHA512) SHA512_Update(&ctx.sha512, data.data(), data.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -314,7 +314,7 @@ Hash hashString(HashType ht, std::string_view s)
|
||||||
Ctx ctx;
|
Ctx ctx;
|
||||||
Hash hash(ht);
|
Hash hash(ht);
|
||||||
start(ht, ctx);
|
start(ht, ctx);
|
||||||
update(ht, ctx, (const unsigned char *) s.data(), s.length());
|
update(ht, ctx, s);
|
||||||
finish(ht, ctx, hash.hash);
|
finish(ht, ctx, hash.hash);
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
@ -341,10 +341,10 @@ HashSink::~HashSink()
|
||||||
delete ctx;
|
delete ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HashSink::write(const unsigned char * data, size_t len)
|
void HashSink::write(std::string_view data)
|
||||||
{
|
{
|
||||||
bytes += len;
|
bytes += data.size();
|
||||||
update(ht, *ctx, data, len);
|
update(ht, *ctx, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
HashResult HashSink::finish()
|
HashResult HashSink::finish()
|
||||||
|
|
|
@ -156,7 +156,7 @@ public:
|
||||||
HashSink(HashType ht);
|
HashSink(HashType ht);
|
||||||
HashSink(const HashSink & h);
|
HashSink(const HashSink & h);
|
||||||
~HashSink();
|
~HashSink();
|
||||||
void write(const unsigned char * data, size_t len) override;
|
void write(std::string_view data) override;
|
||||||
HashResult finish() override;
|
HashResult finish() override;
|
||||||
HashResult currentHash();
|
HashResult currentHash();
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,23 +11,23 @@
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
||||||
void BufferedSink::operator () (const unsigned char * data, size_t len)
|
void BufferedSink::operator () (std::string_view data)
|
||||||
{
|
{
|
||||||
if (!buffer) buffer = decltype(buffer)(new unsigned char[bufSize]);
|
if (!buffer) buffer = decltype(buffer)(new char[bufSize]);
|
||||||
|
|
||||||
while (len) {
|
while (!data.empty()) {
|
||||||
/* Optimisation: bypass the buffer if the data exceeds the
|
/* Optimisation: bypass the buffer if the data exceeds the
|
||||||
buffer size. */
|
buffer size. */
|
||||||
if (bufPos + len >= bufSize) {
|
if (bufPos + data.size() >= bufSize) {
|
||||||
flush();
|
flush();
|
||||||
write(data, len);
|
write(data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Otherwise, copy the bytes to the buffer. Flush the buffer
|
/* Otherwise, copy the bytes to the buffer. Flush the buffer
|
||||||
when it's full. */
|
when it's full. */
|
||||||
size_t n = bufPos + len > bufSize ? bufSize - bufPos : len;
|
size_t n = bufPos + data.size() > bufSize ? bufSize - bufPos : data.size();
|
||||||
memcpy(buffer.get() + bufPos, data, n);
|
memcpy(buffer.get() + bufPos, data.data(), n);
|
||||||
data += n; bufPos += n; len -= n;
|
data.remove_prefix(n); bufPos += n;
|
||||||
if (bufPos == bufSize) flush();
|
if (bufPos == bufSize) flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ void BufferedSink::flush()
|
||||||
if (bufPos == 0) return;
|
if (bufPos == 0) return;
|
||||||
size_t n = bufPos;
|
size_t n = bufPos;
|
||||||
bufPos = 0; // don't trigger the assert() in ~BufferedSink()
|
bufPos = 0; // don't trigger the assert() in ~BufferedSink()
|
||||||
write(buffer.get(), n);
|
write({buffer.get(), n});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,9 +59,9 @@ static void warnLargeDump()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FdSink::write(const unsigned char * data, size_t len)
|
void FdSink::write(std::string_view data)
|
||||||
{
|
{
|
||||||
written += len;
|
written += data.size();
|
||||||
static bool warned = false;
|
static bool warned = false;
|
||||||
if (warn && !warned) {
|
if (warn && !warned) {
|
||||||
if (written > threshold) {
|
if (written > threshold) {
|
||||||
|
@ -70,7 +70,7 @@ void FdSink::write(const unsigned char * data, size_t len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
writeFull(fd, data, len);
|
writeFull(fd, data);
|
||||||
} catch (SysError & e) {
|
} catch (SysError & e) {
|
||||||
_good = false;
|
_good = false;
|
||||||
throw;
|
throw;
|
||||||
|
@ -101,7 +101,7 @@ void Source::drainInto(Sink & sink)
|
||||||
size_t n;
|
size_t n;
|
||||||
try {
|
try {
|
||||||
n = read(buf.data(), buf.size());
|
n = read(buf.data(), buf.size());
|
||||||
sink(buf.data(), n);
|
sink({(char *) buf.data(), n});
|
||||||
} catch (EndOfFile &) {
|
} catch (EndOfFile &) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -229,8 +229,8 @@ std::unique_ptr<Source> sinkToSource(
|
||||||
{
|
{
|
||||||
if (!coro)
|
if (!coro)
|
||||||
coro = coro_t::pull_type(VirtualStackAllocator{}, [&](coro_t::push_type & yield) {
|
coro = coro_t::pull_type(VirtualStackAllocator{}, [&](coro_t::push_type & yield) {
|
||||||
LambdaSink sink([&](const unsigned char * data, size_t len) {
|
LambdaSink sink([&](std::string_view data) {
|
||||||
if (len) yield(std::string((const char *) data, len));
|
if (!data.empty()) yield(std::string(data));
|
||||||
});
|
});
|
||||||
fun(sink);
|
fun(sink);
|
||||||
});
|
});
|
||||||
|
@ -260,22 +260,22 @@ void writePadding(size_t len, Sink & sink)
|
||||||
if (len % 8) {
|
if (len % 8) {
|
||||||
unsigned char zero[8];
|
unsigned char zero[8];
|
||||||
memset(zero, 0, sizeof(zero));
|
memset(zero, 0, sizeof(zero));
|
||||||
sink(zero, 8 - (len % 8));
|
sink({(char *) zero, 8 - (len % 8)});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void writeString(const unsigned char * buf, size_t len, Sink & sink)
|
void writeString(std::string_view data, Sink & sink)
|
||||||
{
|
{
|
||||||
sink << len;
|
sink << data.size();
|
||||||
sink(buf, len);
|
sink(data);
|
||||||
writePadding(len, sink);
|
writePadding(data.size(), sink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Sink & operator << (Sink & sink, const string & s)
|
Sink & operator << (Sink & sink, const string & s)
|
||||||
{
|
{
|
||||||
writeString((const unsigned char *) s.data(), s.size(), sink);
|
writeString(s, sink);
|
||||||
return sink;
|
return sink;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,14 +394,14 @@ Error readError(Source & source)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void StringSink::operator () (const unsigned char * data, size_t len)
|
void StringSink::operator () (std::string_view data)
|
||||||
{
|
{
|
||||||
static bool warned = false;
|
static bool warned = false;
|
||||||
if (!warned && s->size() > threshold) {
|
if (!warned && s->size() > threshold) {
|
||||||
warnLargeDump();
|
warnLargeDump();
|
||||||
warned = true;
|
warned = true;
|
||||||
}
|
}
|
||||||
s->append((const char *) data, len);
|
s->append(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ChainSource::read(unsigned char * data, size_t len)
|
size_t ChainSource::read(unsigned char * data, size_t len)
|
||||||
|
|
|
@ -14,19 +14,14 @@ namespace nix {
|
||||||
struct Sink
|
struct Sink
|
||||||
{
|
{
|
||||||
virtual ~Sink() { }
|
virtual ~Sink() { }
|
||||||
virtual void operator () (const unsigned char * data, size_t len) = 0;
|
virtual void operator () (std::string_view data) = 0;
|
||||||
virtual bool good() { return true; }
|
virtual bool good() { return true; }
|
||||||
|
|
||||||
void operator () (const std::string & s)
|
|
||||||
{
|
|
||||||
(*this)((const unsigned char *) s.data(), s.size());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Just throws away data. */
|
/* Just throws away data. */
|
||||||
struct NullSink : Sink
|
struct NullSink : Sink
|
||||||
{
|
{
|
||||||
void operator () (const unsigned char * data, size_t len) override
|
void operator () (std::string_view data) override
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -35,21 +30,16 @@ struct NullSink : Sink
|
||||||
struct BufferedSink : virtual Sink
|
struct BufferedSink : virtual Sink
|
||||||
{
|
{
|
||||||
size_t bufSize, bufPos;
|
size_t bufSize, bufPos;
|
||||||
std::unique_ptr<unsigned char[]> buffer;
|
std::unique_ptr<char[]> buffer;
|
||||||
|
|
||||||
BufferedSink(size_t bufSize = 32 * 1024)
|
BufferedSink(size_t bufSize = 32 * 1024)
|
||||||
: bufSize(bufSize), bufPos(0), buffer(nullptr) { }
|
: bufSize(bufSize), bufPos(0), buffer(nullptr) { }
|
||||||
|
|
||||||
void operator () (const unsigned char * data, size_t len) override;
|
void operator () (std::string_view data) override;
|
||||||
|
|
||||||
void operator () (const std::string & s)
|
|
||||||
{
|
|
||||||
Sink::operator()(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void flush();
|
void flush();
|
||||||
|
|
||||||
virtual void write(const unsigned char * data, size_t len) = 0;
|
virtual void write(std::string_view data) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,7 +109,7 @@ struct FdSink : BufferedSink
|
||||||
|
|
||||||
~FdSink();
|
~FdSink();
|
||||||
|
|
||||||
void write(const unsigned char * data, size_t len) override;
|
void write(std::string_view data) override;
|
||||||
|
|
||||||
bool good() override;
|
bool good() override;
|
||||||
|
|
||||||
|
@ -163,7 +153,7 @@ struct StringSink : Sink
|
||||||
s->reserve(reservedSize);
|
s->reserve(reservedSize);
|
||||||
};
|
};
|
||||||
StringSink(ref<std::string> s) : s(s) { };
|
StringSink(ref<std::string> s) : s(s) { };
|
||||||
void operator () (const unsigned char * data, size_t len) override;
|
void operator () (std::string_view data) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -182,10 +172,10 @@ struct TeeSink : Sink
|
||||||
{
|
{
|
||||||
Sink & sink1, & sink2;
|
Sink & sink1, & sink2;
|
||||||
TeeSink(Sink & sink1, Sink & sink2) : sink1(sink1), sink2(sink2) { }
|
TeeSink(Sink & sink1, Sink & sink2) : sink1(sink1), sink2(sink2) { }
|
||||||
virtual void operator () (const unsigned char * data, size_t len)
|
virtual void operator () (std::string_view data)
|
||||||
{
|
{
|
||||||
sink1(data, len);
|
sink1(data);
|
||||||
sink2(data, len);
|
sink2(data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -200,7 +190,7 @@ struct TeeSource : Source
|
||||||
size_t read(unsigned char * data, size_t len)
|
size_t read(unsigned char * data, size_t len)
|
||||||
{
|
{
|
||||||
size_t n = orig.read(data, len);
|
size_t n = orig.read(data, len);
|
||||||
sink(data, n);
|
sink({(char *) data, n});
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -241,24 +231,24 @@ struct LengthSink : Sink
|
||||||
{
|
{
|
||||||
uint64_t length = 0;
|
uint64_t length = 0;
|
||||||
|
|
||||||
virtual void operator () (const unsigned char * _, size_t len)
|
void operator () (std::string_view data) override
|
||||||
{
|
{
|
||||||
length += len;
|
length += data.size();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Convert a function into a sink. */
|
/* Convert a function into a sink. */
|
||||||
struct LambdaSink : Sink
|
struct LambdaSink : Sink
|
||||||
{
|
{
|
||||||
typedef std::function<void(const unsigned char *, size_t)> lambda_t;
|
typedef std::function<void(std::string_view data)> lambda_t;
|
||||||
|
|
||||||
lambda_t lambda;
|
lambda_t lambda;
|
||||||
|
|
||||||
LambdaSink(const lambda_t & lambda) : lambda(lambda) { }
|
LambdaSink(const lambda_t & lambda) : lambda(lambda) { }
|
||||||
|
|
||||||
virtual void operator () (const unsigned char * data, size_t len)
|
void operator () (std::string_view data) override
|
||||||
{
|
{
|
||||||
lambda(data, len);
|
lambda(data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -302,7 +292,7 @@ std::unique_ptr<Source> sinkToSource(
|
||||||
|
|
||||||
|
|
||||||
void writePadding(size_t len, Sink & sink);
|
void writePadding(size_t len, Sink & sink);
|
||||||
void writeString(const unsigned char * buf, size_t len, Sink & sink);
|
void writeString(std::string_view s, Sink & sink);
|
||||||
|
|
||||||
inline Sink & operator << (Sink & sink, uint64_t n)
|
inline Sink & operator << (Sink & sink, uint64_t n)
|
||||||
{
|
{
|
||||||
|
@ -315,7 +305,7 @@ inline Sink & operator << (Sink & sink, uint64_t n)
|
||||||
buf[5] = (n >> 40) & 0xff;
|
buf[5] = (n >> 40) & 0xff;
|
||||||
buf[6] = (n >> 48) & 0xff;
|
buf[6] = (n >> 48) & 0xff;
|
||||||
buf[7] = (unsigned char) (n >> 56) & 0xff;
|
buf[7] = (unsigned char) (n >> 56) & 0xff;
|
||||||
sink(buf, sizeof(buf));
|
sink({(char *) buf, sizeof(buf)});
|
||||||
return sink;
|
return sink;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,7 +474,7 @@ struct FramedSink : nix::BufferedSink
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void write(const unsigned char * data, size_t len) override
|
void write(std::string_view data) override
|
||||||
{
|
{
|
||||||
/* Don't send more data if the remote has
|
/* Don't send more data if the remote has
|
||||||
encountered an error. */
|
encountered an error. */
|
||||||
|
@ -493,8 +483,8 @@ struct FramedSink : nix::BufferedSink
|
||||||
ex = nullptr;
|
ex = nullptr;
|
||||||
std::rethrow_exception(ex2);
|
std::rethrow_exception(ex2);
|
||||||
}
|
}
|
||||||
to << len;
|
to << data.size();
|
||||||
to(data, len);
|
to(data);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -346,7 +346,7 @@ void writeFile(const Path & path, Source & source, mode_t mode)
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
auto n = source.read(buf.data(), buf.size());
|
auto n = source.read(buf.data(), buf.size());
|
||||||
writeFull(fd.get(), (unsigned char *) buf.data(), n);
|
writeFull(fd.get(), {(char *) buf.data(), n});
|
||||||
} catch (EndOfFile &) { break; }
|
} catch (EndOfFile &) { break; }
|
||||||
}
|
}
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
|
@ -648,24 +648,16 @@ void readFull(int fd, unsigned char * buf, size_t count)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void writeFull(int fd, const unsigned char * buf, size_t count, bool allowInterrupts)
|
|
||||||
{
|
|
||||||
while (count) {
|
|
||||||
if (allowInterrupts) checkInterrupt();
|
|
||||||
ssize_t res = write(fd, (char *) buf, count);
|
|
||||||
if (res == -1 && errno != EINTR)
|
|
||||||
throw SysError("writing to file");
|
|
||||||
if (res > 0) {
|
|
||||||
count -= res;
|
|
||||||
buf += res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void writeFull(int fd, std::string_view s, bool allowInterrupts)
|
void writeFull(int fd, std::string_view s, bool allowInterrupts)
|
||||||
{
|
{
|
||||||
writeFull(fd, (const unsigned char *) s.data(), s.size(), allowInterrupts);
|
while (!s.empty()) {
|
||||||
|
if (allowInterrupts) checkInterrupt();
|
||||||
|
ssize_t res = write(fd, s.data(), s.size());
|
||||||
|
if (res == -1 && errno != EINTR)
|
||||||
|
throw SysError("writing to file");
|
||||||
|
if (res > 0)
|
||||||
|
s.remove_prefix(res);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -705,7 +697,7 @@ void drainFD(int fd, Sink & sink, bool block)
|
||||||
throw SysError("reading from file");
|
throw SysError("reading from file");
|
||||||
}
|
}
|
||||||
else if (rd == 0) break;
|
else if (rd == 0) break;
|
||||||
else sink(buf.data(), rd);
|
else sink({(char *) buf.data(), (size_t) rd});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1153,7 +1145,7 @@ void runProgram2(const RunOptions & options)
|
||||||
} catch (EndOfFile &) {
|
} catch (EndOfFile &) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
writeFull(in.writeSide.get(), buf.data(), n);
|
writeFull(in.writeSide.get(), {(char *) buf.data(), n});
|
||||||
}
|
}
|
||||||
promise.set_value();
|
promise.set_value();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
|
|
@ -156,7 +156,6 @@ void replaceSymlink(const Path & target, const Path & link,
|
||||||
/* Wrappers arount read()/write() that read/write exactly the
|
/* Wrappers arount read()/write() that read/write exactly the
|
||||||
requested number of bytes. */
|
requested number of bytes. */
|
||||||
void readFull(int fd, unsigned char * buf, size_t count);
|
void readFull(int fd, unsigned char * buf, size_t count);
|
||||||
void writeFull(int fd, const unsigned char * buf, size_t count, bool allowInterrupts = true);
|
|
||||||
void writeFull(int fd, std::string_view s, bool allowInterrupts = true);
|
void writeFull(int fd, std::string_view s, bool allowInterrupts = true);
|
||||||
|
|
||||||
MakeError(EndOfFile, Error);
|
MakeError(EndOfFile, Error);
|
||||||
|
|
|
@ -73,7 +73,7 @@ struct CmdMakeContentAddressable : StorePathsCommand, MixJSON
|
||||||
*sink.s = rewriteStrings(*sink.s, rewrites);
|
*sink.s = rewriteStrings(*sink.s, rewrites);
|
||||||
|
|
||||||
HashModuloSink hashModuloSink(htSHA256, oldHashPart);
|
HashModuloSink hashModuloSink(htSHA256, oldHashPart);
|
||||||
hashModuloSink((unsigned char *) sink.s->data(), sink.s->size());
|
hashModuloSink(*sink.s);
|
||||||
|
|
||||||
auto narHash = hashModuloSink.finish().first;
|
auto narHash = hashModuloSink.finish().first;
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ struct CmdMakeContentAddressable : StorePathsCommand, MixJSON
|
||||||
|
|
||||||
auto source = sinkToSource([&](Sink & nextSink) {
|
auto source = sinkToSource([&](Sink & nextSink) {
|
||||||
RewritingSink rsink2(oldHashPart, std::string(info.path.hashPart()), nextSink);
|
RewritingSink rsink2(oldHashPart, std::string(info.path.hashPart()), nextSink);
|
||||||
rsink2((unsigned char *) sink.s->data(), sink.s->size());
|
rsink2(*sink.s);
|
||||||
rsink2.flush();
|
rsink2.flush();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue