* Avoid expensive conversions from char arrays to STL strings.

This commit is contained in:
Eelco Dolstra 2011-12-16 21:29:46 +00:00
parent e0bd307802
commit 8d3dfa2c17
3 changed files with 26 additions and 14 deletions

View file

@ -149,12 +149,17 @@ void writeLongLong(unsigned long long n, Sink & sink)
} }
void writeString(const unsigned char * buf, size_t len, Sink & sink)
{
writeInt(len, sink);
sink(buf, len);
writePadding(len, sink);
}
void writeString(const string & s, Sink & sink) void writeString(const string & s, Sink & sink)
{ {
size_t len = s.length(); writeString((const unsigned char *) s.c_str(), s.size(), sink);
writeInt(len, sink);
sink((const unsigned char *) s.c_str(), len);
writePadding(len, sink);
} }
@ -208,6 +213,16 @@ unsigned long long readLongLong(Source & source)
} }
size_t readString(unsigned char * buf, size_t max, Source & source)
{
size_t len = readInt(source);
if (len > max) throw Error("string is too long");
source(buf, len);
readPadding(len, source);
return len;
}
string readString(Source & source) string readString(Source & source)
{ {
size_t len = readInt(source); size_t len = readInt(source);

View file

@ -114,12 +114,14 @@ struct StringSource : Source
void writePadding(size_t len, Sink & sink); void writePadding(size_t len, Sink & sink);
void writeInt(unsigned int n, Sink & sink); void writeInt(unsigned int n, Sink & sink);
void writeLongLong(unsigned long long n, Sink & sink); void writeLongLong(unsigned long long n, Sink & sink);
void writeString(const unsigned char * buf, size_t len, Sink & sink);
void writeString(const string & s, Sink & sink); void writeString(const string & s, Sink & sink);
void writeStringSet(const StringSet & ss, Sink & sink); void writeStringSet(const StringSet & ss, Sink & sink);
void readPadding(size_t len, Source & source); void readPadding(size_t len, Source & source);
unsigned int readInt(Source & source); unsigned int readInt(Source & source);
unsigned long long readLongLong(Source & source); unsigned long long readLongLong(Source & source);
size_t readString(unsigned char * buf, size_t max, Source & source);
string readString(Source & source); string readString(Source & source);
StringSet readStringSet(Source & source); StringSet readStringSet(Source & source);

View file

@ -56,7 +56,7 @@ static void tunnelStderr(const unsigned char * buf, size_t count)
if (canSendStderr && myPid == getpid()) { if (canSendStderr && myPid == getpid()) {
try { try {
writeInt(STDERR_NEXT, to); writeInt(STDERR_NEXT, to);
writeString(string((char *) buf, count), to); writeString(buf, count, to);
to.flush(); to.flush();
} catch (...) { } catch (...) {
/* Write failed; that means that the other side is /* Write failed; that means that the other side is
@ -205,7 +205,7 @@ struct TunnelSink : Sink
virtual void operator () (const unsigned char * data, size_t len) virtual void operator () (const unsigned char * data, size_t len)
{ {
writeInt(STDERR_WRITE, to); writeInt(STDERR_WRITE, to);
writeString(string((const char *) data, len), to); writeString(data, len, to);
} }
}; };
@ -224,16 +224,11 @@ struct TunnelSource : BufferedSource
writeInt(STDERR_READ, to); writeInt(STDERR_READ, to);
writeInt(len, to); writeInt(len, to);
to.flush(); to.flush();
string s = readString(from); // !!! inefficient size_t n = readString(data, len, from);
startWork(); startWork();
if (n == 0) throw EndOfFile("unexpected end-of-file");
if (s.empty()) throw EndOfFile("unexpected end-of-file"); return n;
if (s.size() > len) throw Error("client sent too much data");
memcpy(data, (const unsigned char *) s.c_str(), s.size());
return s.size();
} }
}; };