예제 #1
0
void buffer_stream_initialize( stream_buffer_t* stream, void* buffer, unsigned int mode, uint64_t size, uint64_t capacity, bool adopt, bool grow )
{
	memset( stream, 0, sizeof( stream_buffer_t ) );

	stream_initialize( (stream_t*)stream, system_byteorder() );

	if( !FOUNDATION_VALIDATE_MSG( adopt || !grow, "Cannot grow buffer streams that are not adopted" ) )
		grow = false;

	if( !buffer )
	{
		size = 0;
		capacity = 0;
	}

	if( size > capacity )
		size = capacity;

	stream->type = STREAMTYPE_MEMORY;
	stream->path = string_format( "buffer://0x%" PRIfixPTR, stream );
	stream->mode = mode & ( STREAM_OUT | STREAM_IN | STREAM_BINARY );
	stream->buffer = buffer;
	stream->size = size;
	stream->capacity = capacity;
	stream->own = adopt;
	stream->grow = ( adopt && grow );

	if( mode & STREAM_TRUNCATE )
		stream->size = 0;
	if( mode & STREAM_ATEND )
		stream->current = stream->size;

	stream->vtable = &_buffer_stream_vtable;
}
예제 #2
0
파일: pipe.c 프로젝트: HardlyHaki/ProDBG
void pipe_initialize( stream_pipe_t* pipestream )
{
	stream_t* stream = (stream_t*)pipestream;

	memset( stream, 0, sizeof( stream_pipe_t ) );

	stream_initialize( stream, system_byteorder() );

	pipestream->type = STREAMTYPE_PIPE;
	pipestream->path = string_format( "pipe://0x" PRIfixPTR, pipestream );
	pipestream->mode = STREAM_OUT | STREAM_IN | STREAM_BINARY;
	pipestream->sequential = true;

#if FOUNDATION_PLATFORM_WINDOWS
	{
		//Inheritable by default so process can use for stdstreams
		SECURITY_ATTRIBUTES security_attribs = {0};
		security_attribs.nLength = sizeof( SECURITY_ATTRIBUTES );
		security_attribs.bInheritHandle = TRUE;
		security_attribs.lpSecurityDescriptor = 0;

		if( !CreatePipe( &pipestream->handle_read, &pipestream->handle_write, &security_attribs, 0 ) )
			log_warnf( 0, WARNING_SYSTEM_CALL_FAIL, "Unable to create unnamed pipe: %s", system_error_message( GetLastError() ) );
	}
#elif FOUNDATION_PLATFORM_POSIX || FOUNDATION_PLATFORM_PNACL
	int fds[2] = { 0, 0 };
	if( pipe( fds ) < 0 )
		log_warnf( 0, WARNING_SYSTEM_CALL_FAIL, "Unable to create unnamed pipe: %s", system_error_message( 0 ) );
	pipestream->fd_read = fds[0];
	pipestream->fd_write = fds[1];
#endif

	pipestream->vtable = &_pipe_stream_vtable;
}
예제 #3
0
void
buffer_stream_initialize(stream_buffer_t* stream, void* buffer, unsigned int mode, size_t size,
                         size_t capacity, bool adopt, bool grow) {
	memset(stream, 0, sizeof(stream_buffer_t));
	stream_initialize((stream_t*)stream, system_byteorder());

	if (!adopt && grow) {
		log_warn(0, WARNING_INVALID_VALUE, STRING_CONST("Cannot grow buffer streams that are not adopted"));
		grow = false;
	}

	if (!buffer) {
		size = 0;
		capacity = 0;
	}
	if (size > capacity)
		size = capacity;

	stream->type = STREAMTYPE_MEMORY;
	stream->path = string_allocate_format(STRING_CONST("buffer://0x%" PRIfixPTR), (uintptr_t)stream);
	stream->mode = mode & (STREAM_OUT | STREAM_IN | STREAM_BINARY);
	stream->buffer = buffer;
	stream->size = size;
	stream->capacity = capacity;
	stream->own = adopt;
	stream->grow = (adopt && grow);
	stream->lastmod = time_current();

	if ((mode & STREAM_OUT) && (mode & STREAM_TRUNCATE))
		stream->size = 0;
	if (mode & STREAM_ATEND)
		stream->current = stream->size;

	stream->vtable = &_buffer_stream_vtable;
}
예제 #4
0
void
socket_stream_initialize(socket_stream_t* stream, socket_t* sock) {
	//Network streams are always little endian by default
	stream_initialize((stream_t*)stream, BYTEORDER_LITTLEENDIAN);

	stream->type = STREAMTYPE_SOCKET;
	stream->sequential = 1;
	stream->mode = STREAM_OUT | STREAM_IN | STREAM_BINARY;
	stream->vtable = &_socket_stream_vtable;
	stream->socket = sock;

	if (sock->stream_initialize_fn)
		sock->stream_initialize_fn(sock, (stream_t*)stream);
}
예제 #5
0
void ringbuffer_stream_initialize( stream_ringbuffer_t* stream, unsigned int buffer_size, uint64_t total_size )
{
	memset( stream, 0, sizeof( stream_ringbuffer_t ) );

	stream_initialize( (stream_t*)stream, system_byteorder() );

	stream->type = STREAMTYPE_RINGBUFFER;
	stream->sequential = 1;
	stream->path = string_format( "ringbuffer://0x%" PRIfixPTR, stream );
	stream->mode = STREAM_OUT | STREAM_IN | STREAM_BINARY;

	ringbuffer_initialize( RINGBUFFER_FROM_STREAM( stream ), buffer_size );
	semaphore_initialize( &stream->signal_read, 0 );
	semaphore_initialize( &stream->signal_write, 0 );

	stream->total_size = total_size;

	stream->vtable = &_ringbuffer_stream_vtable;
}
예제 #6
0
size_t utf8normalize(const char* input, size_t inputSize, char* target, size_t targetSize, size_t flags, int32_t* errors)
{
	char* dst = target;
	size_t dst_size = targetSize;
	StreamState stream[4];
	DecomposeState decompose_state;
	ComposeState compose_state;
	uint8_t compatibility = (flags & UTF8_NORMALIZE_COMPATIBILITY) != 0;
	StreamState* stream_output;
	uint8_t finished = 0;
	size_t bytes_written = 0;

	/*
		Decomposition uses the following process:

		input         -->  stream[0]  -->
		(decompose)   -->  stream[1]  -->
		(accumulate)  -->  stream[2]  -->
		output

		The accumulation step is necessary in order to prevent buffer overflow
		attacks.

		Composition adds another stream buffer:

		input         --> stream[0]  -->
		(decompose)   --> stream[1]  -->
		(accumulate)  --> stream[2]  -->
		(compose)     --> stream[3]  -->
		output

		Although four streaming buffers may seem excessive, they are necessary
		for preventing allocations on the heap.
	*/

	/* Check for valid flags */

	if ((flags & (UTF8_NORMALIZE_DECOMPOSE | UTF8_NORMALIZE_COMPOSE)) == 0)
	{
		UTF8_SET_ERROR(INVALID_FLAG);

		return bytes_written;
	}

	/* Validate parameters */

	UTF8_VALIDATE_PARAMETERS_CHAR(char, bytes_written);

	/* Initialize decomposition */

	memset(stream, 0, sizeof(stream));

	if (!stream_initialize(&stream[0], input, inputSize) ||
		!decompose_initialize(&decompose_state, &stream[0], &stream[1], compatibility))
	{
		UTF8_SET_ERROR(INVALID_DATA);

		return bytes_written;
	}

	stream_output = &stream[2];

	if ((flags & UTF8_NORMALIZE_COMPOSE) != 0)
	{
		/* Initialize composition */

		if (!compose_initialize(&compose_state, &stream[2], &stream[3], compatibility))
		{
			UTF8_SET_ERROR(INVALID_DATA);

			return bytes_written;
		}

		stream_output = &stream[3];
	}

	do
	{
		uint8_t write = 0;

		/* Accumulate decomposed input in next stream */

		if (stream[1].current > 0)
		{
			unicode_t* src_codepoint = stream[1].codepoint;
			unicode_t* dst_codepoint = stream[2].codepoint + stream[2].filled;
			uint8_t* src_qc = stream[1].quick_check;
			uint8_t* dst_qc = stream[2].quick_check + stream[2].filled;
			uint8_t* src_ccc = stream[1].canonical_combining_class;
			uint8_t* dst_ccc = stream[2].canonical_combining_class + stream[2].filled;

			if ((flags & UTF8_NORMALIZE_COMPOSE) != 0)
			{
				uint8_t i;

				/* Update stream properties to use composition values */

				for (i = 0; i < stream[1].current; ++i)
				{
					*dst_qc++ = PROPERTY_GET(compose_state.qc_index, compose_state.qc_data, *src_codepoint);
					*dst_ccc++ = *src_ccc++;
					*dst_codepoint++ = *src_codepoint++;
				}
			}
			else
			{
				/* Copy directly */

				memcpy(dst_codepoint, src_codepoint, stream[1].current * sizeof(unicode_t));
				memcpy(dst_qc, src_qc, stream[1].current * sizeof(uint8_t));
				memcpy(dst_ccc, src_ccc, stream[1].current * sizeof(uint8_t));
			}

			stream[2].current += stream[1].current;
			stream[2].filled += stream[1].current;
		}

		/* Decompose input sequence into next stream */

		finished = !decompose_execute(&decompose_state);
		if (!finished)
		{
			/* Output current stream it it could overflow accumulation buffer */

			write = (stream[1].current + stream[2].filled) >= STREAM_SAFE_MAX;
		}

		/* Reorder potentially unordered decomposed stream */

		if (!stream[1].stable)
		{
			stream_reorder(&stream[1]);
		}

		/* Write stream to output when overflowing or when accumulation buffer is empty*/

		if (write ||
			finished)
		{
			uint8_t i;

			/* Compose accumulation buffer */

			if ((flags & UTF8_NORMALIZE_COMPOSE) != 0 &&
				!compose_execute(&compose_state))
			{
				break;
			}

			/* Write to output buffer */

			for (i = 0; i < stream_output->current; ++i)
			{
				uint8_t encoded_size = codepoint_write(stream_output->codepoint[i], &dst, &dst_size);
				if (encoded_size == 0)
				{
					UTF8_SET_ERROR(NOT_ENOUGH_SPACE);

					return bytes_written;
				}

				bytes_written += encoded_size;
			}

			/* Reset accumulation buffer */

			stream[2].current = 0;
			stream[2].filled = 0;
		}
	}
	while (!finished);

	UTF8_SET_ERROR(NONE);

	return bytes_written;
}