OSDN Git Service

s
[simplecms/utakata.git] / utf8.h
1 #ifndef _UTF8_H_
2 #define _UTF8_H_
3
4 #include <iostream>
5 #include <string>
6 #include <vector>
7 #include <exception>
8
9 #include "smart_ptr.h"
10 #include "InputStream.h"
11
12 namespace utakata {
13
14     namespace utf8 {
15
16         // inputstreamの準備が出来ていない場合に送出される例外
17         class StreamException : public std::exception
18         {
19         public:
20             StreamException(const std::string& str) : str_(str) {}
21             virtual ~StreamException() throw() {}
22
23             const char* what() throw() {
24                 return str_.c_str();
25             }
26         private:
27
28             std::string str_;
29         };
30
31         class UTF8InputStream : public IInputStream
32         {
33             /**
34                入力ストリームから、UTF-8のデータを指定した文字だけ読みだして
35                返す。
36             */
37
38             const unsigned char EOF_;
39             
40         public:
41             
42             // 入力に利用するストリームは最初に渡される。
43             // 最初に渡さない場合には、後から開けるようにしておかなけりゃならない。
44             UTF8InputStream();
45             UTF8InputStream(smart_ptr<std::istream> strm);
46             virtual ~UTF8InputStream(){}
47
48             bool open(smart_ptr<std::istream> strm);
49
50             std::vector<unsigned char> read();
51             std::vector<unsigned char> read(int num);
52
53             std::vector<unsigned char> peek();
54             std::vector<unsigned char> peek(int num);
55
56             // 読み出した文字数を返す。
57             size_t pos() const {return pos_;}
58
59             // 渡したvectorをストリームに戻す。vectorは、readで取得した
60             // データの並びでなければならない。つまり、read()した
61             // データを戻す際に利用する。
62             void unget(const std::vector<unsigned char>& ch);
63
64             // ファイルの終端に到達しているかどうかを返す。
65             // trueを返す場合、readの結果は常にEOF文字を返す。
66             bool isEOF() const;
67             
68         private:
69
70             smart_ptr<std::istream> strm_;
71             size_t pos_;
72         };
73
74
75         // UTF-8のコードを表すバイト列をUTF-8のコードに変換する。
76         long generateUTF8Code(const std::vector<unsigned char>& code);
77         long generateUTF8Code(const std::string& ch);
78         
79         struct CheckUTF8Byte
80         {
81             // UTF8の先頭バイト以外であるかどうかをチェックする。
82             const unsigned char checker;
83             bool good;
84             CheckUTF8Byte() : checker(0x2), good(true) {}
85
86             template<class T>
87             void operator()(const T& t) {
88                 // 先頭ビットが10ではない場合、チェックに失敗する。
89                 T tmp = t >> 6;
90                 if ( ((tmp & 0x3)) != checker) {
91                     good = false;
92                 }
93             }
94         };
95
96         struct PutBack
97         {
98             // 渡されたデータをistreamにputbackする。
99             smart_ptr<std::istream> strm_;
100             PutBack(smart_ptr<std::istream> strm) : strm_(strm) {}
101
102             template<class T>
103             void operator()(T t)
104                 {
105                     strm_->putback(t);
106                 }
107         };
108         
109         // 与えられたバイト列の先頭から、UTF8一文字に該当しているかどうかを返す。
110         // バイト列がUTF8に該当する場合、そのバイト列のサイズを返す。
111         bool is_utf8_one(const std::vector<unsigned char>& bytes, size_t& size);
112
113         // 与えられたバイト列全てが、UTF8に該当しているかどうかを返す。
114         bool is_utf8_all(const std::vector<unsigned char>& bytes);
115
116         // UTF-8の先頭バイトとして正しいフォーマットであるかどうか。
117         // 正しいフォーマットである場合、渡したバイトを含めた、一文字である
118         // バイト数を返す。
119         bool is_utf8_first_byte(unsigned char c, size_t& size);
120
121         // 渡したバイト列が、0-9で判別される数値文字と一致するかどうかを返す。
122         // is_asciiのサブセットを判別するものである。
123         bool is_utf8_numeric(const std::vector<unsigned char>& bytes);
124
125         // 渡したバイト列が、a-zA-Zの領域であるかどうかを調べる。
126         // is_asciiのサブセットを判別するものである。
127         bool is_utf8_alpha(const std::vector<unsigned char>& bytes);
128
129         // 渡したバイト列が、0x00〜0x7fの領域であるかどうかを返す。
130         // is_utf8_alpha, is_utf8_numericのスーパーセットとなる。
131         bool is_utf8_ascii(const std::vector<unsigned char>& bytes);
132     };
133 }
134
135 #endif /* _UTF8_H_ */