streams.inc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652
  1. {
  2. $Id$
  3. This file is part of the Free Component Library (FCL)
  4. Copyright (c) 1998 by the Free Pascal development team
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {****************************************************************************}
  12. {* TStream *}
  13. {****************************************************************************}
  14. function TStream.GetPosition: Longint;
  15. begin
  16. Result:=Seek(0,soFromCurrent);
  17. end;
  18. procedure TStream.SetPosition(Pos: Longint);
  19. begin
  20. Seek(pos,soFromBeginning);
  21. end;
  22. function TStream.GetSize: Longint;
  23. var
  24. p : longint;
  25. begin
  26. p:=GetPosition;
  27. GetSize:=Seek(0,soFromEnd);
  28. Seek(p,soFromBeginning);
  29. end;
  30. procedure TStream.SetSize(NewSize: Longint);
  31. begin
  32. // We do nothing. Pipe streams don't support this
  33. // As wel as possible read-ony streams !!
  34. end;
  35. procedure TStream.ReadBuffer(var Buffer; Count: Longint);
  36. begin
  37. if Read(Buffer,Count)<Count then
  38. Raise EReadError.Create(SReadError);
  39. end;
  40. procedure TStream.WriteBuffer(const Buffer; Count: Longint);
  41. begin
  42. if Write(Buffer,Count)<Count then
  43. Raise EWriteError.Create(SWriteError);
  44. end;
  45. function TStream.CopyFrom(Source: TStream; Count: Longint): Longint;
  46. var
  47. i : longint;
  48. buffer : array[0..1023] of byte;
  49. begin
  50. CopyFrom:=0;
  51. while Count>0 do
  52. begin
  53. if (Count>sizeof(buffer)) then
  54. i:=sizeof(Buffer)
  55. else
  56. i:=Count;
  57. i:=Source.Read(buffer,i);
  58. i:=Write(buffer,i);
  59. dec(count,i);
  60. CopyFrom:=CopyFrom+i;
  61. if i=0 then
  62. exit;
  63. end;
  64. end;
  65. function TStream.ReadComponent(Instance: TComponent): TComponent;
  66. var
  67. Reader : TReader;
  68. begin
  69. Reader.Create(Self,1024);
  70. if assigned(Instance) then
  71. ReadComponent:=Reader.ReadRootComponent(Instance)
  72. else
  73. begin
  74. {!!!!!}
  75. end;
  76. Reader.Destroy;
  77. end;
  78. function TStream.ReadComponentRes(Instance: TComponent): TComponent;
  79. begin
  80. {!!!!!}
  81. end;
  82. procedure TStream.WriteComponent(Instance: TComponent);
  83. var
  84. Writer : TWriter;
  85. begin
  86. Try
  87. Writer.Create(Self,1024);
  88. Writer.WriteRootComponent(Instance);
  89. Finally
  90. Writer.Destroy;
  91. end;
  92. end;
  93. procedure TStream.WriteComponentRes(const ResName: string; Instance: TComponent);
  94. var
  95. startpos,s : longint;
  96. begin
  97. {$ifdef Win16Res}
  98. { Numeric resource type }
  99. WriteByte($ff);
  100. { Application defined data }
  101. WriteWord($0a);
  102. { write the name as asciiz }
  103. // WriteBuffer(ResName[1],length(ResName));
  104. WriteByte(0);
  105. { Movable, Pure and Discardable }
  106. WriteWord($1030);
  107. { size isn't known yet }
  108. WriteDWord(0);
  109. startpos:=GetPosition;
  110. WriteComponent(Instance);
  111. { calculate size }
  112. s:=GetPosition-startpos;
  113. { back patch size }
  114. SetPosition(startpos-4);
  115. WriteDWord(s);
  116. {$endif Win16Res}
  117. end;
  118. procedure TStream.WriteDescendent(Instance, Ancestor: TComponent);
  119. begin
  120. {!!!!!}
  121. end;
  122. procedure TStream.WriteDescendentRes(const ResName: string; Instance, Ancestor: TComponent);
  123. begin
  124. {!!!!!}
  125. end;
  126. procedure TStream.ReadResHeader;
  127. begin
  128. {$ifdef Win16Res}
  129. try
  130. { application specific resource ? }
  131. if ReadByte<>$ff then
  132. raise EInvalidImage.Create('');
  133. if ReadWord<>$000a then
  134. raise EInvalidImage.Create('');
  135. { read name }
  136. while ReadByte<>0 do
  137. ;
  138. { check the access specifier }
  139. if ReadWord<>$1030 then
  140. raise EInvalidImage.Create('');
  141. { ignore the size }
  142. ReadDWord;
  143. except
  144. {/////
  145. on EInvalidImage do
  146. raise;
  147. else
  148. raise EInvalidImage.create(SInvalidImage);
  149. }
  150. end;
  151. {$endif Win16Res}
  152. end;
  153. function TStream.ReadByte : Byte;
  154. var
  155. b : Byte;
  156. begin
  157. ReadBuffer(b,1);
  158. ReadByte:=b;
  159. end;
  160. function TStream.ReadWord : Word;
  161. var
  162. w : Word;
  163. begin
  164. ReadBuffer(w,2);
  165. ReadWord:=w;
  166. end;
  167. function TStream.ReadDWord : Cardinal;
  168. var
  169. d : Cardinal;
  170. begin
  171. ReadBuffer(d,4);
  172. ReadDWord:=d;
  173. end;
  174. Function TStream.ReadAnsiString : String;
  175. Type PByte = ^Byte;
  176. Var TheSize : Longint;
  177. P : PByte ;
  178. begin
  179. ReadBuffer (TheSize,SizeOf(TheSize));
  180. SetLength(Result,Size);
  181. // Illegal typecast if no AnsiStrings defined.
  182. ReadBuffer (Pointer(Result)^,Size);
  183. P:=Pointer(Result)+Size;
  184. p^:=0;
  185. end;
  186. Procedure TStream.WriteAnsiString (S : String);
  187. Var L : Longint;
  188. begin
  189. L:=Length(S);
  190. WriteBuffer (L,SizeOf(L));
  191. WriteBuffer (Pointer(S)^,L);
  192. end;
  193. procedure TStream.WriteByte(b : Byte);
  194. begin
  195. WriteBuffer(b,1);
  196. end;
  197. procedure TStream.WriteWord(w : Word);
  198. begin
  199. WriteBuffer(w,2);
  200. end;
  201. procedure TStream.WriteDWord(d : Cardinal);
  202. begin
  203. WriteBuffer(d,4);
  204. end;
  205. {****************************************************************************}
  206. {* THandleStream *}
  207. {****************************************************************************}
  208. Constructor THandleStream.Create(AHandle: Integer);
  209. begin
  210. FHandle:=AHandle;
  211. end;
  212. function THandleStream.Read(var Buffer; Count: Longint): Longint;
  213. begin
  214. Result:=FileRead(FHandle,Buffer,Count);
  215. If Result=-1 then Result:=0;
  216. end;
  217. function THandleStream.Write(const Buffer; Count: Longint): Longint;
  218. begin
  219. Result:=FileWrite (FHandle,Buffer,Count);
  220. If Result=-1 then Result:=0;
  221. end;
  222. {****************************************************************************}
  223. {* TFileStream *}
  224. {****************************************************************************}
  225. constructor TFileStream.Create(const FileName: string; Mode: Word);
  226. begin
  227. If Mode=fmcreate then
  228. FHandle:=FileCreate(FileName)
  229. else
  230. FHAndle:=FileOpen(FileName,Mode);
  231. If FHandle<0 then
  232. If Mode=fmcreate then
  233. raise EFCreateError.createfmt(SFCreateError,[FileName])
  234. else
  235. raise EFOpenError.Createfmt(SFOpenError,[Filename]);
  236. end;
  237. destructor TFileStream.Destroy;
  238. begin
  239. FileClose(FHandle);
  240. end;
  241. Procedure TFileStream.SetSize(NewSize: Longint);
  242. begin
  243. FileTruncate(FHandle,NewSize);
  244. end;
  245. function TFileStream.Seek(Offset: Longint; Origin: Word): Longint;
  246. begin
  247. Result:=FileSeek(FHandle,Offset,Origin);
  248. end;
  249. {****************************************************************************}
  250. {* TCustomMemoryStream *}
  251. {****************************************************************************}
  252. procedure TCustomMemoryStream.SetPointer(Ptr: Pointer; Size: Longint);
  253. begin
  254. FMemory:=Ptr;
  255. FSize:=Size;
  256. end;
  257. function TCustomMemoryStream.Read(var Buffer; Count: Longint): Longint;
  258. begin
  259. Result:=0;
  260. If (FSize>0) and (FPosition<Fsize) then
  261. begin
  262. Result:=FSize-FPosition;
  263. If Result>Count then Result:=Count;
  264. Move ((FMemory+FPosition)^,Buffer,Result);
  265. FPosition:=Fposition+Result;
  266. end;
  267. end;
  268. function TCustomMemoryStream.Seek(Offset: Longint; Origin: Word): Longint;
  269. begin
  270. Case Origin of
  271. soFromBeginning : FPosition:=Offset;
  272. soFromEnd : FPosition:=FSize+Offset;
  273. soFromCurrent : FpoSition:=FPosition+Offset;
  274. end;
  275. Result:=FPosition;
  276. end;
  277. procedure TCustomMemoryStream.SaveToStream(Stream: TStream);
  278. begin
  279. if FSize>0 then Stream.WriteBuffer (FMemory^,FSize);
  280. end;
  281. procedure TCustomMemoryStream.SaveToFile(const FileName: string);
  282. Var S : TFileStream;
  283. begin
  284. Try
  285. S:=TFileStream.Create (FileName,fmCreate);
  286. SaveToStream(S);
  287. finally
  288. S.free;
  289. end;
  290. end;
  291. {****************************************************************************}
  292. {* TMemoryStream *}
  293. {****************************************************************************}
  294. Const TMSGrow = 4096; { Use 4k blocks. }
  295. procedure TMemoryStream.SetCapacity(NewCapacity: Longint);
  296. begin
  297. SetPointer (Realloc(NewCapacity),Fsize);
  298. FCapacity:=NewCapacity;
  299. end;
  300. function TMemoryStream.Realloc(var NewCapacity: Longint): Pointer;
  301. Var MoveSize : Longint;
  302. begin
  303. If NewCapacity>0 Then // round off to block size.
  304. NewCapacity := (NewCapacity + (TMSGrow-1)) and not (TMSGROW-1);
  305. // Only now check !
  306. If NewCapacity<>FCapacity then
  307. If NewCapacity=0 then
  308. FreeMem (FMemory,Fcapacity)
  309. else
  310. begin
  311. GetMem (Result,NewCapacity);
  312. If Result=Nil then
  313. Raise EStreamError.Create(SMemoryStreamError);
  314. If FCapacity>0 then
  315. begin
  316. MoveSize:=FSize;
  317. If MoveSize>NewCapacity then MoveSize:=NewCapacity;
  318. Move (Fmemory^,Result^,MoveSize);
  319. FreeMem (FMemory,FCapacity);
  320. end;
  321. end;
  322. end;
  323. destructor TMemoryStream.Destroy;
  324. begin
  325. Clear;
  326. Inherited Destroy;
  327. end;
  328. procedure TMemoryStream.Clear;
  329. begin
  330. FSize:=0;
  331. FPosition:=0;
  332. SetCapacity (0);
  333. end;
  334. procedure TMemoryStream.LoadFromStream(Stream: TStream);
  335. begin
  336. Stream.Position:=0;
  337. SetSize(Stream.Size);
  338. If FSize>0 then Stream.ReadBuffer(FMemory^,FSize);
  339. end;
  340. procedure TMemoryStream.LoadFromFile(const FileName: string);
  341. Var S : TFileStream;
  342. begin
  343. Try
  344. S:=TFileStream.Create (FileName,fmOpenRead);
  345. LoadFromStream(S);
  346. finally
  347. S.free;
  348. end;
  349. end;
  350. procedure TMemoryStream.SetSize(NewSize: Longint);
  351. begin
  352. SetCapacity (NewSize);
  353. If FSize>NewSize then FSize:=NewSize;
  354. IF FPosition>FSize then FPosition:=FSize;
  355. end;
  356. function TMemoryStream.Write(const Buffer; Count: Longint): Longint;
  357. Var NewPos : Longint;
  358. begin
  359. If Count=0 then
  360. exit(0);
  361. NewPos:=FPosition+Count;
  362. If NewPos>Fsize then
  363. begin
  364. IF NewPos>FCapacity then
  365. SetCapacity (NewPos);
  366. FSize:=Newpos;
  367. end;
  368. System.Move (Buffer,(FMemory+FPosition)^,Count);
  369. FPosition:=NewPos;
  370. Result:=Count;
  371. end;
  372. {****************************************************************************}
  373. {* TStringStream *}
  374. {****************************************************************************}
  375. procedure TStringStream.SetSize(NewSize: Longint);
  376. begin
  377. //!! Setlength(FDataString,NewSize);
  378. If FPosition>NewSize then FPosition:=NewSize;
  379. end;
  380. constructor TStringStream.Create(const AString: string);
  381. begin
  382. Inherited create;
  383. FDataString:=AString;
  384. end;
  385. function TStringStream.Read(var Buffer; Count: Longint): Longint;
  386. begin
  387. Result:=Length(FDataString)-FPosition;
  388. If Result>Count then Result:=Count;
  389. // This supposes FDataString to be of type AnsiString !
  390. //!! Move (Pchar(FDataString)[FPosition],Buffer,Count);
  391. FPosition:=FPosition+Count;
  392. end;
  393. function TStringStream.ReadString(Count: Longint): string;
  394. Var NewLen : Longint;
  395. begin
  396. NewLen:=Length(FDataString)-FPosition;
  397. If NewLen>Count then NewLen:=Count;
  398. //!! SetLength(Result,NewLen);
  399. //!! Read (Pointer(Result)^,NewLen);
  400. end;
  401. function TStringStream.Seek(Offset: Longint; Origin: Word): Longint;
  402. begin
  403. Case Origin of
  404. soFromBeginning : FPosition:=Offset;
  405. soFromEnd : FPosition:=Length(FDataString)+Offset;
  406. soFromCurrent : FpoSition:=FPosition+Offset;
  407. end;
  408. If FPosition>Length(FDataString) then FPosition:=Length(FDataString);
  409. If FPosition<0 then FPosition:=0;
  410. Result:=FPosition;
  411. end;
  412. function TStringStream.Write(const Buffer; Count: Longint): Longint;
  413. begin
  414. Result:=Count;
  415. SetSize(FPosition+Count);
  416. // This supposes that FDataString is of type AnsiString)
  417. //!! Move (Buffer,PCHar(FDataString)[Fposition],Count);
  418. FPosition:=FPosition+Count;
  419. end;
  420. procedure TStringStream.WriteString(const AString: string);
  421. begin
  422. //!! Write (PChar(Astring)[0],Length(AString));
  423. end;
  424. {****************************************************************************}
  425. {* TResourceStream *}
  426. {****************************************************************************}
  427. procedure TResourceStream.Initialize(Instance: THandle; Name, ResType: PChar);
  428. begin
  429. end;
  430. constructor TResourceStream.Create(Instance: THandle; const ResName: string; ResType: PChar);
  431. begin
  432. end;
  433. constructor TResourceStream.CreateFromID(Instance: THandle; ResID: Integer; ResType: PChar);
  434. begin
  435. end;
  436. destructor TResourceStream.Destroy;
  437. begin
  438. end;
  439. function TResourceStream.Write(const Buffer; Count: Longint): Longint;
  440. begin
  441. end;
  442. {
  443. $Log$
  444. Revision 1.12 1999-02-10 14:12:26 michael
  445. + Some strange bug in writecoponentres
  446. Revision 1.11 1999/02/06 07:16:48 michael
  447. + Fixed Stream.ReadAnsiString
  448. Revision 1.10 1999/02/02 21:23:19 michael
  449. + only sysutils is used now
  450. Revision 1.9 1999/01/28 23:55:42 florian
  451. * made it compilable
  452. Revision 1.8 1998/10/02 22:41:30 michael
  453. + Added exceptions for error handling
  454. Revision 1.7 1998/08/24 12:38:24 michael
  455. small fixes
  456. Revision 1.6 1998/06/11 21:15:28 michael
  457. + Implemented (Custom)Memory and StringStream
  458. Revision 1.5 1998/06/11 13:46:33 michael
  459. + Fixed some functions. TFileStream OK.
  460. Revision 1.4 1998/06/10 21:53:07 michael
  461. + Implemented Handle/FileStreams
  462. Revision 1.3 1998/05/06 12:58:35 michael
  463. + Added WriteAnsiString method to TStream
  464. Revision 1.2 1998/05/05 15:25:04 michael
  465. + Fix to be able to compile from florian
  466. Revision 1.1 1998/05/04 14:30:12 michael
  467. * Split file according to Class; implemented dummys for all methods, so unit compiles.
  468. }