Refactored away some grossly duplicated code in Socket::write.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3357 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
parent
ba298b2e7c
commit
937e32fb99
@ -483,32 +483,60 @@ void Socket::notifyDataRead(const char* data, size_t length) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Socket::writeBytes(std::function<int(const char*, size_t)> callback, v8::Handle<v8::Value> value, int* outLength) {
|
||||||
|
int result = -1;
|
||||||
|
|
||||||
|
if (value->IsArrayBufferView()) {
|
||||||
|
v8::Handle<v8::ArrayBufferView> array = v8::Handle<v8::ArrayBufferView>::Cast(value);
|
||||||
|
result = callback(reinterpret_cast<const char*>(array->Buffer()->GetContents().Data()), array->Buffer()->GetContents().ByteLength());
|
||||||
|
if (outLength) {
|
||||||
|
*outLength = array->Buffer()->GetContents().ByteLength();
|
||||||
|
}
|
||||||
|
} else if (value->IsString()) {
|
||||||
|
v8::Handle<v8::String> stringValue = v8::Handle<v8::String>::Cast(value);
|
||||||
|
if (stringValue->ContainsOnlyOneByte()) {
|
||||||
|
std::vector<uint8_t> bytes(stringValue->Length());
|
||||||
|
stringValue->WriteOneByte(bytes.data(), 0, bytes.size(), v8::String::NO_NULL_TERMINATION);
|
||||||
|
result = callback(reinterpret_cast<const char*>(bytes.data()), bytes.size());
|
||||||
|
if (outLength) {
|
||||||
|
*outLength = stringValue->Length();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
v8::String::Utf8Value utf8(stringValue);
|
||||||
|
result = callback(*utf8, utf8.length());
|
||||||
|
if (outLength) {
|
||||||
|
*outLength = utf8.length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Socket::writeInternal(promiseid_t promise, const char* data, size_t length) {
|
||||||
|
char* rawBuffer = new char[sizeof(uv_write_t) + length];
|
||||||
|
uv_write_t* request = reinterpret_cast<uv_write_t*>(rawBuffer);
|
||||||
|
std::memcpy(rawBuffer + sizeof(uv_write_t), data, length);
|
||||||
|
|
||||||
|
uv_buf_t buffer;
|
||||||
|
buffer.base = rawBuffer + sizeof(uv_write_t);
|
||||||
|
buffer.len = length;
|
||||||
|
|
||||||
|
request->data = reinterpret_cast<void*>(promise);
|
||||||
|
return uv_write(request, reinterpret_cast<uv_stream_t*>(&_socket), &buffer, 1, onWrite);
|
||||||
|
}
|
||||||
|
|
||||||
void Socket::write(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
void Socket::write(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||||
if (Socket* socket = Socket::get(args.Data())) {
|
if (Socket* socket = Socket::get(args.Data())) {
|
||||||
promiseid_t promise = socket->_task->allocatePromise();
|
promiseid_t promise = socket->_task->allocatePromise();
|
||||||
args.GetReturnValue().Set(socket->_task->getPromise(promise));
|
args.GetReturnValue().Set(socket->_task->getPromise(promise));
|
||||||
v8::Handle<v8::Value> value = args[0];
|
v8::Handle<v8::Value> value = args[0];
|
||||||
if (!value.IsEmpty() && (value->IsString() || value->IsUint8Array())) {
|
if (!value.IsEmpty()) {
|
||||||
if (socket->_tls) {
|
if (socket->_tls) {
|
||||||
socket->reportTlsErrors();
|
socket->reportTlsErrors();
|
||||||
int result;
|
int length = 0;
|
||||||
int length;
|
std::function<int(const char*, size_t)> writeFunction = std::bind(&TlsSession::writePlain, socket->_tls, std::placeholders::_1, std::placeholders::_2);
|
||||||
if (value->IsArrayBufferView()) {
|
int result = socket->writeBytes(writeFunction, value, &length);
|
||||||
v8::Handle<v8::ArrayBufferView> array = v8::Handle<v8::ArrayBufferView>::Cast(value);
|
|
||||||
result = socket->_tls->writePlain(reinterpret_cast<const char*>(array->Buffer()->GetContents().Data()), array->Buffer()->GetContents().ByteLength());
|
|
||||||
} else if (value->IsString()) {
|
|
||||||
v8::Handle<v8::String> stringValue = v8::Handle<v8::String>::Cast(value);
|
|
||||||
if (stringValue->ContainsOnlyOneByte()) {
|
|
||||||
length = stringValue->Length();
|
|
||||||
std::vector<uint8_t> bytes(length);
|
|
||||||
stringValue->WriteOneByte(bytes.data(), 0, bytes.size(), v8::String::NO_NULL_TERMINATION);
|
|
||||||
result = socket->_tls->writePlain(reinterpret_cast<const char*>(bytes.data()), bytes.size());
|
|
||||||
} else {
|
|
||||||
v8::String::Utf8Value utf8(stringValue);
|
|
||||||
length = utf8.length();
|
|
||||||
result = socket->_tls->writePlain(*utf8, utf8.length());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
char buffer[8192];
|
char buffer[8192];
|
||||||
if (result <= 0 && socket->_tls->getError(buffer, sizeof(buffer))) {
|
if (result <= 0 && socket->_tls->getError(buffer, sizeof(buffer))) {
|
||||||
socket->_task->rejectPromise(promise, v8::String::NewFromUtf8(args.GetIsolate(), buffer));
|
socket->_task->rejectPromise(promise, v8::String::NewFromUtf8(args.GetIsolate(), buffer));
|
||||||
@ -520,34 +548,10 @@ void Socket::write(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
|||||||
socket->processOutgoingTls();
|
socket->processOutgoingTls();
|
||||||
} else {
|
} else {
|
||||||
int length;
|
int length;
|
||||||
char* rawBuffer = 0;
|
|
||||||
v8::Handle<v8::String> stringValue = v8::Handle<v8::String>::Cast(value);
|
|
||||||
if (stringValue->IsArrayBufferView()) {
|
|
||||||
v8::Handle<v8::ArrayBufferView> array = v8::Handle<v8::ArrayBufferView>::Cast(value);
|
|
||||||
length = array->Buffer()->GetContents().ByteLength();
|
|
||||||
rawBuffer = new char[sizeof(uv_write_t) + length];
|
|
||||||
std::memcpy(rawBuffer + sizeof(uv_write_t), array->Buffer()->GetContents().Data(), length);
|
|
||||||
} else if (value->IsString()) {
|
|
||||||
v8::String::Utf8Value utf8(stringValue);
|
|
||||||
if (stringValue->ContainsOnlyOneByte()) {
|
|
||||||
length = stringValue->Length();
|
|
||||||
rawBuffer = new char[sizeof(uv_write_t) + length];
|
|
||||||
stringValue->WriteOneByte(reinterpret_cast<uint8_t*>(rawBuffer) + sizeof(uv_write_t), 0, length, v8::String::NO_NULL_TERMINATION);
|
|
||||||
} else {
|
|
||||||
v8::String::Utf8Value utf8(stringValue);
|
|
||||||
length = utf8.length();
|
|
||||||
rawBuffer = new char[sizeof(uv_write_t) + length];
|
|
||||||
std::memcpy(rawBuffer + sizeof(uv_write_t), *utf8, length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uv_write_t* request = reinterpret_cast<uv_write_t*>(rawBuffer);
|
|
||||||
|
|
||||||
uv_buf_t buffer;
|
std::function<int(const char*, size_t)> writeFunction = std::bind(&Socket::writeInternal, socket, promise, std::placeholders::_1, std::placeholders::_2);
|
||||||
buffer.base = rawBuffer + sizeof(uv_write_t);
|
int result = socket->writeBytes(writeFunction, value, &length);
|
||||||
buffer.len = length;
|
|
||||||
|
|
||||||
request->data = reinterpret_cast<void*>(promise);
|
|
||||||
int result = uv_write(request, reinterpret_cast<uv_stream_t*>(&socket->_socket), &buffer, 1, onWrite);
|
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
std::string error = "uv_write: " + std::string(uv_strerror(result));
|
std::string error = "uv_write: " + std::string(uv_strerror(result));
|
||||||
socket->_task->rejectPromise(promise, v8::String::NewFromUtf8(args.GetIsolate(), error.c_str(), v8::String::kNormalString, error.size()));
|
socket->_task->rejectPromise(promise, v8::String::NewFromUtf8(args.GetIsolate(), error.c_str(), v8::String::kNormalString, error.size()));
|
||||||
|
@ -75,6 +75,8 @@ private:
|
|||||||
static void onRelease(const v8::WeakCallbackInfo<Socket>& data);
|
static void onRelease(const v8::WeakCallbackInfo<Socket>& data);
|
||||||
|
|
||||||
void notifyDataRead(const char* data, size_t length);
|
void notifyDataRead(const char* data, size_t length);
|
||||||
|
int writeBytes(std::function<int(const char*, size_t)> callback, v8::Handle<v8::Value> value, int* outLength);
|
||||||
|
int writeInternal(promiseid_t promise, const char* data, size_t length);
|
||||||
void processTlsShutdown(promiseid_t promise);
|
void processTlsShutdown(promiseid_t promise);
|
||||||
static void onTlsShutdown(uv_write_t* request, int status);
|
static void onTlsShutdown(uv_write_t* request, int status);
|
||||||
void shutdownInternal(promiseid_t promise);
|
void shutdownInternal(promiseid_t promise);
|
||||||
|
Loading…
Reference in New Issue
Block a user