-  inc(size,len);\r
-  while len > 0 do begin\r
-    p := l;\r
-    if ofs = pagesize then begin\r
-      p := tplinklist.create;\r
-      if getl = nil then getl := p;\r
-      getmem(tplinklist(p).p,pagesize);\r
-      inc(testcount);\r
-      linklistadd(l,p);\r
-      ofs := 0;\r
+\r
+  {$ifdef bfifo_assert}\r
+  if (size < 0) then raise exception.create('tfifo.add: size<0: '+inttostr(size));\r
+  if (allocsize < 0) then raise exception.create('tfifo.add: allocsize<0: '+inttostr(allocsize));\r
+  if assigned(p) and (size = 0) then raise exception.create('tfifo.add: p assigned and size=0');\r
+  if assigned(p) and (allocsize = 0) then raise exception.create('tfifo.add: p assigned and allocsize=0');\r
+  {$endif}\r
+\r
+  if not assigned(p) then begin\r
+    {$ifdef bfifo_assert}\r
+    if (size > 0) then raise exception.create('tfifo.add: p not assigned and size>0: '+inttostr(size));\r
+    if (allocsize > 0) then raise exception.create('tfifo.add: p not assigned and allocsize>0: '+inttostr(allocsize));\r
+    {$endif}\r
+\r
+    //no buffer is allocated, allocate big enough one now\r
+    allocsize := getallocsizeforsize(len);\r
+\r
+    //reuse the biggest size seen to avoid unnecessary growing of the buffer all the time, but sometimes shrink it\r
+    //so an unnecessary big buffer isn't around forever\r
+    inc(lastalloccount);\r
+    if (lastalloccount and 7 = 0) then lastallocsize := getallocsizeforsize(lastallocsize div 2);\r
+\r
+    if allocsize < lastallocsize then allocsize := lastallocsize;\r
+\r
+    getmem(p,allocsize);\r
+    head := 0;\r
+    tail := 0;\r
+  end else if (head + len > allocsize) then begin\r
+    //buffer is not big enough to add new data to the end\r
+\r
+    if (size + len <= allocsize) then begin\r
+      //it will fit if we move the data in the buffer to the start first\r
+      if (size > 0) then move(pointer(taddrint(p) + tail)^,p^,size);\r
+      //if (size > 0) then move(p[tail],p[0],size);\r
+    end else begin\r
+      //grow the buffer\r
+\r
+      allocsize := getallocsizeforsize(size + len);\r
+\r
+      getmem(p2,allocsize);\r
+      move(pointer(taddrint(p) + tail)^,p2^,size);\r
+      freemem(p);\r
+      p := p2;\r