AutoBlob Blob::Concat(std::vector<AutoBlob>& blobs) { if (blobs.size() == 0) { this->duplicate(); return this; } int size = this->Length(); for (size_t i = 0; i < blobs.size(); i++) { size += blobs.at(i)->Length(); } char* buffer = new char[size+1]; buffer[size] = '\0'; char* current = buffer; memcpy(current, this->Get(), this->Length()); current += this->Length(); for (size_t i = 0; i < blobs.size(); i++) { AutoBlob blob = blobs.at(i); if (blob->Length() > 0) { memcpy(current, blob->Get(), blob->Length()); current += blob->Length(); } } return new Blob(buffer, size, false); }
void PosixProcess::ReadCallback(const ValueList& args, SharedValue result) { if (args.at(0)->IsObject()) { AutoBlob blob = args.GetObject(0).cast<Blob>(); if (!blob.isNull() && blob->Length() > 0) { Poco::Mutex::ScopedLock lock(processOutputMutex); processOutput.push_back(blob); } } }
void NativePipe::RawWrite(AutoBlob blob) { try { this->RawWrite((char*) blob->Get(), blob->Length()); } catch (Poco::Exception& e) { logger->Error("Exception while try to write to pipe Pipe: %s", e.displayText().c_str()); } }
int NativePipe::Write(AutoBlob blob) { if (isReader) { // If this is a reader pipe (ie one reading from stdout and stderr // via polling), then we want to pass along the data to all attached // pipes // Someone (probably a process) wants to subscribe to this pipe's // reads synchronously. So we need to call the callback on this thread // right now. if (!readCallback.isNull()) { readCallback->Call(Value::NewObject(blob)); } return Pipe::Write(blob); } else { // If this is not a reader pipe (ie one that simply accepts write // requests via the Write(...) method, like stdin), then queue the // data to be written to the native pipe (blocking operation) by // our writer thread.: Poco::Mutex::ScopedLock lock(buffersMutex); buffers.push(blob); } return blob->Length(); }
void NativePipe::PollForWriteIteration() { AutoBlob blob = 0; while (buffers.size() > 0) { { Poco::Mutex::ScopedLock lock(buffersMutex); blob = buffers.front(); buffers.pop(); } if (!blob.isNull()) { this->RawWrite(blob); blob = 0; } } }
void NativePipe::PollForReads() { this->duplicate(); // We want to be somewhat conservative here about when // we call this->Write since event handling is inherently // slow (it's synchronous and on the main thread). We'll // keep a local buffer which we'll periodically glob and // push out. std::vector<AutoBlob> buffers; unsigned int currentBuffersLength = 0; char buffer[MAX_BUFFER_SIZE]; int length = MAX_BUFFER_SIZE; int bytesRead = this->RawRead(buffer, length); while (bytesRead > 0) { AutoBlob blob = new Blob(buffer, bytesRead); buffers.push_back(blob); currentBuffersLength += blob->Length(); if (currentBuffersLength >= READ_LOOP_BUFFER_SIZE) { AutoBlob glob = Blob::GlobBlobs(buffers); this->Write(glob); buffers.clear(); currentBuffersLength = 0; } bytesRead = this->RawRead(buffer, length); } if (!buffers.empty()) { AutoBlob glob = Blob::GlobBlobs(buffers); this->Write(glob); } this->CloseNativeRead(); this->release(); }
void Blob::Concat(const ValueList& args, SharedValue result) { std::vector<AutoBlob> blobs; for (size_t i = 0; i < args.size(); i++) { if (args.at(i)->IsObject()) { AutoBlob blob = args.GetObject(i).cast<Blob>(); if (!blob.isNull()) { blobs.push_back(blob); } } else if (args.at(i)->IsString()) { blobs.push_back(new Blob(args.GetString(i))); } } AutoBlob newBlob = this->Concat(blobs); result->SetObject(newBlob); }
/*static*/ AutoBlob Blob::GlobBlobs(std::vector<AutoBlob>& blobs) { AutoBlob blob = new Blob(); blob = blob->Concat(blobs); return blob; }