/src/im/gpinyin/share/utf16reader.cpp

http://ftk.googlecode.com/ · C++ · 131 lines · 91 code · 23 blank · 17 comment · 47 complexity · 5a1d117f5f8178be26ed4bd27167c4cb MD5 · raw file

  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. #include "../include/utf16reader.h"
  17. namespace ime_pinyin {
  18. #define MIN_BUF_LEN 128
  19. #define MAX_BUF_LEN 65535
  20. Utf16Reader::Utf16Reader() {
  21. fp_ = NULL;
  22. buffer_ = NULL;
  23. buffer_total_len_ = 0;
  24. buffer_next_pos_ = 0;
  25. buffer_valid_len_ = 0;
  26. }
  27. Utf16Reader::~Utf16Reader() {
  28. if (NULL != fp_)
  29. fclose(fp_);
  30. if (NULL != buffer_)
  31. delete [] buffer_;
  32. }
  33. bool Utf16Reader::open(const char* filename, unsigned buffer_len) {
  34. if (filename == NULL)
  35. return false;
  36. if (buffer_len < MIN_BUF_LEN)
  37. buffer_len = MIN_BUF_LEN;
  38. else if (buffer_len > MAX_BUF_LEN)
  39. buffer_len = MAX_BUF_LEN;
  40. buffer_total_len_ = buffer_len;
  41. if (NULL != buffer_)
  42. delete [] buffer_;
  43. buffer_ = new char16[buffer_total_len_];
  44. if (NULL == buffer_)
  45. return false;
  46. if ((fp_ = fopen(filename, "rb")) == NULL)
  47. return false;
  48. // the UTF16 file header, skip
  49. char16 header;
  50. if (fread(&header, sizeof(header), 1, fp_) != 1 || header != 0xfeff) {
  51. fclose(fp_);
  52. fp_ = NULL;
  53. return false;
  54. }
  55. return true;
  56. }
  57. char16* Utf16Reader::readline(char16* read_buf, unsigned max_len) {
  58. if (NULL == fp_ || NULL == read_buf || 0 == max_len)
  59. return NULL;
  60. unsigned ret_len = 0;
  61. do {
  62. if (buffer_valid_len_ == 0) {
  63. buffer_next_pos_ = 0;
  64. buffer_valid_len_ = fread(buffer_, sizeof(char16),
  65. buffer_total_len_, fp_);
  66. if (buffer_valid_len_ == 0) {
  67. if (0 == ret_len)
  68. return NULL;
  69. read_buf[ret_len] = (char16)'\0';
  70. return read_buf;
  71. }
  72. }
  73. for (unsigned i = 0; i < buffer_valid_len_; i++) {
  74. if (i == max_len - 1 ||
  75. buffer_[buffer_next_pos_ + i] == (char16)'\n') {
  76. if (ret_len + i > 0 && read_buf[ret_len + i - 1] == (char16)'\r') {
  77. read_buf[ret_len + i - 1] = (char16)'\0';
  78. } else {
  79. read_buf[ret_len + i] = (char16)'\0';
  80. }
  81. i++;
  82. buffer_next_pos_ += i;
  83. buffer_valid_len_ -= i;
  84. if (buffer_next_pos_ == buffer_total_len_) {
  85. buffer_next_pos_ = 0;
  86. buffer_valid_len_ = 0;
  87. }
  88. return read_buf;
  89. } else {
  90. read_buf[ret_len + i] = buffer_[buffer_next_pos_ + i];
  91. }
  92. }
  93. ret_len += buffer_valid_len_;
  94. buffer_valid_len_ = 0;
  95. } while (true);
  96. // Never reach here
  97. return NULL;
  98. }
  99. bool Utf16Reader::close() {
  100. if (NULL != fp_)
  101. fclose(fp_);
  102. fp_ = NULL;
  103. if (NULL != buffer_)
  104. delete [] buffer_;
  105. buffer_ = NULL;
  106. return true;
  107. }
  108. } // namespace ime_pinyin