1 /*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "../include/utf16reader.h"
18
19 namespace ime_pinyin {
20
21 #define MIN_BUF_LEN 128
22 #define MAX_BUF_LEN 65535
23
Utf16Reader()24 Utf16Reader::Utf16Reader() {
25 fp_ = NULL;
26 buffer_ = NULL;
27 buffer_total_len_ = 0;
28 buffer_next_pos_ = 0;
29 buffer_valid_len_ = 0;
30 }
31
~Utf16Reader()32 Utf16Reader::~Utf16Reader() {
33 if (NULL != fp_)
34 fclose(fp_);
35
36 if (NULL != buffer_)
37 delete [] buffer_;
38 }
39
40
open(const char * filename,size_t buffer_len)41 bool Utf16Reader::open(const char* filename, size_t buffer_len) {
42 if (filename == NULL)
43 return false;
44
45 if (buffer_len < MIN_BUF_LEN)
46 buffer_len = MIN_BUF_LEN;
47 else if (buffer_len > MAX_BUF_LEN)
48 buffer_len = MAX_BUF_LEN;
49
50 buffer_total_len_ = buffer_len;
51
52 if (NULL != buffer_)
53 delete [] buffer_;
54 buffer_ = new char16[buffer_total_len_];
55 if (NULL == buffer_)
56 return false;
57
58 if ((fp_ = fopen(filename, "rb")) == NULL)
59 return false;
60
61 // the UTF16 file header, skip
62 char16 header;
63 if (fread(&header, sizeof(header), 1, fp_) != 1 || header != 0xfeff) {
64 fclose(fp_);
65 fp_ = NULL;
66 return false;
67 }
68
69 return true;
70 }
71
readline(char16 * read_buf,size_t max_len)72 char16* Utf16Reader::readline(char16* read_buf, size_t max_len) {
73 if (NULL == fp_ || NULL == read_buf || 0 == max_len)
74 return NULL;
75
76 size_t ret_len = 0;
77
78 do {
79 if (buffer_valid_len_ == 0) {
80 buffer_next_pos_ = 0;
81 buffer_valid_len_ = fread(buffer_, sizeof(char16),
82 buffer_total_len_, fp_);
83 if (buffer_valid_len_ == 0) {
84 if (0 == ret_len)
85 return NULL;
86 read_buf[ret_len] = (char16)'\0';
87 return read_buf;
88 }
89 }
90
91 for (size_t i = 0; i < buffer_valid_len_; i++) {
92 if (i == max_len - 1 ||
93 buffer_[buffer_next_pos_ + i] == (char16)'\n') {
94 if (ret_len + i > 0 && read_buf[ret_len + i - 1] == (char16)'\r') {
95 read_buf[ret_len + i - 1] = (char16)'\0';
96 } else {
97 read_buf[ret_len + i] = (char16)'\0';
98 }
99
100 i++;
101 buffer_next_pos_ += i;
102 buffer_valid_len_ -= i;
103 if (buffer_next_pos_ == buffer_total_len_) {
104 buffer_next_pos_ = 0;
105 buffer_valid_len_ = 0;
106 }
107 return read_buf;
108 } else {
109 read_buf[ret_len + i] = buffer_[buffer_next_pos_ + i];
110 }
111 }
112
113 ret_len += buffer_valid_len_;
114 buffer_valid_len_ = 0;
115 } while (true);
116
117 // Never reach here
118 return NULL;
119 }
120
close()121 bool Utf16Reader::close() {
122 if (NULL != fp_)
123 fclose(fp_);
124 fp_ = NULL;
125
126 if (NULL != buffer_)
127 delete [] buffer_;
128 buffer_ = NULL;
129 return true;
130 }
131 } // namespace ime_pinyin
132