fix slow send speed, new fifo allows get of entire buffer
[lcore.git] / readtxt2.pas
index 84c57652c4e90fe86d85cb4dc263b4261a4a8dd1..e7ac690e823646d05a4f8efe50cf17c327a32dfe 100644 (file)
@@ -22,30 +22,34 @@ uses
 const\r
   bufsize=4096;\r
   eoltype_none=0;\r
+  eoltype_any=0;\r
   eoltype_cr=1;\r
   eoltype_lf=2;\r
   eoltype_crlf=3;\r
 \r
 type\r
   treadtxt=class(tobject)\r
+  private\r
+    buf:array[0..bufsize-1] of byte;\r
+    numread:integer;\r
+    bufpointer:integer;\r
+    currenteol,preveol:integer;\r
+    fileeof,reachedeof:boolean;\r
+    fdetectedeol:integer;\r
+    procedure checkandread;\r
   public\r
     sourcestream:tstream;\r
     destroysourcestream:boolean;\r
+    allowedeol:integer;\r
     constructor create(asourcestream: tstream; adestroysourcestream:boolean);\r
     constructor createf(filename : string);\r
 \r
-    function readline:string;\r
+    function readline:ansistring;\r
     function eof:boolean;\r
     destructor destroy; override;\r
-  private\r
-    buf:array[0..bufsize-1] of byte;\r
-    numread:integer;\r
-    bufpointer:integer;\r
-    currenteol,preveol:integer;\r
-    fileeof,reachedeof:boolean;\r
-    eoltype:integer;\r
+    property detectedeol : integer read fdetectedeol;\r
   end;\r
-\r
+  \r
 implementation\r
 \r
 constructor treadtxt.create(asourcestream: tstream; adestroysourcestream:boolean);\r
@@ -54,39 +58,74 @@ begin
   sourcestream := asourcestream;\r
   destroysourcestream := adestroysourcestream;\r
 \r
-  if sourcestream.Position >= sourcestream.size then fileeof := true;\r
+  //if sourcestream.Position >= sourcestream.size then fileeof := true;\r
   bufpointer := bufsize;\r
-  destroysourcestream := false;\r
 end;\r
 \r
-constructor treadtxt.createf(filename : string);\r
+constructor treadtxt.createf(filename: string);\r
 begin\r
-  create(tfilestream.create(filename,fmOpenRead),true);\r
+  create(tfilestream.create(filename,fmOpenRead or fmShareDenyWrite),true);\r
 end;\r
 \r
 \r
+procedure treadtxt.checkandread;\r
+begin\r
+  if bufpointer >= numread then begin\r
+    numread := sourcestream.read(buf,bufsize);\r
+    bufpointer := 0;\r
+    if numread = 0 then fileeof := true;\r
+      \r
+  end;\r
+end;\r
+\r
 function treadtxt.readline;\r
 var\r
   a,b,c,d:integer;\r
+  prevchar : integer;\r
+  trimchar : boolean;\r
 begin\r
-\r
+  prevchar := 0;\r
   result := '';\r
   repeat\r
-    if bufpointer >= bufsize then begin\r
-      numread := sourcestream.read(buf,bufsize);\r
-      bufpointer := 0;\r
-      if sourcestream.Position >= sourcestream.size then fileeof := true;\r
-    end;\r
+    checkandread;\r
     b := numread-1;\r
-\r
+    trimchar := false;\r
     {core search loop begin}\r
     d := -1;\r
     for a := bufpointer to b do begin\r
       c := buf[a];\r
-      if (c = 10) or (c = 13) then begin\r
-         d := a;\r
-         break;\r
+      //check if the character can possibly be a line ending before getting\r
+      //into the more complex checks that depend on eol type\r
+      if (c = 10) or (c = 13) then case allowedeol of\r
+        eoltype_any: begin\r
+          d := a;\r
+          break;\r
+        end;\r
+        eoltype_cr: begin\r
+          if (c = 13) then begin\r
+            d := a;\r
+            break;\r
+          end;\r
+        end;\r
+        eoltype_lf: begin\r
+          if (c = 10) then begin\r
+            d := a;\r
+            break;\r
+          end;\r
+        end;\r
+        eoltype_crlf: begin\r
+          if (c = 10) and (prevchar= 13) then begin\r
+            d := a;\r
+            trimchar := true;\r
+            break;\r
+          end;\r
+          prevchar := c;\r
+        end;\r
+        else begin\r
+          raise exception.create('undefined eol type set');\r
+        end;\r
       end;\r
+      prevchar := c;\r
     end;\r
     {core search loop end}\r
     \r
@@ -97,7 +136,8 @@ begin
       setlength(result,c+b);\r
       move(buf[bufpointer],result[c+1],b);\r
       bufpointer := numread;\r
-      if numread < bufsize then begin\r
+      if fileeof then begin\r
+        {we reached the end of the file, return what we have}\r
         reachedeof := true;\r
         exit;\r
       end;\r
@@ -107,18 +147,24 @@ begin
       currenteol := buf[d];\r
 \r
       {end of line before end of buffer}\r
-      if (currenteol = 10) and (preveol = 13) then begin\r
+      if (currenteol = 10) and (preveol = 13) and (bufpointer = d) then begin\r
         {it's the second EOL char of a DOS line ending, don't cause a line}\r
         bufpointer := d+1;\r
-        eoltype := eoltype_crlf;\r
+        fdetectedeol := eoltype_crlf;\r
       end else begin\r
-        if eoltype = eoltype_none then begin\r
-          if (currenteol = 10) then eoltype := eoltype_lf else eoltype := eoltype_cr;\r
+        if fdetectedeol = eoltype_none then begin\r
+          if (currenteol = 10) then fdetectedeol := eoltype_lf else fdetectedeol := eoltype_cr;\r
         end;  \r
         b := d-bufpointer;\r
-        setlength(result,c+b);\r
-        move(buf[bufpointer],result[c+1],b);\r
-        bufpointer := d+1;\r
+        if trimchar then begin\r
+          setlength(result,c+b-1);\r
+          move(buf[bufpointer],result[c+1],b-1);\r
+          bufpointer := d+1;\r
+        end else begin\r
+          setlength(result,c+b);\r
+          move(buf[bufpointer],result[c+1],b);\r
+          bufpointer := d+1;\r
+        end;\r
 \r
         {EOF check}\r
         if fileeof then begin\r
@@ -134,8 +180,8 @@ end;
 \r
 function treadtxt.eof:boolean;\r
 begin\r
-\r
-  result := ((bufpointer >= bufsize) and fileeof) or reachedeof;\r
+  checkandread;\r
+  result := ((bufpointer >= numread) and fileeof) or reachedeof;\r
 end;\r
 \r
 destructor treadtxt.destroy;\r