* Avoid expensive conversions from char arrays to STL strings.
This commit is contained in:
parent
e0bd307802
commit
8d3dfa2c17
3 changed files with 26 additions and 14 deletions
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue