streams.inc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662
  1. {
  2. $Id$
  3. This file is part of the Free Component Library (FCL)
  4. Copyright (c) 1999-2000 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 := TReader.Create(Self, 4096);
  70. try
  71. Result := Reader.ReadRootComponent(Instance);
  72. finally
  73. Reader.Free;
  74. end;
  75. end;
  76. function TStream.ReadComponentRes(Instance: TComponent): TComponent;
  77. begin
  78. ReadResHeader;
  79. Result := ReadComponent(Instance);
  80. end;
  81. procedure TStream.WriteComponent(Instance: TComponent);
  82. begin
  83. WriteDescendent(Instance, nil);
  84. end;
  85. procedure TStream.WriteComponentRes(const ResName: string; Instance: TComponent);
  86. begin
  87. WriteDescendentRes(ResName, Instance, nil);
  88. end;
  89. procedure TStream.WriteDescendent(Instance, Ancestor: TComponent);
  90. var
  91. Driver : TAbstractObjectWriter;
  92. Writer : TWriter;
  93. begin
  94. Driver := TBinaryObjectWriter.Create(Self, 4096);
  95. Try
  96. Writer := TWriter.Create(Driver);
  97. Try
  98. Writer.WriteDescendent(Instance, Ancestor);
  99. Finally
  100. Writer.Destroy;
  101. end;
  102. Finally
  103. Driver.Free;
  104. end;
  105. end;
  106. procedure TStream.WriteDescendentRes(const ResName: string; Instance, Ancestor: TComponent);
  107. var
  108. FixupInfo: Integer;
  109. begin
  110. { Write a resource header }
  111. WriteResourceHeader(ResName, FixupInfo);
  112. { Write the instance itself }
  113. WriteDescendent(Instance, Ancestor);
  114. { Insert the correct resource size into the resource header }
  115. FixupResourceHeader(FixupInfo);
  116. end;
  117. procedure TStream.WriteResourceHeader(const ResName: string; {!!!: out} var FixupInfo: Integer);
  118. begin
  119. { Numeric resource type }
  120. WriteByte($ff);
  121. { Application defined data }
  122. WriteWord($0a);
  123. { write the name as asciiz }
  124. WriteBuffer(ResName[1],length(ResName));
  125. WriteByte(0);
  126. { Movable, Pure and Discardable }
  127. WriteWord($1030);
  128. { Placeholder for the resource size }
  129. WriteDWord(0);
  130. { Return current stream position so that the resource size can be
  131. inserted later }
  132. FixupInfo := Position;
  133. end;
  134. procedure TStream.FixupResourceHeader(FixupInfo: Integer);
  135. var
  136. ResSize : Integer;
  137. begin
  138. ResSize := Position - FixupInfo;
  139. { Insert the correct resource size into the placeholder written by
  140. WriteResourceHeader }
  141. Position := FixupInfo - 4;
  142. WriteDWord(ResSize);
  143. { Seek back to the end of the resource }
  144. Position := FixupInfo + ResSize;
  145. end;
  146. procedure TStream.ReadResHeader;
  147. begin
  148. try
  149. { application specific resource ? }
  150. if ReadByte<>$ff then
  151. raise EInvalidImage.Create(SInvalidImage);
  152. if ReadWord<>$000a then
  153. raise EInvalidImage.Create(SInvalidImage);
  154. { read name }
  155. while ReadByte<>0 do
  156. ;
  157. { check the access specifier }
  158. if ReadWord<>$1030 then
  159. raise EInvalidImage.Create(SInvalidImage);
  160. { ignore the size }
  161. ReadDWord;
  162. except
  163. on EInvalidImage do
  164. raise;
  165. else
  166. raise EInvalidImage.create(SInvalidImage);
  167. end;
  168. end;
  169. function TStream.ReadByte : Byte;
  170. var
  171. b : Byte;
  172. begin
  173. ReadBuffer(b,1);
  174. ReadByte:=b;
  175. end;
  176. function TStream.ReadWord : Word;
  177. var
  178. w : Word;
  179. begin
  180. ReadBuffer(w,2);
  181. ReadWord:=w;
  182. end;
  183. function TStream.ReadDWord : Cardinal;
  184. var
  185. d : Cardinal;
  186. begin
  187. ReadBuffer(d,4);
  188. ReadDWord:=d;
  189. end;
  190. Function TStream.ReadAnsiString : String;
  191. Type
  192. PByte = ^Byte;
  193. Var
  194. TheSize : Longint;
  195. P : PByte ;
  196. begin
  197. ReadBuffer (TheSize,SizeOf(TheSize));
  198. SetLength(Result,TheSize);
  199. // Illegal typecast if no AnsiStrings defined.
  200. if TheSize>0 then
  201. begin
  202. ReadBuffer (Pointer(Result)^,TheSize);
  203. P:=Pointer(Result)+TheSize;
  204. p^:=0;
  205. end;
  206. end;
  207. Procedure TStream.WriteAnsiString (S : String);
  208. Var L : Longint;
  209. begin
  210. L:=Length(S);
  211. WriteBuffer (L,SizeOf(L));
  212. WriteBuffer (Pointer(S)^,L);
  213. end;
  214. procedure TStream.WriteByte(b : Byte);
  215. begin
  216. WriteBuffer(b,1);
  217. end;
  218. procedure TStream.WriteWord(w : Word);
  219. begin
  220. WriteBuffer(w,2);
  221. end;
  222. procedure TStream.WriteDWord(d : Cardinal);
  223. begin
  224. WriteBuffer(d,4);
  225. end;
  226. {****************************************************************************}
  227. {* THandleStream *}
  228. {****************************************************************************}
  229. Constructor THandleStream.Create(AHandle: Integer);
  230. begin
  231. FHandle:=AHandle;
  232. end;
  233. function THandleStream.Read(var Buffer; Count: Longint): Longint;
  234. begin
  235. Result:=FileRead(FHandle,Buffer,Count);
  236. If Result=-1 then Result:=0;
  237. end;
  238. function THandleStream.Write(const Buffer; Count: Longint): Longint;
  239. begin
  240. Result:=FileWrite (FHandle,Buffer,Count);
  241. If Result=-1 then Result:=0;
  242. end;
  243. {****************************************************************************}
  244. {* TFileStream *}
  245. {****************************************************************************}
  246. constructor TFileStream.Create(const AFileName: string; Mode: Word);
  247. begin
  248. FFileName:=AFileName;
  249. If Mode=fmcreate then
  250. FHandle:=FileCreate(AFileName)
  251. else
  252. FHAndle:=FileOpen(AFileName,Mode);
  253. If FHandle<0 then
  254. If Mode=fmcreate then
  255. raise EFCreateError.createfmt(SFCreateError,[AFileName])
  256. else
  257. raise EFOpenError.Createfmt(SFOpenError,[AFilename]);
  258. end;
  259. destructor TFileStream.Destroy;
  260. begin
  261. FileClose(FHandle);
  262. end;
  263. Procedure TFileStream.SetSize(NewSize: Longint);
  264. begin
  265. FileTruncate(FHandle,NewSize);
  266. end;
  267. function TFileStream.Seek(Offset: Longint; Origin: Word): Longint;
  268. begin
  269. Result:=FileSeek(FHandle,Offset,Origin);
  270. end;
  271. {****************************************************************************}
  272. {* TCustomMemoryStream *}
  273. {****************************************************************************}
  274. procedure TCustomMemoryStream.SetPointer(Ptr: Pointer; ASize: Longint);
  275. begin
  276. FMemory:=Ptr;
  277. FSize:=ASize;
  278. end;
  279. function TCustomMemoryStream.Read(var Buffer; Count: Longint): Longint;
  280. begin
  281. Result:=0;
  282. If (FSize>0) and (FPosition<Fsize) then
  283. begin
  284. Result:=FSize-FPosition;
  285. If Result>Count then Result:=Count;
  286. Move ((FMemory+FPosition)^,Buffer,Result);
  287. FPosition:=Fposition+Result;
  288. end;
  289. end;
  290. function TCustomMemoryStream.Seek(Offset: Longint; Origin: Word): Longint;
  291. begin
  292. Case Origin of
  293. soFromBeginning : FPosition:=Offset;
  294. soFromEnd : FPosition:=FSize+Offset;
  295. soFromCurrent : FpoSition:=FPosition+Offset;
  296. end;
  297. Result:=FPosition;
  298. end;
  299. procedure TCustomMemoryStream.SaveToStream(Stream: TStream);
  300. begin
  301. if FSize>0 then Stream.WriteBuffer (FMemory^,FSize);
  302. end;
  303. procedure TCustomMemoryStream.SaveToFile(const FileName: string);
  304. Var S : TFileStream;
  305. begin
  306. Try
  307. S:=TFileStream.Create (FileName,fmCreate);
  308. SaveToStream(S);
  309. finally
  310. S.free;
  311. end;
  312. end;
  313. {****************************************************************************}
  314. {* TMemoryStream *}
  315. {****************************************************************************}
  316. Const TMSGrow = 4096; { Use 4k blocks. }
  317. procedure TMemoryStream.SetCapacity(NewCapacity: Longint);
  318. begin
  319. SetPointer (Realloc(NewCapacity),Fsize);
  320. FCapacity:=NewCapacity;
  321. end;
  322. function TMemoryStream.Realloc(var NewCapacity: Longint): Pointer;
  323. Var MoveSize : Longint;
  324. begin
  325. If NewCapacity>0 Then // round off to block size.
  326. NewCapacity := (NewCapacity + (TMSGrow-1)) and not (TMSGROW-1);
  327. // Only now check !
  328. If NewCapacity=FCapacity then
  329. Result:=FMemory
  330. else
  331. If NewCapacity=0 then
  332. FreeMem (FMemory,Fcapacity)
  333. else
  334. begin
  335. GetMem (Result,NewCapacity);
  336. If Result=Nil then
  337. Raise EStreamError.Create(SMemoryStreamError);
  338. If FCapacity>0 then
  339. begin
  340. MoveSize:=FSize;
  341. If MoveSize>NewCapacity then MoveSize:=NewCapacity;
  342. Move (Fmemory^,Result^,MoveSize);
  343. FreeMem (FMemory,FCapacity);
  344. end;
  345. end;
  346. end;
  347. destructor TMemoryStream.Destroy;
  348. begin
  349. Clear;
  350. Inherited Destroy;
  351. end;
  352. procedure TMemoryStream.Clear;
  353. begin
  354. FSize:=0;
  355. FPosition:=0;
  356. SetCapacity (0);
  357. end;
  358. procedure TMemoryStream.LoadFromStream(Stream: TStream);
  359. begin
  360. Stream.Position:=0;
  361. SetSize(Stream.Size);
  362. If FSize>0 then Stream.ReadBuffer(FMemory^,FSize);
  363. end;
  364. procedure TMemoryStream.LoadFromFile(const FileName: string);
  365. Var S : TFileStream;
  366. begin
  367. Try
  368. S:=TFileStream.Create (FileName,fmOpenRead);
  369. LoadFromStream(S);
  370. finally
  371. S.free;
  372. end;
  373. end;
  374. procedure TMemoryStream.SetSize(NewSize: Longint);
  375. begin
  376. SetCapacity (NewSize);
  377. FSize:=NewSize;
  378. IF FPosition>FSize then
  379. FPosition:=FSize;
  380. end;
  381. function TMemoryStream.Write(const Buffer; Count: Longint): Longint;
  382. Var NewPos : Longint;
  383. begin
  384. If Count=0 then
  385. exit(0);
  386. NewPos:=FPosition+Count;
  387. If NewPos>Fsize then
  388. begin
  389. IF NewPos>FCapacity then
  390. SetCapacity (NewPos);
  391. FSize:=Newpos;
  392. end;
  393. System.Move (Buffer,(FMemory+FPosition)^,Count);
  394. FPosition:=NewPos;
  395. Result:=Count;
  396. end;
  397. {****************************************************************************}
  398. {* TStringStream *}
  399. {****************************************************************************}
  400. procedure TStringStream.SetSize(NewSize: Longint);
  401. begin
  402. //!! Setlength(FDataString,NewSize);
  403. If FPosition>NewSize then FPosition:=NewSize;
  404. end;
  405. constructor TStringStream.Create(const AString: string);
  406. begin
  407. Inherited create;
  408. FDataString:=AString;
  409. end;
  410. function TStringStream.Read(var Buffer; Count: Longint): Longint;
  411. begin
  412. Result:=Length(FDataString)-FPosition;
  413. If Result>Count then Result:=Count;
  414. // This supposes FDataString to be of type AnsiString !
  415. //!! Move (Pchar(FDataString)[FPosition],Buffer,Count);
  416. FPosition:=FPosition+Count;
  417. end;
  418. function TStringStream.ReadString(Count: Longint): string;
  419. Var NewLen : Longint;
  420. begin
  421. NewLen:=Length(FDataString)-FPosition;
  422. If NewLen>Count then NewLen:=Count;
  423. //!! SetLength(Result,NewLen);
  424. //!! Read (Pointer(Result)^,NewLen);
  425. ReadString:='';
  426. end;
  427. function TStringStream.Seek(Offset: Longint; Origin: Word): Longint;
  428. begin
  429. Case Origin of
  430. soFromBeginning : FPosition:=Offset;
  431. soFromEnd : FPosition:=Length(FDataString)+Offset;
  432. soFromCurrent : FpoSition:=FPosition+Offset;
  433. end;
  434. If FPosition>Length(FDataString) then FPosition:=Length(FDataString);
  435. If FPosition<0 then FPosition:=0;
  436. Result:=FPosition;
  437. end;
  438. function TStringStream.Write(const Buffer; Count: Longint): Longint;
  439. begin
  440. Result:=Count;
  441. SetSize(FPosition+Count);
  442. // This supposes that FDataString is of type AnsiString)
  443. //!! Move (Buffer,PCHar(FDataString)[Fposition],Count);
  444. FPosition:=FPosition+Count;
  445. end;
  446. procedure TStringStream.WriteString(const AString: string);
  447. begin
  448. //!! Write (PChar(Astring)[0],Length(AString));
  449. end;
  450. {****************************************************************************}
  451. {* TResourceStream *}
  452. {****************************************************************************}
  453. procedure TResourceStream.Initialize(Instance: THandle; Name, ResType: PChar);
  454. begin
  455. end;
  456. constructor TResourceStream.Create(Instance: THandle; const ResName: string; ResType: PChar);
  457. begin
  458. end;
  459. constructor TResourceStream.CreateFromID(Instance: THandle; ResID: Integer; ResType: PChar);
  460. begin
  461. end;
  462. destructor TResourceStream.Destroy;
  463. begin
  464. end;
  465. function TResourceStream.Write(const Buffer; Count: Longint): Longint;
  466. begin
  467. Write:=0;
  468. end;
  469. {
  470. $Log$
  471. Revision 1.2 2000-07-13 11:33:00 michael
  472. + removed logs
  473. }