Home | History | Annotate | Download | only in share
      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