132 lines
3.1 KiB
C++
132 lines
3.1 KiB
C++
|
/*
|
||
|
* 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 "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
|