Sink: Use std::string_view

This commit is contained in:
Eelco Dolstra 2020-12-02 14:00:43 +01:00
parent aa68486112
commit faa31f4084
21 changed files with 182 additions and 211 deletions

View file

@ -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)

View file

@ -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";

View file

@ -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);
} }
}; };

View file

@ -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);
} }
} }

View file

@ -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()) { }

View file

@ -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

View file

@ -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};

View file

@ -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;
}; };

View file

@ -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();
} }

View file

@ -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());
} }

View file

@ -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 };

View file

@ -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);

View file

@ -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)

View file

@ -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);
} }

View file

@ -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()

View file

@ -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();
}; };

View file

@ -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)

View file

@ -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);
}; };
}; };

View file

@ -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 (...) {

View file

@ -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);

View file

@ -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();
}); });