📄 mbfilter.c
字号:
/* * charset=UTF-8 * vim600: encoding=utf-8 *//* * "streamable kanji code filter and converter" * * Copyright (c) 1998,1999,2000,2001 HappySize, Inc. All rights reserved. * * This software is released under the GNU Lesser General Public License. * (Version 2.1, February 1999) * Please read the following detail of the licence (in japanese). * * ◆使用許諾条件◆ * * このソフトウェアは株式会社ハッピーサイズによって開発されました。株式会社ハッ * ピーサイズは、著作権法および万国著作権条約の定めにより、このソフトウェアに関 * するすべての権利を留保する権利を持ち、ここに行使します。株式会社ハッピーサイ * ズは以下に明記した条件に従って、このソフトウェアを使用する排他的ではない権利 * をお客様に許諾します。何人たりとも、以下の条件に反してこのソフトウェアを使用 * することはできません。 * * このソフトウェアを「GNU Lesser General Public License (Version 2.1, February * 1999)」に示された条件で使用することを、全ての方に許諾します。「GNU Lesser * General Public License」を満たさない使用には、株式会社ハッピーサイズから書面 * による許諾を得る必要があります。 * * 「GNU Lesser General Public License」の全文は以下のウェブページから取得でき * ます。「GNU Lesser General Public License」とは、これまでLibrary General * Public Licenseと呼ばれていたものです。 * http://www.gnu.org/ --- GNUウェブサイト * http://www.gnu.org/copyleft/lesser.html --- ライセンス文面 * このライセンスの内容がわからない方、守れない方には使用を許諾しません。 * * しかしながら、当社とGNUプロジェクトとの特定の関係を示唆または主張するもので * はありません。 * * ◆保証内容◆ * * このソフトウェアは、期待された動作・機能・性能を持つことを目標として設計され * 開発されていますが、これを保証するものではありません。このソフトウェアは「こ * のまま」の状態で提供されており、たとえばこのソフトウェアの有用性ないし特定の * 目的に合致することといった、何らかの保証内容が、明示されたり暗黙に示されてい * る場合であっても、その保証は無効です。このソフトウェアを使用した結果ないし使 * 用しなかった結果によって、直接あるいは間接に受けた身体的な傷害、財産上の損害 * 、データの損失あるいはその他の全ての損害については、その損害の可能性が使用者 * 、当社あるいは第三者によって警告されていた場合であっても、当社はその損害の賠 * 償および補填を行いません。この規定は他の全ての、書面上または書面に無い保証・ * 契約・規定に優先します。 * * ◆著作権者の連絡先および使用条件についての問い合わせ先◆ * * 〒102-0073 * 東京都千代田区九段北1-13-5日本地所第一ビル4F * 株式会社ハッピーサイズ * Phone: 03-3512-3655, Fax: 03-3512-3656 * Email: sales@happysize.co.jp * Web: http://happysize.com/ * * ◆著者◆ * * 金本 茂 <sgk@happysize.co.jp> * * ◆履歴◆ * * 1998/11/10 sgk implementation in C++ * 1999/4/25 sgk Cで書きなおし。 * 1999/4/26 sgk 入力フィルタを実装。漢字コードを推定しながらフィルタを追加。 * 1999/6/?? Unicodeサポート。 * 1999/6/22 sgk ライセンスをLGPLに変更。 * *//* * Unicode support * * Portions copyright (c) 1999,2000,2001 by the PHP3 internationalization team. * All rights reserved. * */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stddef.h>#ifdef HAVE_STRING_H#include <string.h>#endif#ifdef HAVE_STRINGS_H#include <strings.h>#endif#ifdef HAVE_STDDEF_H#include <stddef.h>#endif#include "mbfilter.h"#include "mbfl_filter_output.h"#include "mbfilter_pass.h"#include "eaw_table.h"/* hex character table "0123456789ABCDEF" */static char mbfl_hexchar_table[] = { 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46};/* * encoding filter */#define CK(statement) do { if ((statement) < 0) return (-1); } while (0)/* * buffering converter */mbfl_buffer_converter *mbfl_buffer_converter_new( enum mbfl_no_encoding from, enum mbfl_no_encoding to, int buf_initsz){ mbfl_buffer_converter *convd; /* allocate */ convd = (mbfl_buffer_converter*)mbfl_malloc(sizeof (mbfl_buffer_converter)); if (convd == NULL) { return NULL; } /* initialize */ convd->from = mbfl_no2encoding(from); convd->to = mbfl_no2encoding(to); if (convd->from == NULL) { convd->from = &mbfl_encoding_pass; } if (convd->to == NULL) { convd->to = &mbfl_encoding_pass; } /* create convert filter */ convd->filter1 = NULL; convd->filter2 = NULL; if (mbfl_convert_filter_get_vtbl(convd->from->no_encoding, convd->to->no_encoding) != NULL) { convd->filter1 = mbfl_convert_filter_new(convd->from->no_encoding, convd->to->no_encoding, mbfl_memory_device_output, 0, &convd->device); } else { convd->filter2 = mbfl_convert_filter_new(mbfl_no_encoding_wchar, convd->to->no_encoding, mbfl_memory_device_output, 0, &convd->device); if (convd->filter2 != NULL) { convd->filter1 = mbfl_convert_filter_new(convd->from->no_encoding, mbfl_no_encoding_wchar, (int (*)(int, void*))convd->filter2->filter_function, NULL, convd->filter2); if (convd->filter1 == NULL) { mbfl_convert_filter_delete(convd->filter2); } } } if (convd->filter1 == NULL) { return NULL; } mbfl_memory_device_init(&convd->device, buf_initsz, buf_initsz/4); return convd;}voidmbfl_buffer_converter_delete(mbfl_buffer_converter *convd){ if (convd != NULL) { if (convd->filter1) { mbfl_convert_filter_delete(convd->filter1); } if (convd->filter2) { mbfl_convert_filter_delete(convd->filter2); } mbfl_memory_device_clear(&convd->device); mbfl_free((void*)convd); }}voidmbfl_buffer_converter_reset(mbfl_buffer_converter *convd){ mbfl_memory_device_reset(&convd->device);}intmbfl_buffer_converter_illegal_mode(mbfl_buffer_converter *convd, int mode){ if (convd != NULL) { if (convd->filter2 != NULL) { convd->filter2->illegal_mode = mode; } else if (convd->filter1 != NULL) { convd->filter1->illegal_mode = mode; } else { return 0; } } return 1;}intmbfl_buffer_converter_illegal_substchar(mbfl_buffer_converter *convd, int substchar){ if (convd != NULL) { if (convd->filter2 != NULL) { convd->filter2->illegal_substchar = substchar; } else if (convd->filter1 != NULL) { convd->filter1->illegal_substchar = substchar; } else { return 0; } } return 1;}intmbfl_buffer_converter_strncat(mbfl_buffer_converter *convd, const unsigned char *p, int n){ mbfl_convert_filter *filter; int (*filter_function)(int c, mbfl_convert_filter *filter); if (convd != NULL && p != NULL) { filter = convd->filter1; if (filter != NULL) { filter_function = filter->filter_function; while (n > 0) { if ((*filter_function)(*p++, filter) < 0) { break; } n--; } } } return n;}intmbfl_buffer_converter_feed(mbfl_buffer_converter *convd, mbfl_string *string){ int n; unsigned char *p; mbfl_convert_filter *filter; int (*filter_function)(int c, mbfl_convert_filter *filter); if (convd == NULL || string == NULL) { return -1; } mbfl_memory_device_realloc(&convd->device, convd->device.pos + string->len, string->len/4); /* feed data */ n = string->len; p = string->val; filter = convd->filter1; if (filter != NULL) { filter_function = filter->filter_function; while (n > 0) { if ((*filter_function)(*p++, filter) < 0) { return -1; } n--; } } return 0;}intmbfl_buffer_converter_flush(mbfl_buffer_converter *convd){ if (convd == NULL) { return -1; } if (convd->filter1 != NULL) { mbfl_convert_filter_flush(convd->filter1); } if (convd->filter2 != NULL) { mbfl_convert_filter_flush(convd->filter2); } return 0;}mbfl_string *mbfl_buffer_converter_getbuffer(mbfl_buffer_converter *convd, mbfl_string *result){ if (convd != NULL && result != NULL && convd->device.buffer != NULL) { result->no_encoding = convd->to->no_encoding; result->val = convd->device.buffer; result->len = convd->device.pos; } else { result = NULL; } return result;}mbfl_string *mbfl_buffer_converter_result(mbfl_buffer_converter *convd, mbfl_string *result){ if (convd == NULL || result == NULL) { return NULL; } result->no_encoding = convd->to->no_encoding; return mbfl_memory_device_result(&convd->device, result);}mbfl_string *mbfl_buffer_converter_feed_result(mbfl_buffer_converter *convd, mbfl_string *string, mbfl_string *result){ if (convd == NULL || string == NULL || result == NULL) { return NULL; } mbfl_buffer_converter_feed(convd, string); if (convd->filter1 != NULL) { mbfl_convert_filter_flush(convd->filter1); } if (convd->filter2 != NULL) { mbfl_convert_filter_flush(convd->filter2); } result->no_encoding = convd->to->no_encoding; return mbfl_memory_device_result(&convd->device, result);}int mbfl_buffer_illegalchars(mbfl_buffer_converter *convd){ int num_illegalchars = 0; if (convd == NULL) { return 0; } if (convd->filter1 != NULL) { num_illegalchars += convd->filter1->num_illegalchar; } if (convd->filter2 != NULL) { num_illegalchars += convd->filter2->num_illegalchar; } return (num_illegalchars);}/* * encoding detector */mbfl_encoding_detector *mbfl_encoding_detector_new(enum mbfl_no_encoding *elist, int elistsz, int strict){ mbfl_encoding_detector *identd; int i, num; mbfl_identify_filter *filter; if (elist == NULL || elistsz <= 0) { return NULL; } /* allocate */ identd = (mbfl_encoding_detector*)mbfl_malloc(sizeof(mbfl_encoding_detector)); if (identd == NULL) { return NULL; } identd->filter_list = (mbfl_identify_filter **)mbfl_calloc(elistsz, sizeof(mbfl_identify_filter *)); if (identd->filter_list == NULL) { mbfl_free(identd); return NULL; } /* create filters */ i = 0; num = 0; while (i < elistsz) { filter = mbfl_identify_filter_new(elist[i]); if (filter != NULL) { identd->filter_list[num] = filter; num++; } i++; } identd->filter_list_size = num; /* set strict flag */ identd->strict = strict; return identd;}voidmbfl_encoding_detector_delete(mbfl_encoding_detector *identd){ int i; if (identd != NULL) { if (identd->filter_list != NULL) { i = identd->filter_list_size; while (i > 0) { i--; mbfl_identify_filter_delete(identd->filter_list[i]); } mbfl_free((void *)identd->filter_list); } mbfl_free((void *)identd); }}intmbfl_encoding_detector_feed(mbfl_encoding_detector *identd, mbfl_string *string){ int i, n, num, bad, res; unsigned char *p; mbfl_identify_filter *filter; res = 0; /* feed data */ if (identd != NULL && string != NULL && string->val != NULL) { num = identd->filter_list_size; n = string->len; p = string->val; bad = 0; while (n > 0) { for (i = 0; i < num; i++) { filter = identd->filter_list[i]; if (!filter->flag) { (*filter->filter_function)(*p, filter); if (filter->flag) { bad++; } } } if ((num - 1) <= bad) { res = 1; break; } p++; n--; } } return res;}enum mbfl_no_encoding mbfl_encoding_detector_judge(mbfl_encoding_detector *identd){ mbfl_identify_filter *filter; enum mbfl_no_encoding encoding; int n; /* judge */ encoding = mbfl_no_encoding_invalid; if (identd != NULL) { n = identd->filter_list_size - 1; while (n >= 0) { filter = identd->filter_list[n]; if (!filter->flag) { if (identd->strict && filter->status) { continue; } encoding = filter->encoding->no_encoding; } n--; } /* fallback judge */ if (encoding == mbfl_no_encoding_invalid) { n = identd->filter_list_size - 1; while (n >= 0) { filter = identd->filter_list[n]; if (!filter->flag) { encoding = filter->encoding->no_encoding; } n--; } } } return encoding;}/* * encoding converter */mbfl_string *mbfl_convert_encoding( mbfl_string *string, mbfl_string *result, enum mbfl_no_encoding toenc){ int n; unsigned char *p; const mbfl_encoding *encoding; mbfl_memory_device device; mbfl_convert_filter *filter1; mbfl_convert_filter *filter2; /* initialize */ encoding = mbfl_no2encoding(toenc); if (encoding == NULL || string == NULL || result == NULL) { return NULL; } filter1 = NULL; filter2 = NULL; if (mbfl_convert_filter_get_vtbl(string->no_encoding, toenc) != NULL) { filter1 = mbfl_convert_filter_new(string->no_encoding, toenc, mbfl_memory_device_output, 0, &device); } else { filter2 = mbfl_convert_filter_new(mbfl_no_encoding_wchar, toenc, mbfl_memory_device_output, 0, &device);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -