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 " "); } 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; }