You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

bfifo.pas 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. { Copyright (C) 2005 Bas Steendijk and Peter Green
  2. For conditions of distribution and use, see copyright notice in zlib_license.txt
  3. which is included in the package
  4. ----------------------------------------------------------------------------- }
  5. unit bfifo;
  6. {$ifdef fpc}
  7. {$mode delphi}
  8. {$endif}
  9. interface
  10. uses blinklist,pgtypes;
  11. const
  12. pagesize=1420;
  13. type
  14. tfifo=class(tobject)
  15. private
  16. l:tlinklist; {add to}
  17. getl:tlinklist; {remove from}
  18. ofs:integer;
  19. getofs:integer;
  20. public
  21. size:integer;
  22. procedure add(data:pointer;len:integer);
  23. function get(var resultptr:pointer;len:integer):integer;
  24. procedure del(len:integer);
  25. constructor create;
  26. destructor destroy; override;
  27. end;
  28. implementation
  29. var
  30. testcount:integer;
  31. {
  32. xx1..... add
  33. xxxxxxxx
  34. ....2xxx delete
  35. 1 ofs
  36. 2 getofs
  37. }
  38. procedure tfifo.add;
  39. var
  40. a:integer;
  41. p:tlinklist;
  42. begin
  43. if len <= 0 then exit;
  44. inc(size,len);
  45. while len > 0 do begin
  46. p := l;
  47. if ofs = pagesize then begin
  48. p := tplinklist.create;
  49. if getl = nil then getl := p;
  50. getmem(tplinklist(p).p,pagesize);
  51. inc(testcount);
  52. linklistadd(l,p);
  53. ofs := 0;
  54. end;
  55. a := pagesize - ofs;
  56. if len < a then a := len;
  57. move(data^,pointer(taddrint(tplinklist(p).p)+ofs)^,a);
  58. inc(taddrint(data),a);
  59. dec(len,a);
  60. inc(ofs,a);
  61. end;
  62. end;
  63. function tfifo.get;
  64. var
  65. p:tlinklist;
  66. a:integer;
  67. begin
  68. if len > size then len := size;
  69. if len <= 0 then begin
  70. result := 0;
  71. resultptr := nil;
  72. exit;
  73. end;
  74. p := getl;
  75. resultptr := pointer(taddrint(tplinklist(p).p)+getofs);
  76. result := pagesize-getofs;
  77. if result > len then result := len;
  78. end;
  79. procedure tfifo.del;
  80. var
  81. a:integer;
  82. p,p2:tlinklist;
  83. begin
  84. if len <= 0 then exit;
  85. p := getl;
  86. if len > size then len := size;
  87. dec(size,len);
  88. if len = 0 then exit;
  89. while len > 0 do begin
  90. a := pagesize-getofs;
  91. if a > len then a := len;
  92. inc(getofs,a);
  93. dec(len,a);
  94. if getofs = pagesize then begin
  95. p2 := p.prev;
  96. freemem(tplinklist(p).p);
  97. dec(testcount);
  98. linklistdel(l,p);
  99. p.destroy;
  100. p := p2;
  101. getl := p;
  102. getofs := 0;
  103. end;
  104. end;
  105. if size = 0 then begin
  106. if assigned(l) then begin
  107. p := l;
  108. freemem(tplinklist(p).p);
  109. dec(testcount);
  110. linklistdel(l,p);
  111. p.destroy;
  112. getl := nil;
  113. end;
  114. ofs := pagesize;
  115. getofs := 0;
  116. end;
  117. end;
  118. constructor tfifo.create;
  119. begin
  120. ofs := pagesize;
  121. inherited create;
  122. end;
  123. destructor tfifo.destroy;
  124. begin
  125. del(size);
  126. inherited destroy;
  127. end;
  128. end.