replace internal uses of gettimeofday with monotonic time where appropriate. make...
[lcore.git] / readtxt2.pas
index 12bea5afed8cceeccd92590e58671ab1bf0a7b83..e7ac690e823646d05a4f8efe50cf17c327a32dfe 100644 (file)
@@ -22,31 +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: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
-    procedure checkandread;\r
+    property detectedeol : integer read fdetectedeol;\r
   end;\r
-\r
+  \r
 implementation\r
 \r
 constructor treadtxt.create(asourcestream: tstream; adestroysourcestream:boolean);\r
@@ -61,7 +64,7 @@ end;
 \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
@@ -78,21 +81,51 @@ end;
 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
     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
@@ -114,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