Example #1
0
	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();
	}
Example #7
0
	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);
	}
Example #8
0
	/*static*/
	AutoBlob Blob::GlobBlobs(std::vector<AutoBlob>& blobs)
	{
		AutoBlob blob = new Blob();
		blob = blob->Concat(blobs);
		return blob;
	}