C/Migemo 1.4
charset.h
[詳解]
1// vim:set ts=8 sts=4 sw=4 tw=0 et:
2//
3// charset.h -
4//
5// Written By: MURAOKA Taro <koron.kaoriya@gmail.com>
6
7#pragma once
8
9enum {
14};
15
16// The maximum number of bytes into which a single code point can be expanded.
17#define CHARSET_MAX_BYTES 6
18
19typedef int (*charset_proc_char2int)(const unsigned char *, unsigned int *);
20typedef int (*charset_proc_int2char)(unsigned int, unsigned char *);
21#define CHARSET_PROC_CHAR2INT charset_proc_char2int
22#define CHARSET_PROC_INT2CHAR charset_proc_int2char
23
24extern const unsigned char CHARSET_UTF8_LUT[128];
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30int charset_none_int2char(unsigned int in, unsigned char *out);
31
32int charset_cp932_char2int(const unsigned char *in, unsigned int *out);
33int charset_cp932_int2char(unsigned int in, unsigned char *out);
34int charset_eucjp_char2int(const unsigned char *in, unsigned int *out);
35int charset_eucjp_int2char(unsigned int in, unsigned char *out);
36int charset_utf8_char2int(const unsigned char *in, unsigned int *out);
37int charset_utf8_int2char(unsigned int in, unsigned char *out);
38
39int charset_detect_file(const char *path);
40void charset_getproc(int charset, CHARSET_PROC_CHAR2INT *char2int,
41 CHARSET_PROC_INT2CHAR *int2char);
42
43#ifdef __cplusplus
44}
45#endif
46
47static inline int
48charset_none_char2int(const unsigned char *in, unsigned int *out)
49{
50 if (out)
51 *out = *in;
52 return 1;
53}
54
55static inline int
56charset_utf8_char2int_inner(const unsigned char *in, unsigned int *out)
57{
58 if (!(in[0] & 0x80))
59 return charset_none_char2int(in, out);
60
61 int len = CHARSET_UTF8_LUT[in[0] - 128];
62 if (!len)
63 // Output an invalid byte as-is.
64 return charset_none_char2int(in, out);
65
66 unsigned int code = in[0] & (0xff >> len);
67 for (int i = 1; i < len; ++i)
68 {
69 // check invalid byte.
70 if ((in[i] & 0xc0) != 0x80)
71 // Output an invalid byte as-is.
72 return charset_none_char2int(in, out);
73 code <<= 6;
74 code += in[i] & 0x3f;
75 }
76 if (out)
77 *out = code;
78 return len;
79}
80
81static inline unsigned int
82charset_decode(CHARSET_PROC_CHAR2INT proc, const unsigned char **pptr)
83{
84 unsigned int code = 0;
85 *pptr += proc ? proc(*pptr, &code)
86 : charset_utf8_char2int_inner(*pptr, &code);
87 return code;
88}
89
90static inline CHARSET_PROC_CHAR2INT
91charset_regulate_char2int(CHARSET_PROC_CHAR2INT proc)
92{
93 return proc && proc != charset_utf8_char2int ? proc : NULL;
94}
int charset_utf8_char2int(const unsigned char *in, unsigned int *out)
Definition charset.c:120
const unsigned char CHARSET_UTF8_LUT[128]
Definition charset.c:97
void charset_getproc(int charset, CHARSET_PROC_CHAR2INT *char2int, CHARSET_PROC_INT2CHAR *int2char)
Definition charset.c:255
int charset_cp932_char2int(const unsigned char *in, unsigned int *out)
Definition charset.c:25
int charset_eucjp_int2char(unsigned int in, unsigned char *out)
Definition charset.c:78
#define CHARSET_PROC_CHAR2INT
Definition charset.h:21
@ CHARSET_EUCJP
Definition charset.h:12
@ CHARSET_UTF8
Definition charset.h:13
@ CHARSET_NONE
Definition charset.h:10
@ CHARSET_CP932
Definition charset.h:11
int charset_none_int2char(unsigned int in, unsigned char *out)
Definition charset.c:17
int(* charset_proc_char2int)(const unsigned char *, unsigned int *)
Definition charset.h:19
int(* charset_proc_int2char)(unsigned int, unsigned char *)
Definition charset.h:20
int charset_utf8_char2int(const unsigned char *in, unsigned int *out)
Definition charset.c:120
int charset_eucjp_char2int(const unsigned char *in, unsigned int *out)
Definition charset.c:61
#define CHARSET_PROC_INT2CHAR
Definition charset.h:22
int charset_utf8_int2char(unsigned int in, unsigned char *out)
Definition charset.c:126
int charset_detect_file(const char *path)
Definition charset.c:286
int charset_cp932_int2char(unsigned int in, unsigned char *out)
Definition charset.c:42