TextReader.pm
上传用户:market2
上传日期:2018-11-18
资源大小:18786k
文件大小:3k
源码类别:

外挂编程

开发平台:

Windows_Unix

  1. #########################################################################
  2. #  OpenKore - UTF-8 text reader
  3. #
  4. #  Copryight (c) 2006 OpenKore Development Team
  5. #
  6. #  This software is open source, licensed under the GNU General Public
  7. #  License, version 2.
  8. #  Basically, this means that you're allowed to modify and distribute
  9. #  this software. However, if you distribute modified versions, you MUST
  10. #  also distribute the source code.
  11. #  See http://www.gnu.org/licenses/gpl.html for the full license.
  12. #########################################################################
  13. ##
  14. # MODULE DESCRIPTION: UTF-8 text reader.
  15. #
  16. # A convenience class for reading text files encoded in UTF-8. If you're
  17. # not familiar with UTF-8, Unicode or character encoding in general, then you
  18. # should read <a href="http://www.joelonsoftware.com/articles/Unicode.html">this article
  19. # by Joel on Software</a>.
  20. #
  21. # If the text file is not valid UTF-8, then it will assume that the text file
  22. # is in the system's default encoding. If that isn't correct either, then an
  23. # exception will be thrown during reading.
  24. #
  25. # This class is to be used as follows:
  26. # <pre class="example">
  27. # use Utils::TextReader;
  28. #
  29. # my $reader = new Utils::TextReader("file.txt");
  30. # while (!$reader->eof()) {
  31. #    print $reader->readLine();
  32. # }
  33. # </pre>
  34. package Utils::TextReader;
  35. use strict;
  36. use Encode;
  37. use Utils::Exceptions;
  38. my $supportsAutoConversion;
  39. eval {
  40. $supportsAutoConversion = 0;
  41. require Translation;
  42. require Encode;
  43. $supportsAutoConversion = defined(&Translation::getLocaleCharset);
  44. };
  45. ##
  46. # Utils::TextReader->new(String filename)
  47. # Throws: FileNotFoundException, IOException
  48. #
  49. # Create a new TextReader and open the given file for reading.
  50. sub new {
  51. my ($class, $file) = @_;
  52. my %self;
  53. if (! -e $file) {
  54. FileNotFoundException->throw("File does not exist.");
  55. } elsif (!open($self{handle}, "<", $file)) {
  56. IOException->throw(error => $!);
  57. }
  58. $self{file} = $file;
  59. $self{line} = 1;
  60. return bless %self, $class;
  61. }
  62. sub DESTROY {
  63. close($_[0]->{handle});
  64. }
  65. ##
  66. # boolean $TextReader->eof()
  67. #
  68. # Check whether end-of-file has been reached.
  69. sub eof {
  70. return eof($_[0]->{handle});
  71. }
  72. ##
  73. # String $TextReader->readLine()
  74. # Requires: !$TextReader->eof()
  75. # Throws: UTF8MalformedException
  76. #
  77. # Read one line from the file, including a possible newline character.
  78. # UTF-8 BOM characters are automatically stripped.
  79. sub readLine {
  80. my $self = $_[0];
  81. my $handle = $self->{handle};
  82. my $line = <$handle>;
  83. # Validate UTF-8.
  84. {
  85. use bytes;
  86. if ($line !~ m/^(
  87.      [x09x0Ax0Dx20-x7E]            # ASCII
  88.    | [xC2-xDF][x80-xBF]             # non-overlong 2-byte
  89.    |  xE0[xA0-xBF][x80-xBF]        # excluding overlongs
  90.    | [xE1-xECxEExEF][x80-xBF]{2}  # straight 3-byte
  91.    |  xED[x80-x9F][x80-xBF]        # excluding surrogates
  92.    |  xF0[x90-xBF][x80-xBF]{2}     # planes 1-3
  93.    | [xF1-xF3][x80-xBF]{3}          # planes 4-15
  94.    |  xF4[x80-x8F][x80-xBF]{2}     # plane 16
  95.   )*$/x) {
  96. if ($supportsAutoConversion) {
  97. eval {
  98. $line = Encode::decode(Translation::getLocaleCharset(),
  99. $line, Encode::FB_CROAK);
  100. };
  101. }
  102. if (!$supportsAutoConversion || $@) {
  103. UTF8MalformedException->throw(
  104. error => "Malformed UTF-8 data at line $_[0]->{line}.",
  105. textfileline => $self->{line},
  106. textfile => $self->{file}
  107. );
  108. }
  109. }
  110. }
  111. # Convert to string and remove UTF-8 BOM characters.
  112. Encode::_utf8_on($line);
  113. $line =~ s/x{FEFF}//g;
  114. $self->{line}++;
  115. return $line;
  116. }
  117. 1;