owbase.pas 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. {
  2. Copyright (c) 1998-2002 by Peter Vreman
  3. Contains the base stuff for writing for object files to disk
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit owbase;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. cstreams,
  22. cclasses;
  23. type
  24. tobjectwriter=class
  25. private
  26. f : TCFileStream;
  27. opened : boolean;
  28. buf : pchar;
  29. bufidx : longint;
  30. size : longint;
  31. procedure writebuf;
  32. public
  33. constructor create;
  34. destructor destroy;override;
  35. function createfile(const fn:string):boolean;virtual;
  36. procedure closefile;virtual;
  37. procedure writesym(const sym:string);virtual;
  38. procedure write(const b;len:longint);virtual;
  39. procedure WriteZeros(l:longint);
  40. end;
  41. tobjectreader=class
  42. private
  43. f : TCFileStream;
  44. opened : boolean;
  45. buf : pchar;
  46. bufidx,
  47. bufmax : longint;
  48. function readbuf:boolean;
  49. public
  50. constructor create;
  51. destructor destroy;override;
  52. function openfile(const fn:string):boolean;virtual;
  53. procedure closefile;virtual;
  54. procedure seek(len:longint);
  55. function read(var b;len:longint):boolean;virtual;
  56. function readarray(a:TDynamicArray;len:longint):boolean;
  57. end;
  58. implementation
  59. uses
  60. verbose, globals;
  61. const
  62. bufsize = 32768;
  63. {****************************************************************************
  64. TObjectWriter
  65. ****************************************************************************}
  66. constructor tobjectwriter.create;
  67. begin
  68. getmem(buf,bufsize);
  69. bufidx:=0;
  70. opened:=false;
  71. size:=0;
  72. end;
  73. destructor tobjectwriter.destroy;
  74. begin
  75. if opened then
  76. closefile;
  77. freemem(buf,bufsize);
  78. end;
  79. function tobjectwriter.createfile(const fn:string):boolean;
  80. begin
  81. createfile:=false;
  82. f:=TCFileStream.Create(fn,fmCreate);
  83. if CStreamError<>0 then
  84. begin
  85. Message1(exec_e_cant_create_objectfile,fn);
  86. exit;
  87. end;
  88. bufidx:=0;
  89. size:=0;
  90. opened:=true;
  91. createfile:=true;
  92. end;
  93. procedure tobjectwriter.closefile;
  94. var
  95. fn : string;
  96. begin
  97. if bufidx>0 then
  98. writebuf;
  99. fn:=f.filename;
  100. f.free;
  101. { Remove if size is 0 }
  102. if size=0 then
  103. RemoveFile(fn);
  104. opened:=false;
  105. size:=0;
  106. end;
  107. procedure tobjectwriter.writebuf;
  108. begin
  109. f.write(buf^,bufidx);
  110. bufidx:=0;
  111. end;
  112. procedure tobjectwriter.writesym(const sym:string);
  113. begin
  114. end;
  115. procedure tobjectwriter.write(const b;len:longint);
  116. var
  117. p : pchar;
  118. left,
  119. idx : longint;
  120. begin
  121. inc(size,len);
  122. p:=pchar(@b);
  123. idx:=0;
  124. while len>0 do
  125. begin
  126. left:=bufsize-bufidx;
  127. if len>left then
  128. begin
  129. move(p[idx],buf[bufidx],left);
  130. dec(len,left);
  131. inc(idx,left);
  132. inc(bufidx,left);
  133. writebuf;
  134. end
  135. else
  136. begin
  137. move(p[idx],buf[bufidx],len);
  138. inc(bufidx,len);
  139. exit;
  140. end;
  141. end;
  142. end;
  143. procedure tobjectwriter.WriteZeros(l:longint);
  144. var
  145. empty : array[0..255] of byte;
  146. begin
  147. if l>sizeof(empty) then
  148. internalerror(200404081);
  149. if l>0 then
  150. begin
  151. fillchar(empty,l,0);
  152. Write(empty,l);
  153. end;
  154. end;
  155. {****************************************************************************
  156. TObjectReader
  157. ****************************************************************************}
  158. constructor tobjectreader.create;
  159. begin
  160. getmem(buf,bufsize);
  161. bufidx:=0;
  162. bufmax:=0;
  163. opened:=false;
  164. end;
  165. destructor tobjectreader.destroy;
  166. begin
  167. if opened then
  168. closefile;
  169. freemem(buf,bufsize);
  170. end;
  171. function tobjectreader.openfile(const fn:string):boolean;
  172. begin
  173. openfile:=false;
  174. f:=TCFileStream.Create(fn,fmOpenRead);
  175. if CStreamError<>0 then
  176. begin
  177. Message1(exec_e_cant_create_objectfile,fn);
  178. exit;
  179. end;
  180. bufidx:=0;
  181. bufmax:=0;
  182. opened:=true;
  183. openfile:=true;
  184. end;
  185. procedure tobjectreader.closefile;
  186. begin
  187. f.free;
  188. opened:=false;
  189. bufidx:=0;
  190. bufmax:=0;
  191. end;
  192. function tobjectreader.readbuf:boolean;
  193. begin
  194. bufmax:=f.read(buf^,bufsize);
  195. bufidx:=0;
  196. readbuf:=(bufmax>0);
  197. end;
  198. procedure tobjectreader.seek(len:longint);
  199. begin
  200. f.seek(len,soFromBeginning);
  201. bufidx:=0;
  202. bufmax:=0;
  203. end;
  204. function tobjectreader.read(var b;len:longint):boolean;
  205. var
  206. p : pchar;
  207. left,
  208. idx : longint;
  209. begin
  210. read:=false;
  211. if bufmax=0 then
  212. if not readbuf then
  213. exit;
  214. p:=pchar(@b);
  215. idx:=0;
  216. while len>0 do
  217. begin
  218. left:=bufmax-bufidx;
  219. if len>left then
  220. begin
  221. move(buf[bufidx],p[idx],left);
  222. dec(len,left);
  223. inc(idx,left);
  224. inc(bufidx,left);
  225. if not readbuf then
  226. exit;
  227. end
  228. else
  229. begin
  230. move(buf[bufidx],p[idx],len);
  231. inc(bufidx,len);
  232. inc(idx,len);
  233. break;
  234. end;
  235. end;
  236. read:=(idx=len);
  237. end;
  238. function tobjectreader.readarray(a:TDynamicArray;len:longint):boolean;
  239. var
  240. orglen,
  241. left,
  242. idx : longint;
  243. begin
  244. readarray:=false;
  245. if bufmax=0 then
  246. if not readbuf then
  247. exit;
  248. orglen:=len;
  249. idx:=0;
  250. while len>0 do
  251. begin
  252. left:=bufmax-bufidx;
  253. if len>left then
  254. begin
  255. a.Write(buf[bufidx],left);
  256. dec(len,left);
  257. inc(idx,left);
  258. inc(bufidx,left);
  259. if not readbuf then
  260. exit;
  261. end
  262. else
  263. begin
  264. a.Write(buf[bufidx],len);
  265. inc(bufidx,len);
  266. inc(idx,len);
  267. break;
  268. end;
  269. end;
  270. readarray:=(idx=orglen);
  271. end;
  272. end.