/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "../include/utf16reader.h"
namespace ime_pinyin {
#define MIN_BUF_LEN 128
#define MAX_BUF_LEN 65535
Utf16Reader::Utf16Reader() {
fp_ = NULL;
buffer_ = NULL;
buffer_total_len_ = 0;
buffer_next_pos_ = 0;
buffer_valid_len_ = 0;
}
Utf16Reader::~Utf16Reader() {
if (NULL != fp_)
fclose(fp_);
if (NULL != buffer_)
delete [] buffer_;
}
bool Utf16Reader::open(const char* filename, size_t buffer_len) {
if (filename == NULL)
return false;
if (buffer_len < MIN_BUF_LEN)
buffer_len = MIN_BUF_LEN;
else if (buffer_len > MAX_BUF_LEN)
buffer_len = MAX_BUF_LEN;
buffer_total_len_ = buffer_len;
if (NULL != buffer_)
delete [] buffer_;
buffer_ = new char16[buffer_total_len_];
if (NULL == buffer_)
return false;
if ((fp_ = fopen(filename, "rb")) == NULL)
return false;
// the UTF16 file header, skip
char16 header;
if (fread(&header, sizeof(header), 1, fp_) != 1 || header != 0xfeff) {
fclose(fp_);
fp_ = NULL;
return false;
}
return true;
}
char16* Utf16Reader::readline(char16* read_buf, size_t max_len) {
if (NULL == fp_ || NULL == read_buf || 0 == max_len)
return NULL;
size_t ret_len = 0;
do {
if (buffer_valid_len_ == 0) {
buffer_next_pos_ = 0;
buffer_valid_len_ = fread(buffer_, sizeof(char16),
buffer_total_len_, fp_);
if (buffer_valid_len_ == 0) {
if (0 == ret_len)
return NULL;
read_buf[ret_len] = (char16)'\0';
return read_buf;
}
}
for (size_t i = 0; i < buffer_valid_len_; i++) {
if (i == max_len - 1 ||
buffer_[buffer_next_pos_ + i] == (char16)'\n') {
if (ret_len + i > 0 && read_buf[ret_len + i - 1] == (char16)'\r') {
read_buf[ret_len + i - 1] = (char16)'\0';
} else {
read_buf[ret_len + i] = (char16)'\0';
}
i++;
buffer_next_pos_ += i;
buffer_valid_len_ -= i;
if (buffer_next_pos_ == buffer_total_len_) {
buffer_next_pos_ = 0;
buffer_valid_len_ = 0;
}
return read_buf;
} else {
read_buf[ret_len + i] = buffer_[buffer_next_pos_ + i];
}
}
ret_len += buffer_valid_len_;
buffer_valid_len_ = 0;
} while (true);
// Never reach here
return NULL;
}
bool Utf16Reader::close() {
if (NULL != fp_)
fclose(fp_);
fp_ = NULL;
if (NULL != buffer_)
delete [] buffer_;
buffer_ = NULL;
return true;
}
} // namespace ime_pinyin