• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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