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 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 32 Utf16Reader::~Utf16Reader() { 33 if (NULL != fp_) 34 fclose(fp_); 35 36 if (NULL != buffer_) 37 delete [] buffer_; 38 } 39 40 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 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 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