home *** CD-ROM | disk | FTP | other *** search
/ Chip 2003 January / Chip_2003-01_cd1.bin / zkuste / delphi / unity / d56 / FNDUTL.ZIP / Unicode / cUnicodeReader.pas < prev   
Encoding:
Pascal/Delphi Source File  |  2002-10-28  |  11.9 KB  |  408 lines

  1. {$INCLUDE ..\cDefines.inc}
  2. unit cUnicodeReader;
  3.  
  4. {                                                                              }
  5. {                        Unicode Reader class v3.02                            }
  6. {                                                                              }
  7. {         This unit is copyright ⌐ 2002 by David Butler (david@e.co.za)        }
  8. {                                                                              }
  9. {                  This unit is part of Delphi Fundamentals.                   }
  10. {                Its original file name is cUnicodeReader.pas                  }
  11. {       The latest version is available from the Fundamentals home page        }
  12. {                     http://fundementals.sourceforge.net/                     }
  13. {                                                                              }
  14. {                I invite you to use this unit, free of charge.                }
  15. {        I invite you to distibute this unit, but it must be for free.         }
  16. {             I also invite you to contribute to its development,              }
  17. {             but do not distribute a modified copy of this file.              }
  18. {                                                                              }
  19. {          A forum is available on SourceForge for general discussion          }
  20. {             http://sourceforge.net/forum/forum.php?forum_id=2117             }
  21. {                                                                              }
  22. {                                                                              }
  23. { Description:                                                                 }
  24. {   Unicode reader class.                                                      }
  25. {                                                                              }
  26. { Revision history:                                                            }
  27. {   19/04/2002  0.01  Initial version                                          }
  28. {   28/10/2002  3.02  Refactored for Fundamentals 3.                           }
  29. {                                                                              }
  30.  
  31. interface
  32.  
  33. uses
  34.   // Fundamentals
  35.   cUtils,
  36.   cReaders,
  37.   cUnicodeChar,
  38.   cUnicodeCodecs,
  39.   cUnicode;
  40.  
  41.  
  42.  
  43. {                                                                              }
  44. { AUnicodeReader                                                               }
  45. {                                                                              }
  46. type
  47.   AUnicodeReader = class
  48.   protected
  49.     FReader      : AReader;
  50.     FReaderOwner : Boolean;
  51.     FCodec       : AUnicodeCodec;
  52.     FBuffer      : WideString;
  53.     FBufPos      : Integer;
  54.     FRawBuf      : Pointer;
  55.     FRawSize     : Integer;
  56.  
  57.     procedure ReadError;
  58.     function  BufferChars(const Count: Integer): Boolean;
  59.  
  60.   public
  61.     constructor Create(const Reader: AReader; const ReaderOwner: Boolean = True);
  62.     destructor Destroy; override;
  63.  
  64.     property  Codec: AUnicodeCodec read FCodec write FCodec;
  65.  
  66.     procedure Skip(const Count: Integer);
  67.     function  SkipAll(const CharMatchFunc: WideCharMatchFunction): Integer;
  68.  
  69.     function  MatchChar(const CharMatchFunc: WideCharMatchFunction;
  70.               const Skip: Boolean): Boolean; overload;
  71.     function  MatchChar(const Ch: WideChar; const Skip: Boolean): Boolean; overload;
  72.     function  MatchChar(const Ch: Char; const Skip: Boolean): Boolean; overload;
  73.     function  MatchAnsiStr(const S: String; const CaseSensitive: Boolean;
  74.               const Skip: Boolean): Boolean;
  75.     function  MatchAnsiStrDelimited(const S: String; const CaseSensitive: Boolean;
  76.               const Delimiter: WideCharMatchFunction;
  77.               const Skip: Boolean): Boolean;
  78.  
  79.     function  PeekChar: WideChar;
  80.  
  81.     function  ReadChar: WideChar;
  82.     function  ReadChars(const CharMatchFunc: WideCharMatchFunction): WideString;
  83.     function  ReadToAnsiStr(const S: String; const CaseSensitive: Boolean): WideString;
  84.     function  ReadToChar(const C: CharSet): WideString;
  85.   end;
  86.   EUnicodeReader = class(EUnicode);
  87.   EUnicodeReaderReadError = class(EUnicodeReader);
  88.  
  89.  
  90.  
  91. {                                                                              }
  92. { TUnicodeMemoryReader                                                         }
  93. {                                                                              }
  94. type
  95.   TUnicodeMemoryReader = class(AUnicodeReader)
  96.   public
  97.     constructor Create(const Data: Pointer; const Size: Integer);
  98.   end;
  99.  
  100.  
  101.  
  102. {                                                                              }
  103. { TUnicodeFileReader                                                           }
  104. {                                                                              }
  105. type
  106.   TUnicodeFileReader = class(AUnicodeReader)
  107.   public
  108.     constructor Create(const FileName: String);
  109.   end;
  110.  
  111.  
  112.  
  113. implementation
  114.  
  115. uses
  116.   // Delphi
  117.   SysUtils;
  118.  
  119.  
  120.  
  121. {                                                                              }
  122. { AUnicodeReader                                                               }
  123. {                                                                              }
  124. const
  125.   ReaderBlockSize = 1024;
  126.  
  127. constructor AUnicodeReader.Create(const Reader: AReader; const ReaderOwner: Boolean);
  128. begin
  129.   inherited Create;
  130.   FReader := Reader;
  131.   FReaderOwner := ReaderOwner;
  132.   GetMem(FRawBuf, ReaderBlockSize);
  133. end;
  134.  
  135. destructor AUnicodeReader.Destroy;
  136. begin
  137.   if Assigned(FRawBuf) then
  138.     FreeMem(FRawBuf);
  139.   if FReaderOwner then
  140.     FreeAndNil(FReader) else
  141.     FReader := nil;
  142.   inherited Destroy;
  143. end;
  144.  
  145. procedure AUnicodeReader.ReadError;
  146. begin
  147.   raise EUnicodeReaderReadError.Create('Read error');
  148. end;
  149.  
  150. function AUnicodeReader.BufferChars(const Count: Integer): Boolean;
  151. const PackLevel = 1024;
  152. var L, I, J : Integer;
  153.     P : PByte;
  154.     S : WideString;
  155.     T : String;
  156. begin
  157.   L := Length(FBuffer) - FBufPos;
  158.   if L >= Count then
  159.     begin
  160.       Result := True;
  161.       exit;
  162.     end;
  163.   if FBufPos > PackLevel then
  164.     begin
  165.       if L > 0 then
  166.         Move(FBuffer[FBufPos + 1], FBuffer[1], Sizeof(WideChar) * L);
  167.       FBufPos := 0;
  168.       SetLength(FBuffer, L);
  169.     end;
  170.   Repeat
  171.     P := FRawBuf;
  172.     Inc(P, FRawSize);
  173.     J := FReader.Read(P, ReaderBlockSize - FRawSize);
  174.     if J = 0 then
  175.       begin
  176.         Result := False;
  177.         exit;
  178.       end;
  179.     Inc(FRawSize, J);
  180.     if Assigned(FCodec) then
  181.       S := FCodec.DecodeStr(FRawBuf, FRawSize, I) else
  182.       begin
  183.         I := J;
  184.         SetLength(T, I);
  185.         Move(FRawBuf^, Pointer(T)^, I);
  186.         S := T;
  187.       end;
  188.     if I < FRawSize then
  189.       Move(P^, FRawBuf^, FRawSize - I);
  190.     Dec(FRawSize, I);
  191.     FBuffer := FBuffer + S;
  192.     Inc(L, Length(S));
  193.   Until L >= Count;
  194.   Result := True;
  195. end;
  196.  
  197. procedure AUnicodeReader.Skip(const Count: Integer);
  198. begin
  199.   if Count <= 0 then
  200.     exit;
  201.   if not BufferChars(Count) then
  202.     ReadError;
  203.   Inc(FBufPos, Count);
  204. end;
  205.  
  206. function AUnicodeReader.SkipAll(const CharMatchFunc: WideCharMatchFunction): Integer;
  207. var P : PWideChar;
  208. begin
  209.   Result := 0;
  210.   While BufferChars(1) do
  211.     begin
  212.       P := Pointer(FBuffer);
  213.       Inc(P, FBufPos);
  214.       if not CharMatchFunc(P^) then
  215.         exit;
  216.       Inc(Result);
  217.     end;
  218. end;
  219.  
  220. function AUnicodeReader.MatchChar(const CharMatchFunc: WideCharMatchFunction; const Skip: Boolean): Boolean;
  221. var P : PWideChar;
  222. begin
  223.   if not BufferChars(1) then
  224.     Result := False else
  225.     begin
  226.       P := Pointer(FBuffer);
  227.       Inc(P, FBufPos);
  228.       Result := CharMatchFunc(P^);
  229.       if Skip and Result then
  230.         Inc(FBufPos);
  231.     end;
  232. end;
  233.  
  234. function AUnicodeReader.MatchChar(const Ch: WideChar; const Skip: Boolean): Boolean;
  235. var P : PWideChar;
  236. begin
  237.   if not BufferChars(1) then
  238.     Result := False else
  239.     begin
  240.       P := Pointer(FBuffer);
  241.       Inc(P, FBufPos);
  242.       Result := P^ = Ch;
  243.       if Skip and Result then
  244.         Inc(FBufPos);
  245.     end;
  246. end;
  247.  
  248. function AUnicodeReader.MatchChar(const Ch: Char; const Skip: Boolean): Boolean;
  249. begin
  250.   Result := MatchChar(WideChar(Ch), Skip);
  251. end;
  252.  
  253. function AUnicodeReader.MatchAnsiStr(const S: String; const CaseSensitive: Boolean; const Skip: Boolean): Boolean;
  254. var L : Integer;
  255.     P : PWideChar;
  256. begin
  257.   L := Length(S);
  258.   if not BufferChars(L + 1) then
  259.     begin
  260.       Result := False;
  261.       exit;
  262.     end;
  263.   P := Pointer(FBuffer);
  264.   Inc(P, FBufPos);
  265.   Result := WideMatchAnsiStr(S, P, CaseSensitive);
  266.   if Skip and Result then
  267.     Inc(FBufPos, L);
  268. end;
  269.  
  270. function AUnicodeReader.MatchAnsiStrDelimited(const S: String; const CaseSensitive: Boolean; const Delimiter: WideCharMatchFunction; const Skip: Boolean): Boolean;
  271. var L : Integer;
  272.     P : PWideChar;
  273. begin
  274.   L := Length(S);
  275.   if not BufferChars(L + 1) then
  276.     begin
  277.       Result := False;
  278.       exit;
  279.     end;
  280.   P := Pointer(FBuffer);
  281.   Inc(P, FBufPos);
  282.   Result := WideMatchAnsiStr(S, P, CaseSensitive);
  283.   if not Result then
  284.     exit;
  285.   Inc(P, L);
  286.   Result := Delimiter (P^);
  287.   if Skip and Result then
  288.     Inc(FBufPos, L);
  289. end;
  290.  
  291. function AUnicodeReader.PeekChar : WideChar;
  292. var P : PWideChar;
  293. begin
  294.   if not BufferChars(1) then
  295.     ReadError;
  296.   P := Pointer(FBuffer);
  297.   Inc(P, FBufPos);
  298.   Result := P^;
  299. end;
  300.  
  301. function AUnicodeReader.ReadChar : WideChar;
  302. var P : PWideChar;
  303. begin
  304.   if not BufferChars(1) then
  305.     ReadError;
  306.   P := Pointer(FBuffer);
  307.   Inc(P, FBufPos);
  308.   Result := P^;
  309.   Inc(FBufPos);
  310. end;
  311.  
  312. function AUnicodeReader.ReadChars(const CharMatchFunc: WideCharMatchFunction): WideString;
  313. var P : PWideChar;
  314.     L : Integer;
  315. begin
  316.   L := 0;
  317.   While BufferChars(L + 1) do
  318.     begin
  319.       P := Pointer(FBuffer);
  320.       Inc(P, FBufPos + L);
  321.       if not CharMatchFunc(P^) then
  322.         break;
  323.       Inc(L);
  324.     end;
  325.   if L = 0 then
  326.     Result := '' else
  327.     begin
  328.       SetLength(Result, L);
  329.       P := Pointer(FBuffer);
  330.       Inc(P, FBufPos);
  331.       Move(P^, Pointer(Result)^, Sizeof(WideChar) * L);
  332.       Inc(FBufPos, L);
  333.     end;
  334. end;
  335.  
  336. function AUnicodeReader.ReadToAnsiStr(const S: String; const CaseSensitive: Boolean): WideString;
  337. var P : PWideChar;
  338.     L, M : Integer;
  339. begin
  340.   L := 0;
  341.   M := Length(S);
  342.   While BufferChars(L + M) do
  343.     begin
  344.       P := Pointer(FBuffer);
  345.       Inc(P, FBufPos + L);
  346.       if WideMatchAnsiStr(S, P, CaseSensitive) then
  347.         break;
  348.       Inc(L);
  349.     end;
  350.   if L = 0 then
  351.     Result := '' else
  352.     begin
  353.       SetLength(Result, L);
  354.       P := Pointer(FBuffer);
  355.       Inc(P, FBufPos);
  356.       Move(P^, Pointer(Result)^, Sizeof(WideChar) * L);
  357.       Inc(FBufPos, L);
  358.     end;
  359. end;
  360.  
  361. function AUnicodeReader.ReadToChar(const C: CharSet): WideString;
  362. var P : PWideChar;
  363.     L : Integer;
  364. begin
  365.   L := 0;
  366.   While BufferChars(L + 1) do
  367.     begin
  368.       P := Pointer(FBuffer);
  369.       Inc(P, FBufPos + L);
  370.       if (Ord(P^) < $80) and (Char(Ord(P^)) in C) then
  371.         break;
  372.       Inc(L);
  373.     end;
  374.   if L = 0 then
  375.     Result := '' else
  376.     begin
  377.       SetLength(Result, L);
  378.       P := Pointer(FBuffer);
  379.       Inc(P, FBufPos);
  380.       Move(P^, Pointer(Result)^, Sizeof(WideChar) * L);
  381.       Inc(FBufPos, L);
  382.     end;
  383. end;
  384.  
  385.  
  386.  
  387. {                                                                              }
  388. { TUnicodeMemoryReader                                                         }
  389. {                                                                              }
  390. constructor TUnicodeMemoryReader.Create(const Data: Pointer; const Size: Integer);
  391. begin
  392.   inherited Create(TMemoryReader.Create(Data, Size), True);
  393. end;
  394.  
  395.  
  396.  
  397. {                                                                              }
  398. { TUnicodeFileReader                                                           }
  399. {                                                                              }
  400. constructor TUnicodeFileReader.Create(const FileName: String);
  401. begin
  402.   inherited Create(TFileReader.Create(FileName), True);
  403. end;
  404.  
  405.  
  406.  
  407. end.
  408.