📄 mbfilter.c
字号:
if (pc->output >= pc->stop) { return -1; } if (pc->output >= pc->start) { (*pc->next_filter->filter_function)(c, pc->next_filter); } pc->output++; return c;}mbfl_string *mbfl_substr( mbfl_string *string, mbfl_string *result, int from, int length){ const mbfl_encoding *encoding; int n, m, k, len, start, end; unsigned char *p, *w; const unsigned char *mbtab; encoding = mbfl_no2encoding(string->no_encoding); if (encoding == NULL || string == NULL || result == NULL) { return NULL; } mbfl_string_init(result); result->no_language = string->no_language; result->no_encoding = string->no_encoding; if ((encoding->flag & (MBFL_ENCTYPE_SBCS | MBFL_ENCTYPE_WCS2BE | MBFL_ENCTYPE_WCS2LE | MBFL_ENCTYPE_WCS4BE | MBFL_ENCTYPE_WCS4LE)) || encoding->mblen_table != NULL) { len = string->len; start = from; end = from + length; if (encoding->flag & (MBFL_ENCTYPE_WCS2BE | MBFL_ENCTYPE_MWC2LE)) { start *= 2; end = start + length*2; } else if (encoding->flag & (MBFL_ENCTYPE_WCS4BE | MBFL_ENCTYPE_MWC4LE)) { start *= 4; end = start + length*4; } else if (encoding->mblen_table != NULL) { mbtab = encoding->mblen_table; start = 0; end = 0; n = 0; k = 0; p = string->val; if (p != NULL) { /* search start position */ while (k <= from) { start = n; if (n >= len) { break; } m = mbtab[*p]; n += m; p += m; k++; } /* detect end position */ k = 0; end = start; while (k < length) { end = n; if (n >= len) { break; } m = mbtab[*p]; n += m; p += m; k++; } } } if (start > len) { start = len; } if (start < 0) { start = 0; } if (end > len) { end = len; } if (end < 0) { end = 0; } if (start > end) { start = end; } /* allocate memory and copy */ n = end - start; result->len = 0; result->val = w = (unsigned char*)mbfl_malloc((n + 8)*sizeof(unsigned char)); if (w != NULL) { p = string->val; if (p != NULL) { p += start; result->len = n; while (n > 0) { *w++ = *p++; n--; } } *w++ = '\0'; *w++ = '\0'; *w++ = '\0'; *w = '\0'; } else { result = NULL; } } else { mbfl_memory_device device; struct collector_substr_data pc; mbfl_convert_filter *decoder; mbfl_convert_filter *encoder; mbfl_memory_device_init(&device, length + 1, 0); mbfl_string_init(result); result->no_language = string->no_language; result->no_encoding = string->no_encoding; /* output code filter */ decoder = mbfl_convert_filter_new( mbfl_no_encoding_wchar, string->no_encoding, mbfl_memory_device_output, 0, &device); /* wchar filter */ encoder = mbfl_convert_filter_new( string->no_encoding, mbfl_no_encoding_wchar, collector_substr, 0, &pc); if (decoder == NULL || encoder == NULL) { mbfl_convert_filter_delete(encoder); mbfl_convert_filter_delete(decoder); return NULL; } pc.next_filter = decoder; pc.start = from; pc.stop = from + length; pc.output = 0; /* feed data */ p = string->val; n = string->len; if (p != NULL) { while (n > 0) { if ((*encoder->filter_function)(*p++, encoder) < 0) { break; } n--; } } mbfl_convert_filter_flush(encoder); mbfl_convert_filter_flush(decoder); result = mbfl_memory_device_result(&device, result); mbfl_convert_filter_delete(encoder); mbfl_convert_filter_delete(decoder); } return result;}/* * strcut */mbfl_string *mbfl_strcut( mbfl_string *string, mbfl_string *result, int from, int length){ const mbfl_encoding *encoding; int n, m, k, len, start, end; unsigned char *p, *w; const unsigned char *mbtab; mbfl_memory_device device; mbfl_convert_filter *encoder, *encoder_tmp, *decoder, *decoder_tmp; encoding = mbfl_no2encoding(string->no_encoding); if (encoding == NULL || string == NULL || result == NULL) { return NULL; } mbfl_string_init(result); result->no_language = string->no_language; result->no_encoding = string->no_encoding; if ((encoding->flag & (MBFL_ENCTYPE_SBCS | MBFL_ENCTYPE_WCS2BE | MBFL_ENCTYPE_WCS2LE | MBFL_ENCTYPE_WCS4BE | MBFL_ENCTYPE_WCS4LE)) || encoding->mblen_table != NULL) { len = string->len; start = from; end = from + length; if (encoding->flag & (MBFL_ENCTYPE_WCS2BE | MBFL_ENCTYPE_WCS2LE)) { start /= 2; start *= 2; end = length/2; end *= 2; end += start; } else if (encoding->flag & (MBFL_ENCTYPE_WCS4BE | MBFL_ENCTYPE_WCS4LE)) { start /= 4; start *= 4; end = length/4; end *= 4; end += start; } else if (encoding->mblen_table != NULL) { mbtab = encoding->mblen_table; start = 0; end = 0; n = 0; p = string->val; if (p != NULL) { /* search start position */ for (;;) { m = mbtab[*p]; n += m; p += m; if (n > from) { break; } start = n; } /* search end position */ k = start + length; if (k >= (int)string->len) { end = string->len; } else { end = start; while (n <= k) { end = n; m = mbtab[*p]; n += m; p += m; } } } } if (start > len) { start = len; } if (start < 0) { start = 0; } if (end > len) { end = len; } if (end < 0) { end = 0; } if (start > end) { start = end; } /* allocate memory and copy string */ n = end - start; result->len = 0; result->val = w = (unsigned char*)mbfl_malloc((n + 8)*sizeof(unsigned char)); if (w != NULL) { result->len = n; p = &(string->val[start]); while (n > 0) { *w++ = *p++; n--; } *w++ = '\0'; *w++ = '\0'; *w++ = '\0'; *w = '\0'; } else { result = NULL; } } else { /* wchar filter */ encoder = mbfl_convert_filter_new( string->no_encoding, mbfl_no_encoding_wchar, mbfl_filter_output_null, 0, 0); encoder_tmp = mbfl_convert_filter_new( string->no_encoding, mbfl_no_encoding_wchar, mbfl_filter_output_null, 0, 0); /* output code filter */ decoder = mbfl_convert_filter_new( mbfl_no_encoding_wchar, string->no_encoding, mbfl_memory_device_output, 0, &device); decoder_tmp = mbfl_convert_filter_new( mbfl_no_encoding_wchar, string->no_encoding, mbfl_memory_device_output, 0, &device); if (encoder == NULL || encoder_tmp == NULL || decoder == NULL || decoder_tmp == NULL) { mbfl_convert_filter_delete(encoder); mbfl_convert_filter_delete(encoder_tmp); mbfl_convert_filter_delete(decoder); mbfl_convert_filter_delete(decoder_tmp); return NULL; } mbfl_memory_device_init(&device, length + 8, 0); k = 0; n = 0; p = string->val; if (p != NULL) { /* seartch start position */ while (n < from) { (*encoder->filter_function)(*p++, encoder); n++; } /* output a little shorter than "length" */ encoder->output_function = mbfl_filter_output_pipe; encoder->data = decoder; k = length - 20; len = string->len; while (n < len && device.pos < k) { (*encoder->filter_function)(*p++, encoder); n++; } /* detect end position */ for (;;) { /* backup current state */ k = device.pos; mbfl_convert_filter_copy(encoder, encoder_tmp); mbfl_convert_filter_copy(decoder, decoder_tmp); if (n >= len) { break; } /* feed 1byte and flush */ (*encoder->filter_function)(*p, encoder); (*encoder->filter_flush)(encoder); (*decoder->filter_flush)(decoder); if (device.pos > length) { break; } /* restore filter and re-feed data */ device.pos = k; mbfl_convert_filter_copy(encoder_tmp, encoder); mbfl_convert_filter_copy(decoder_tmp, decoder); (*encoder->filter_function)(*p, encoder); p++; n++; } device.pos = k; mbfl_convert_filter_copy(encoder_tmp, encoder); mbfl_convert_filter_copy(decoder_tmp, decoder); mbfl_convert_filter_flush(encoder); mbfl_convert_filter_flush(decoder); } result = mbfl_memory_device_result(&device, result); mbfl_convert_filter_delete(encoder); mbfl_convert_filter_delete(encoder_tmp); mbfl_convert_filter_delete(decoder); mbfl_convert_filter_delete(decoder_tmp); } return result;}/* * strwidth */static int is_fullwidth(int c){ int i; if (c < mbfl_eaw_table[0].begin) { return 0; } for (i = 0; i < sizeof(mbfl_eaw_table) / sizeof(mbfl_eaw_table[0]); i++) { if (mbfl_eaw_table[i].begin <= c && c <= mbfl_eaw_table[i].end) { return 1; } } return 0;}static intfilter_count_width(int c, void* data){ (*(int *)data) += (is_fullwidth(c) ? 2: 1); return c;}intmbfl_strwidth(mbfl_string *string){ int len, n; unsigned char *p; mbfl_convert_filter *filter; len = 0; if (string->len > 0 && string->val != NULL) { /* wchar filter */ filter = mbfl_convert_filter_new( string->no_encoding, mbfl_no_encoding_wchar, filter_count_width, 0, &len); if (filter == NULL) { mbfl_convert_filter_delete(filter); return -1; } /* feed data */ p = string->val; n = string->len; while (n > 0) { (*filter->filter_function)(*p++, filter); n--; } mbfl_convert_filter_flush(filter); mbfl_convert_filter_delete(filter); } return len;}/* * strimwidth */struct collector_strimwidth_data { mbfl_convert_filter *decoder; mbfl_convert_filter *decoder_backup; mbfl_memory_device device; int from; int width; int outwidth; int outchar; int status; int endpos;};static intcollector_strimwidth(int c, void* data){ struct collector_strimwidth_data *pc = (struct collector_strimwidth_data*)data; switch (pc->status) { case 10: (*pc->decoder->filter_function)(c, pc->decoder); break; default: if (pc->outchar >= pc->from) { pc->outwidth += (is_fullwidth(c) ? 2: 1); if (pc->outwidth > pc->width) { if (pc->status == 0) { pc->endpos = pc->device.pos; mbfl_convert_filter_copy(pc->decoder, pc->decoder_backup); } pc->status++; (*pc->decoder->filter_function)(c, pc->decoder); c = -1; } else { (*pc->decoder->filter_function)(c, pc->decoder); } } pc->outchar++; break; } return c;}mbfl_string *mbfl_strimwidth( mbfl_string *string, mbfl_string *marker, mbfl_string *result, int from, int width){ struct collector_strimwidth_data pc; mbfl_convert_filter *encoder; int n, mkwidth; unsigned char *p; if (string == NULL || result == NULL) { return NULL; } mbfl_string_init(result); result->no_language = string->no_language; result->no_encoding = string->no_encoding; mbfl_memory_device_init(&pc.device, width, 0); /* output code filter */ pc.decoder = mbfl_convert_filter_new( mbfl_no_encoding_wchar, string->no_encoding, mbfl_memory_device_output, 0, &pc.device); pc.decoder_backup = mbfl_convert_filter_new( mbfl_no_encoding_wchar, string->no_encoding, mbfl_memory_device_output, 0, &pc.device); /* wchar filter */ encoder = mbfl_convert_filter_new( string->no_encoding, mbfl_no_encoding_wchar, collector_strimwidth, 0, &pc); if (pc.decoder == NULL || pc.decoder_backup == NULL || encoder == NULL) { mbfl_convert_filter_delete(encoder); mbfl_convert_filter_delete(pc.decoder); mbfl_convert_filter_delete(pc.decoder_backup); return NULL; } mkwidth = 0; if (marker) { mkwidth = mbfl_strwidth(marker);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -