Exemple #1
0
void add_conv_str(unsigned char **s, int *l, unsigned char *b, int ll, int encode_special)
{
	for (; ll > 0; ll--, b++) {
		if ((unsigned char)*b < ' ') continue;
		if (special_char(*b) && encode_special == 1) {
			unsigned char h[4];
			sprintf(cast_char h, "%%%02X", (unsigned)*b & 0xff);
			add_to_str(s, l, h);
		} else if (*b == '%' && encode_special <= -1 && ll > 2 && ((b[1] >= '0' && b[1] <= '9') || (b[1] >= 'A' && b[1] <= 'F') || (b[1] >= 'a' && b[1] <= 'f'))) {
			unsigned char h = 0;
			int i;
			for (i = 1; i < 3; i++) {
				if (b[i] >= '0' && b[i] <= '9') h = h * 16 + b[i] - '0';
				if (b[i] >= 'A' && b[i] <= 'F') h = h * 16 + b[i] - 'A' + 10;
				if (b[i] >= 'a' && b[i] <= 'f') h = h * 16 + b[i] - 'a' + 10;
			}
			if (h >= ' ') add_chr_to_str(s, l, h);
			ll -= 2;
			b += 2;
		} else if (*b == ' ' && (!encode_special || encode_special == -1)) {
			add_to_str(s, l, cast_uchar "&nbsp;");
		} else if (accept_char(*b) || encode_special == -2) {
			add_chr_to_str(s, l, *b);
		} else {
			add_to_str(s, l, cast_uchar "&#");
			add_num_to_str(s, l, (int)*b);
			add_chr_to_str(s, l, ';');
		}
	}
}
static int can_post_key_directly(unicode_char_t ch)
{
	int rc;

	if (queue_chars)
	{
		rc = accept_char ? accept_char(ch) : TRUE;
	}
	else
	{
		assert(codes);
		rc = ((ch < NUM_CODES) && codes[ch].ipt[0] != NULL);
	}
	return rc;
}
skit_slice skit_text_stream_read_fn(skit_text_stream *stream, skit_loaf *buffer, void *context, int (*accept_char)( skit_custom_read_context *ctx ))
{
	skit_custom_read_context ctx;
	
	sASSERT(stream != NULL);
	skit_text_stream_internal *tstreami = &(stream->as_internal);
	
	size_t block_begin = tstreami->cursor;
	size_t block_end = block_begin;
	skit_slice text = tstreami->text;
	ssize_t length = sSLENGTH(text);
	
	/* Return null when reading past the end of the stream. */
	if ( block_begin >= length )
		return skit_slice_null();
	
	skit_utf8c *text_ptr = sSPTR(text);
	ctx.caller_context = context; /* Pass the caller's context along. */
	
	int done = 0;
	while ( !done )
	{
		if ( block_end >= length )
			break;

		ctx.current_char = text_ptr[block_end];
		block_end++;
		ctx.current_slice = skit_slice_of(text, block_begin, block_end);
		if ( !accept_char( &ctx ) )
			break;
	}
	
	tstreami->cursor = block_end;
	
	return ctx.current_slice;
}
skit_slice skit_pfile_stream_read_fn(skit_pfile_stream *stream, skit_loaf *buffer, void *context, int (*accept_char)( skit_custom_read_context *ctx ))
{
	SKIT_USE_FEATURE_EMULATION;
	sASSERT(stream != NULL);
	skit_pfile_stream_internal *pstreami = &(stream->as_internal);
	skit_custom_read_context ctx;
	skit_loaf *read_buf;
	
	/* Return NULL slices when attempting to read from an already-exhausted stream. */
	if ( feof(pstreami->file_handle) )
		return skit_slice_null();
	
	/* Figure out which buffer to use. */
	read_buf = skit_pfile_get_read_buffer(pstreami, buffer);
	ssize_t length = sLLENGTH(*read_buf);
	skit_utf8c *buf_ptr = sLPTR(*read_buf);
	ctx.caller_context = context; /* Pass the caller's context along. */
	
	/* Iterate and feed the caller 1 character at a time. */
	FILE *fhandle = pstreami->file_handle;
	ssize_t nbytes = 0;
	int done = 0;
	while ( !done )
	{
		/* Get the next character. */
		int c = fgetc(fhandle);
		
		/* EOF check. */
		if ( c == EOF )
			break;
		
		/* Upsize buffer as needed. */
		nbytes++;
		if ( length < nbytes )
		{
			/* Slow, but w/e. */
			skit_loaf_resize(read_buf, nbytes+64);
			length = sLLENGTH(*read_buf);
			buf_ptr = sLPTR(*read_buf);
		}
		
		/* Place the new character into the read buffer. */
		buf_ptr[nbytes-1] = c;
		
		/* Push the character to the caller. */
		ctx.current_char = c;
		ctx.current_slice = skit_slice_of(read_buf->as_slice, 0, nbytes);
		if ( !accept_char(&ctx) )
			break;
	}
	
	/* fgetc returns EOF to signal errors as well. */
	/* To distinguish that from legit EOFs, we need to check the ferror function. */
	if ( ferror(fhandle) )
	{
		char errbuf[1024];
		sTRACE(skit_stream_throw_exc(SKIT_FILE_IO_EXCEPTION, &(stream->as_stream), skit_errno_to_cstr(errbuf, sizeof(errbuf))));
	}
	
	return ctx.current_slice;
}