streams.inc 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977
  1. {
  2. This file is part of the Free Component Library (FCL)
  3. Copyright (c) 1999-2000 by the Free Pascal development team
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. **********************************************************************}
  10. {****************************************************************************}
  11. {* TStream *}
  12. {****************************************************************************}
  13. procedure TStream.ReadNotImplemented;
  14. begin
  15. raise EStreamError.CreateFmt(SStreamNoReading, [ClassName]) at get_caller_addr(get_frame), get_caller_frame(get_frame);
  16. end;
  17. procedure TStream.WriteNotImplemented;
  18. begin
  19. raise EStreamError.CreateFmt(SStreamNoWriting, [ClassName]) at get_caller_addr(get_frame), get_caller_frame(get_frame);
  20. end;
  21. function TStream.Read(var Buffer; Count: Longint): Longint;
  22. begin
  23. ReadNotImplemented;
  24. Result := 0;
  25. end;
  26. function TStream.Read(Buffer: TBytes; Count: Longint): Longint;
  27. begin
  28. Result:=Read(Buffer,0,Count);
  29. end;
  30. function TStream.Read(Buffer: TBytes; aOffset, Count: Longint): Longint;
  31. begin
  32. Result:=Read(Buffer[aOffset],Count);
  33. end;
  34. function TStream.Write(const Buffer: TBytes; Offset, Count: Longint): Longint;
  35. begin
  36. Result:=Write(Buffer[Offset],Count);
  37. end;
  38. function TStream.Write(const Buffer: TBytes; Count: Longint): Longint;
  39. begin
  40. Result:=Write(Buffer,0,Count);
  41. end;
  42. function TStream.Write(const Buffer; Count: Longint): Longint;
  43. begin
  44. WriteNotImplemented;
  45. Result := 0;
  46. end;
  47. function TStream.GetPosition: Int64;
  48. begin
  49. Result:=Seek(0,soCurrent);
  50. end;
  51. procedure TStream.SetPosition(const Pos: Int64);
  52. begin
  53. Seek(pos,soBeginning);
  54. end;
  55. procedure TStream.SetSize64(const NewSize: Int64);
  56. begin
  57. // Required because can't use overloaded functions in properties
  58. SetSize(NewSize);
  59. end;
  60. function TStream.GetSize: Int64;
  61. var
  62. p : int64;
  63. begin
  64. p:=Seek(0,soCurrent);
  65. GetSize:=Seek(0,soEnd);
  66. Seek(p,soBeginning);
  67. end;
  68. procedure TStream.SetSize(NewSize: Longint);
  69. begin
  70. // We do nothing. Pipe streams don't support this
  71. // As wel as possible read-ony streams !!
  72. end;
  73. procedure TStream.SetSize(const NewSize: Int64);
  74. begin
  75. // Backwards compatibility that calls the longint SetSize
  76. if (NewSize<Low(longint)) or
  77. (NewSize>High(longint)) then
  78. raise ERangeError.Create(SRangeError);
  79. SetSize(longint(NewSize));
  80. end;
  81. function TStream.Seek(Offset: Longint; Origin: Word): Longint;
  82. type
  83. TSeek64 = function(const offset:Int64;Origin:TSeekorigin):Int64 of object;
  84. var
  85. CurrSeek,
  86. TStreamSeek : TSeek64;
  87. CurrClass : TClass;
  88. begin
  89. // Redirect calls to 64bit Seek, but we can't call the 64bit Seek
  90. // from TStream, because then we end up in an infinite loop
  91. CurrSeek:=nil;
  92. CurrClass:=Classtype;
  93. while (CurrClass<>nil) and
  94. (CurrClass<>TStream) do
  95. CurrClass:=CurrClass.Classparent;
  96. if CurrClass<>nil then
  97. begin
  98. CurrSeek:[email protected];
  99. TStreamSeek:=@TStream(@CurrClass).Seek;
  100. if TMethod(TStreamSeek).Code=TMethod(CurrSeek).Code then
  101. CurrSeek:=nil;
  102. end;
  103. if CurrSeek<>nil then
  104. Result:=Seek(Int64(offset),TSeekOrigin(origin))
  105. else
  106. raise EStreamError.CreateFmt(SSeekNotImplemented,[ClassName]);
  107. end;
  108. procedure TStream.Discard(const Count: Int64);
  109. const
  110. CSmallSize =255;
  111. CLargeMaxBuffer =32*1024; // 32 KiB
  112. var
  113. Buffer: array[1..CSmallSize] of Byte;
  114. begin
  115. if Count=0 then
  116. Exit;
  117. if Count<=SizeOf(Buffer) then
  118. ReadBuffer(Buffer,Count)
  119. else
  120. DiscardLarge(Count,CLargeMaxBuffer);
  121. end;
  122. procedure TStream.DiscardLarge(Count: int64; const MaxBufferSize: Longint);
  123. var
  124. Buffer: array of Byte;
  125. begin
  126. if Count=0 then
  127. Exit;
  128. if Count>MaxBufferSize then
  129. SetLength(Buffer,MaxBufferSize)
  130. else
  131. SetLength(Buffer,Count);
  132. while (Count>=Length(Buffer)) do
  133. begin
  134. ReadBuffer(Buffer[0],Length(Buffer));
  135. Dec(Count,Length(Buffer));
  136. end;
  137. if Count>0 then
  138. ReadBuffer(Buffer[0],Count);
  139. end;
  140. procedure TStream.InvalidSeek;
  141. begin
  142. raise EStreamError.CreateFmt(SStreamInvalidSeek, [ClassName]) at get_caller_addr(get_frame), get_caller_frame(get_frame);
  143. end;
  144. procedure TStream.FakeSeekForward(Offset: Int64; const Origin: TSeekOrigin; const Pos: Int64);
  145. begin
  146. if Origin=soBeginning then
  147. Dec(Offset,Pos);
  148. if (Offset<0) or (Origin=soEnd) then
  149. InvalidSeek;
  150. if Offset>0 then
  151. Discard(Offset);
  152. end;
  153. function TStream.Seek(const Offset: Int64; Origin: TSeekorigin): Int64;
  154. begin
  155. // Backwards compatibility that calls the longint Seek
  156. if (Offset<Low(longint)) or
  157. (Offset>High(longint)) then
  158. raise ERangeError.Create(SRangeError);
  159. Result:=Seek(longint(Offset),ord(Origin));
  160. end;
  161. function TStream.ReadData(Buffer: Pointer; Count: NativeInt): NativeInt;
  162. begin
  163. Result:=Read(Buffer^,Count);
  164. end;
  165. function TStream.ReadData(const Buffer: TBytes; Count: NativeInt): NativeInt;
  166. begin
  167. Result:=Read(Buffer,0,Count);
  168. end;
  169. function TStream.ReadData(var Buffer: Boolean): NativeInt;
  170. begin
  171. Result:=Read(Buffer,sizeOf(Buffer));
  172. end;
  173. function TStream.ReadMaxSizeData(Var Buffer; aSize,aCount : NativeInt) : NativeInt;
  174. Var
  175. CP : Int64;
  176. begin
  177. if aCount<=aSize then
  178. Result:=read(Buffer,aCount)
  179. else
  180. begin
  181. Result:=Read(Buffer,aSize);
  182. CP:=Position;
  183. Result:=Result+Seek(aCount-aSize,soCurrent)-CP;
  184. end
  185. end;
  186. function TStream.WriteMaxSizeData(Const Buffer; aSize,aCount : NativeInt) : NativeInt;
  187. Var
  188. CP : Int64;
  189. begin
  190. if aCount<=aSize then
  191. Result:=Write(Buffer,aCount)
  192. else
  193. begin
  194. Result:=Write(Buffer,aSize);
  195. CP:=Position;
  196. Result:=Result+Seek(aCount-aSize,soCurrent)-CP;
  197. end
  198. end;
  199. procedure TStream.WriteExactSizeData(const Buffer; aSize, aCount: NativeInt);
  200. begin
  201. // Embarcadero docs mentions no exception. Does not seem very logical
  202. WriteMaxSizeData(Buffer,aSize,ACount);
  203. end;
  204. procedure TStream.ReadExactSizeData(var Buffer; aSize, aCount: NativeInt);
  205. begin
  206. if ReadMaxSizeData(Buffer,aSize,ACount)<>aCount then
  207. Raise EReadError.Create(SReadError);
  208. end;
  209. function TStream.ReadData(var Buffer: Boolean; Count: NativeInt): NativeInt;
  210. begin
  211. Result:=ReadMaxSizeData(Buffer,SizeOf(Buffer),Count);
  212. end;
  213. function TStream.ReadData(var Buffer: AnsiChar): NativeInt;
  214. begin
  215. Result:=Read(Buffer,sizeOf(Buffer));
  216. end;
  217. function TStream.ReadData(var Buffer: AnsiChar; Count: NativeInt): NativeInt;
  218. begin
  219. Result:=ReadMaxSizeData(Buffer,SizeOf(Buffer),Count);
  220. end;
  221. function TStream.ReadData(var Buffer: WideChar): NativeInt;
  222. begin
  223. Result:=Read(Buffer,sizeOf(Buffer));
  224. end;
  225. function TStream.ReadData(var Buffer: WideChar; Count: NativeInt): NativeInt;
  226. begin
  227. Result:=ReadMaxSizeData(Buffer,SizeOf(Buffer),Count);
  228. end;
  229. function TStream.ReadData(var Buffer: Int8): NativeInt;
  230. begin
  231. Result:=Read(Buffer,sizeOf(Buffer));
  232. end;
  233. function TStream.ReadData(var Buffer: Int8; Count: NativeInt): NativeInt;
  234. begin
  235. Result:=ReadMaxSizeData(Buffer,SizeOf(Buffer),Count);
  236. end;
  237. function TStream.ReadData(var Buffer: UInt8): NativeInt;
  238. begin
  239. Result:=Read(Buffer,sizeOf(Buffer));
  240. end;
  241. function TStream.ReadData(var Buffer: UInt8; Count: NativeInt): NativeInt;
  242. begin
  243. Result:=ReadMaxSizeData(Buffer,SizeOf(Buffer),Count);
  244. end;
  245. function TStream.ReadData(var Buffer: Int16): NativeInt;
  246. begin
  247. Result:=Read(Buffer,sizeOf(Buffer));
  248. end;
  249. function TStream.ReadData(var Buffer: Int16; Count: NativeInt): NativeInt;
  250. begin
  251. Result:=ReadMaxSizeData(Buffer,SizeOf(Buffer),Count);
  252. end;
  253. function TStream.ReadData(var Buffer: UInt16): NativeInt;
  254. begin
  255. Result:=Read(Buffer,sizeOf(Buffer));
  256. end;
  257. function TStream.ReadData(var Buffer: UInt16; Count: NativeInt): NativeInt;
  258. begin
  259. Result:=ReadMaxSizeData(Buffer,SizeOf(Buffer),Count);
  260. end;
  261. function TStream.ReadData(var Buffer: Int32): NativeInt;
  262. begin
  263. Result:=Read(Buffer,sizeOf(Buffer));
  264. end;
  265. function TStream.ReadData(var Buffer: Int32; Count: NativeInt): NativeInt;
  266. begin
  267. Result:=ReadMaxSizeData(Buffer,SizeOf(Buffer),Count);
  268. end;
  269. function TStream.ReadData(var Buffer: UInt32): NativeInt;
  270. begin
  271. Result:=Read(Buffer,sizeOf(Buffer));
  272. end;
  273. function TStream.ReadData(var Buffer: UInt32; Count: NativeInt): NativeInt;
  274. begin
  275. Result:=ReadMaxSizeData(Buffer,SizeOf(Buffer),Count);
  276. end;
  277. function TStream.ReadData(var Buffer: Int64): NativeInt;
  278. begin
  279. Result:=Read(Buffer,sizeOf(Buffer));
  280. end;
  281. function TStream.ReadData(var Buffer: Int64; Count: NativeInt): NativeInt;
  282. begin
  283. Result:=ReadMaxSizeData(Buffer,SizeOf(Buffer),Count);
  284. end;
  285. function TStream.ReadData(var Buffer: UInt64): NativeInt;
  286. begin
  287. Result:=Read(Buffer,sizeOf(Buffer));
  288. end;
  289. function TStream.ReadData(var Buffer: UInt64; Count: NativeInt): NativeInt;
  290. begin
  291. Result:=ReadMaxSizeData(Buffer,SizeOf(Buffer),Count);
  292. end;
  293. function TStream.ReadData(var Buffer: Single): NativeInt;
  294. begin
  295. Result:=Read(Buffer,sizeOf(Buffer));
  296. end;
  297. function TStream.ReadData(var Buffer: Single; Count: NativeInt): NativeInt;
  298. begin
  299. Result:=ReadMaxSizeData(Buffer,SizeOf(Buffer),Count);
  300. end;
  301. function TStream.ReadData(var Buffer: Double): NativeInt;
  302. begin
  303. Result:=Read(Buffer,sizeOf(Buffer));
  304. end;
  305. function TStream.ReadData(var Buffer: Double; Count: NativeInt): NativeInt;
  306. begin
  307. Result:=ReadMaxSizeData(Buffer,SizeOf(Buffer),Count);
  308. end;
  309. function TStream.ReadData(var Buffer: Extended): NativeInt;
  310. begin
  311. Result:=Read(Buffer,sizeOf(Buffer));
  312. end;
  313. function TStream.ReadData(var Buffer: Extended; Count: NativeInt): NativeInt;
  314. begin
  315. Result:=ReadMaxSizeData(Buffer,SizeOf(Buffer),Count);
  316. end;
  317. function TStream.ReadData(var Buffer: TExtended80Rec): NativeInt;
  318. begin
  319. Result:=Read(Buffer,sizeOf(Buffer));
  320. end;
  321. function TStream.ReadData(var Buffer: TExtended80Rec; Count: NativeInt): NativeInt;
  322. begin
  323. Result:=ReadMaxSizeData(Buffer,SizeOf(Buffer),Count);
  324. end;
  325. procedure TStream.ReadBuffer(var Buffer; Count: Longint);
  326. Var
  327. r,t : longint;
  328. begin
  329. t:=0;
  330. repeat
  331. r:=Read(PByte(@Buffer)[t],Count-t);
  332. inc(t,r);
  333. until (t=Count) or (r<=0);
  334. if (t<Count) then
  335. Raise EReadError.Create(SReadError);
  336. end;
  337. procedure TStream.ReadBuffer(var Buffer: TBytes; Count: NativeInt);
  338. begin
  339. ReadBuffer(Buffer,0,Count);
  340. end;
  341. procedure TStream.ReadBuffer(var Buffer: TBytes; Offset, Count: NativeInt);
  342. begin
  343. ReadBuffer(Buffer[OffSet],Count);
  344. end;
  345. procedure TStream.ReadBufferData(var Buffer: Boolean);
  346. begin
  347. ReadBuffer(Buffer,SizeOf(Buffer));
  348. end;
  349. procedure TStream.ReadBufferData(var Buffer: Boolean; Count: NativeInt);
  350. begin
  351. ReadExactSizeData(Buffer,SizeOf(Buffer),Count);
  352. end;
  353. procedure TStream.ReadBufferData(var Buffer: AnsiChar);
  354. begin
  355. ReadBuffer(Buffer,SizeOf(Buffer));
  356. end;
  357. procedure TStream.ReadBufferData(var Buffer: AnsiChar; Count: NativeInt);
  358. begin
  359. ReadExactSizeData(Buffer,SizeOf(Buffer),Count);
  360. end;
  361. procedure TStream.ReadBufferData(var Buffer: WideChar);
  362. begin
  363. ReadBuffer(Buffer,SizeOf(Buffer));
  364. end;
  365. procedure TStream.ReadBufferData(var Buffer: WideChar; Count: NativeInt);
  366. begin
  367. ReadExactSizeData(Buffer,SizeOf(Buffer),Count);
  368. end;
  369. procedure TStream.ReadBufferData(var Buffer: Int8);
  370. begin
  371. ReadBuffer(Buffer,SizeOf(Buffer));
  372. end;
  373. procedure TStream.ReadBufferData(var Buffer: Int8; Count: NativeInt);
  374. begin
  375. ReadExactSizeData(Buffer,SizeOf(Buffer),Count);
  376. end;
  377. procedure TStream.ReadBufferData(var Buffer: UInt8);
  378. begin
  379. ReadBuffer(Buffer,SizeOf(Buffer));
  380. end;
  381. procedure TStream.ReadBufferData(var Buffer: UInt8; Count: NativeInt);
  382. begin
  383. ReadExactSizeData(Buffer,SizeOf(Buffer),Count);
  384. end;
  385. procedure TStream.ReadBufferData(var Buffer: Int16);
  386. begin
  387. ReadBuffer(Buffer,SizeOf(Buffer));
  388. end;
  389. procedure TStream.ReadBufferData(var Buffer: Int16; Count: NativeInt);
  390. begin
  391. ReadExactSizeData(Buffer,SizeOf(Buffer),Count);
  392. end;
  393. procedure TStream.ReadBufferData(var Buffer: UInt16);
  394. begin
  395. ReadBuffer(Buffer,SizeOf(Buffer));
  396. end;
  397. procedure TStream.ReadBufferData(var Buffer: UInt16; Count: NativeInt);
  398. begin
  399. ReadExactSizeData(Buffer,SizeOf(Buffer),Count);
  400. end;
  401. procedure TStream.ReadBufferData(var Buffer: Int32);
  402. begin
  403. ReadBuffer(Buffer,SizeOf(Buffer));
  404. end;
  405. procedure TStream.ReadBufferData(var Buffer: Int32; Count: NativeInt);
  406. begin
  407. ReadExactSizeData(Buffer,SizeOf(Buffer),Count);
  408. end;
  409. procedure TStream.ReadBufferData(var Buffer: UInt32);
  410. begin
  411. ReadBuffer(Buffer,SizeOf(Buffer));
  412. end;
  413. procedure TStream.ReadBufferData(var Buffer: UInt32; Count: NativeInt);
  414. begin
  415. ReadExactSizeData(Buffer,SizeOf(Buffer),Count);
  416. end;
  417. procedure TStream.ReadBufferData(var Buffer: Int64);
  418. begin
  419. ReadBuffer(Buffer,SizeOf(Buffer));
  420. end;
  421. procedure TStream.ReadBufferData(var Buffer: Int64; Count: NativeInt);
  422. begin
  423. ReadExactSizeData(Buffer,SizeOf(Buffer),Count);
  424. end;
  425. procedure TStream.ReadBufferData(var Buffer: UInt64);
  426. begin
  427. ReadBuffer(Buffer,SizeOf(Buffer));
  428. end;
  429. procedure TStream.ReadBufferData(var Buffer: UInt64; Count: NativeInt);
  430. begin
  431. ReadExactSizeData(Buffer,SizeOf(Buffer),Count);
  432. end;
  433. procedure TStream.ReadBufferData(var Buffer: Single);
  434. begin
  435. ReadBuffer(Buffer,SizeOf(Buffer));
  436. end;
  437. procedure TStream.ReadBufferData(var Buffer: Single; Count: NativeInt);
  438. begin
  439. ReadExactSizeData(Buffer,SizeOf(Buffer),Count);
  440. end;
  441. procedure TStream.ReadBufferData(var Buffer: Double);
  442. begin
  443. ReadBuffer(Buffer,SizeOf(Buffer));
  444. end;
  445. procedure TStream.ReadBufferData(var Buffer: Double; Count: NativeInt);
  446. begin
  447. ReadExactSizeData(Buffer,SizeOf(Buffer),Count);
  448. end;
  449. procedure TStream.ReadBufferData(var Buffer: Extended);
  450. begin
  451. ReadBuffer(Buffer,SizeOf(Buffer));
  452. end;
  453. procedure TStream.ReadBufferData(var Buffer: Extended; Count: NativeInt);
  454. begin
  455. ReadExactSizeData(Buffer,SizeOf(Buffer),Count);
  456. end;
  457. procedure TStream.ReadBufferData(var Buffer: TExtended80Rec);
  458. begin
  459. ReadBuffer(Buffer,SizeOf(Buffer));
  460. end;
  461. procedure TStream.ReadBufferData(var Buffer: TExtended80Rec; Count: NativeInt);
  462. begin
  463. ReadExactSizeData(Buffer,SizeOf(Buffer),Count);
  464. end;
  465. procedure TStream.WriteBuffer(const Buffer; Count: Longint);
  466. var
  467. r,t : Longint;
  468. begin
  469. T:=0;
  470. Repeat
  471. r:=Write(PByte(@Buffer)[t],Count-t);
  472. inc(t,r);
  473. Until (t=count) or (r<=0);
  474. if (t<Count) then
  475. Raise EWriteError.Create(SWriteError);
  476. end;
  477. procedure TStream.WriteBuffer(const Buffer: TBytes; Count: NativeInt);
  478. begin
  479. WriteBuffer(Buffer,0,Count);
  480. end;
  481. procedure TStream.WriteBuffer(const Buffer: TBytes; Offset, Count: NativeInt);
  482. begin
  483. WriteBuffer(Buffer[Offset],Count);
  484. end;
  485. function TStream.WriteData(const Buffer: TBytes; Count: NativeInt): NativeInt;
  486. begin
  487. Result:=Write(Buffer, 0, Count);
  488. end;
  489. function TStream.WriteData(const Buffer: Pointer; Count: NativeInt): NativeInt;
  490. begin
  491. Result:=Write(Buffer^, Count);
  492. end;
  493. function TStream.WriteData(const Buffer: Boolean): NativeInt;
  494. begin
  495. Result:=Write(Buffer,SizeOf(Buffer));
  496. end;
  497. function TStream.WriteData(const Buffer: Boolean; Count: NativeInt): NativeInt;
  498. begin
  499. Result:=WriteMaxSizeData(Buffer,SizeOf(Buffer),Count);
  500. end;
  501. function TStream.WriteData(const Buffer: AnsiChar): NativeInt;
  502. begin
  503. Result:=Write(Buffer,SizeOf(Buffer));
  504. end;
  505. function TStream.WriteData(const Buffer: AnsiChar; Count: NativeInt): NativeInt;
  506. begin
  507. Result:=WriteMaxSizeData(Buffer,SizeOf(Buffer),Count);
  508. end;
  509. function TStream.WriteData(const Buffer: WideChar): NativeInt;
  510. begin
  511. Result:=Write(Buffer,SizeOf(Buffer));
  512. end;
  513. function TStream.WriteData(const Buffer: WideChar; Count: NativeInt): NativeInt;
  514. begin
  515. Result:=WriteMaxSizeData(Buffer,SizeOf(Buffer),Count);
  516. end;
  517. function TStream.WriteData(const Buffer: Int8): NativeInt;
  518. begin
  519. Result:=Write(Buffer,SizeOf(Buffer));
  520. end;
  521. function TStream.WriteData(const Buffer: Int8; Count: NativeInt): NativeInt;
  522. begin
  523. Result:=WriteMaxSizeData(Buffer,SizeOf(Buffer),Count);
  524. end;
  525. function TStream.WriteData(const Buffer: UInt8): NativeInt;
  526. begin
  527. Result:=Write(Buffer,SizeOf(Buffer));
  528. end;
  529. function TStream.WriteData(const Buffer: UInt8; Count: NativeInt): NativeInt;
  530. begin
  531. Result:=WriteMaxSizeData(Buffer,SizeOf(Buffer),Count);
  532. end;
  533. function TStream.WriteData(const Buffer: Int16): NativeInt;
  534. begin
  535. Result:=Write(Buffer,SizeOf(Buffer));
  536. end;
  537. function TStream.WriteData(const Buffer: Int16; Count: NativeInt): NativeInt;
  538. begin
  539. Result:=WriteMaxSizeData(Buffer,SizeOf(Buffer),Count);
  540. end;
  541. function TStream.WriteData(const Buffer: UInt16): NativeInt;
  542. begin
  543. Result:=Write(Buffer,SizeOf(Buffer));
  544. end;
  545. function TStream.WriteData(const Buffer: UInt16; Count: NativeInt): NativeInt;
  546. begin
  547. Result:=WriteMaxSizeData(Buffer,SizeOf(Buffer),Count);
  548. end;
  549. function TStream.WriteData(const Buffer: Int32): NativeInt;
  550. begin
  551. Result:=Write(Buffer,SizeOf(Buffer));
  552. end;
  553. function TStream.WriteData(const Buffer: Int32; Count: NativeInt): NativeInt;
  554. begin
  555. Result:=WriteMaxSizeData(Buffer,SizeOf(Buffer),Count);
  556. end;
  557. function TStream.WriteData(const Buffer: UInt32): NativeInt;
  558. begin
  559. Result:=Write(Buffer,SizeOf(Buffer));
  560. end;
  561. function TStream.WriteData(const Buffer: UInt32; Count: NativeInt): NativeInt;
  562. begin
  563. Result:=WriteMaxSizeData(Buffer,SizeOf(Buffer),Count);
  564. end;
  565. function TStream.WriteData(const Buffer: Int64): NativeInt;
  566. begin
  567. Result:=Write(Buffer,SizeOf(Buffer));
  568. end;
  569. function TStream.WriteData(const Buffer: Int64; Count: NativeInt): NativeInt;
  570. begin
  571. Result:=WriteMaxSizeData(Buffer,SizeOf(Buffer),Count);
  572. end;
  573. function TStream.WriteData(const Buffer: UInt64): NativeInt;
  574. begin
  575. Result:=Write(Buffer,SizeOf(Buffer));
  576. end;
  577. function TStream.WriteData(const Buffer: UInt64; Count: NativeInt): NativeInt;
  578. begin
  579. Result:=WriteMaxSizeData(Buffer,SizeOf(Buffer),Count);
  580. end;
  581. function TStream.WriteData(const Buffer: Single): NativeInt;
  582. begin
  583. Result:=Write(Buffer,SizeOf(Buffer));
  584. end;
  585. function TStream.WriteData(const Buffer: Single; Count: NativeInt): NativeInt;
  586. begin
  587. Result:=WriteMaxSizeData(Buffer,SizeOf(Buffer),Count);
  588. end;
  589. function TStream.WriteData(const Buffer: Double): NativeInt;
  590. begin
  591. Result:=Write(Buffer,SizeOf(Buffer));
  592. end;
  593. function TStream.WriteData(const Buffer: Double; Count: NativeInt): NativeInt;
  594. begin
  595. Result:=WriteMaxSizeData(Buffer,SizeOf(Buffer),Count);
  596. end;
  597. function TStream.WriteData(const Buffer: Extended): NativeInt;
  598. begin
  599. Result:=Write(Buffer,SizeOf(Buffer));
  600. end;
  601. function TStream.WriteData(const Buffer: Extended; Count: NativeInt): NativeInt;
  602. begin
  603. Result:=WriteMaxSizeData(Buffer,SizeOf(Buffer),Count);
  604. end;
  605. function TStream.WriteData(const Buffer: TExtended80Rec): NativeInt;
  606. begin
  607. Result:=Write(Buffer,SizeOf(Buffer));
  608. end;
  609. function TStream.WriteData(const Buffer: TExtended80Rec; Count: NativeInt): NativeInt;
  610. begin
  611. Result:=WriteMaxSizeData(Buffer,SizeOf(Buffer),Count);
  612. end;
  613. procedure TStream.WriteBufferData(Buffer: Integer);
  614. begin
  615. WriteBuffer(Buffer,SizeOf(Buffer));
  616. end;
  617. procedure TStream.WriteBufferData(Buffer: Integer; Count: NativeInt);
  618. begin
  619. WriteMaxSizeData(Buffer,SizeOf(Buffer),Count);
  620. end;
  621. procedure TStream.WriteBufferData(Buffer: Boolean);
  622. begin
  623. WriteBuffer(Buffer,SizeOf(Buffer));
  624. end;
  625. procedure TStream.WriteBufferData(Buffer: Boolean; Count: NativeInt);
  626. begin
  627. WriteExactSizeData(Buffer,SizeOf(Buffer),Count);
  628. end;
  629. procedure TStream.WriteBufferData(Buffer: AnsiChar);
  630. begin
  631. WriteBuffer(Buffer,SizeOf(Buffer));
  632. end;
  633. procedure TStream.WriteBufferData(Buffer: AnsiChar; Count: NativeInt);
  634. begin
  635. WriteExactSizeData(Buffer,SizeOf(Buffer),Count);
  636. end;
  637. procedure TStream.WriteBufferData(Buffer: WideChar);
  638. begin
  639. WriteBuffer(Buffer,SizeOf(Buffer));
  640. end;
  641. procedure TStream.WriteBufferData(Buffer: WideChar; Count: NativeInt);
  642. begin
  643. WriteExactSizeData(Buffer,SizeOf(Buffer),Count);
  644. end;
  645. procedure TStream.WriteBufferData(Buffer: Int8);
  646. begin
  647. WriteBuffer(Buffer,SizeOf(Buffer));
  648. end;
  649. procedure TStream.WriteBufferData(Buffer: Int8; Count: NativeInt);
  650. begin
  651. WriteExactSizeData(Buffer,SizeOf(Buffer),Count);
  652. end;
  653. procedure TStream.WriteBufferData(Buffer: UInt8);
  654. begin
  655. WriteBuffer(Buffer,SizeOf(Buffer));
  656. end;
  657. procedure TStream.WriteBufferData(Buffer: UInt8; Count: NativeInt);
  658. begin
  659. WriteExactSizeData(Buffer,SizeOf(Buffer),Count);
  660. end;
  661. procedure TStream.WriteBufferData(Buffer: Int16);
  662. begin
  663. WriteBuffer(Buffer,SizeOf(Buffer));
  664. end;
  665. procedure TStream.WriteBufferData(Buffer: Int16; Count: NativeInt);
  666. begin
  667. WriteExactSizeData(Buffer,SizeOf(Buffer),Count);
  668. end;
  669. procedure TStream.WriteBufferData(Buffer: UInt16);
  670. begin
  671. WriteBuffer(Buffer,SizeOf(Buffer));
  672. end;
  673. procedure TStream.WriteBufferData(Buffer: UInt16; Count: NativeInt);
  674. begin
  675. WriteExactSizeData(Buffer,SizeOf(Buffer),Count);
  676. end;
  677. procedure TStream.WriteBufferData(Buffer: UInt32);
  678. begin
  679. WriteBuffer(Buffer,SizeOf(Buffer));
  680. end;
  681. procedure TStream.WriteBufferData(Buffer: UInt32; Count: NativeInt);
  682. begin
  683. WriteExactSizeData(Buffer,SizeOf(Buffer),Count);
  684. end;
  685. procedure TStream.WriteBufferData(Buffer: Int64);
  686. begin
  687. WriteBuffer(Buffer,SizeOf(Buffer));
  688. end;
  689. procedure TStream.WriteBufferData(Buffer: Int64; Count: NativeInt);
  690. begin
  691. WriteExactSizeData(Buffer,SizeOf(Buffer),Count);
  692. end;
  693. procedure TStream.WriteBufferData(Buffer: UInt64);
  694. begin
  695. WriteBuffer(Buffer,SizeOf(Buffer));
  696. end;
  697. procedure TStream.WriteBufferData(Buffer: UInt64; Count: NativeInt);
  698. begin
  699. WriteExactSizeData(Buffer,SizeOf(Buffer),Count);
  700. end;
  701. procedure TStream.WriteBufferData(Buffer: Single);
  702. begin
  703. WriteBuffer(Buffer,SizeOf(Buffer));
  704. end;
  705. procedure TStream.WriteBufferData(Buffer: Single; Count: NativeInt);
  706. begin
  707. WriteExactSizeData(Buffer,SizeOf(Buffer),Count);
  708. end;
  709. procedure TStream.WriteBufferData(Buffer: Double);
  710. begin
  711. WriteBuffer(Buffer,SizeOf(Buffer));
  712. end;
  713. procedure TStream.WriteBufferData(Buffer: Double; Count: NativeInt);
  714. begin
  715. WriteExactSizeData(Buffer,SizeOf(Buffer),Count);
  716. end;
  717. procedure TStream.WriteBufferData(Buffer: Extended);
  718. begin
  719. WriteBuffer(Buffer,SizeOf(Buffer));
  720. end;
  721. procedure TStream.WriteBufferData(Buffer: Extended; Count: NativeInt);
  722. begin
  723. WriteExactSizeData(Buffer,SizeOf(Buffer),Count);
  724. end;
  725. procedure TStream.WriteBufferData(Buffer: TExtended80Rec);
  726. begin
  727. WriteBuffer(Buffer,SizeOf(Buffer));
  728. end;
  729. procedure TStream.WriteBufferData(Buffer: TExtended80Rec; Count: NativeInt);
  730. begin
  731. WriteExactSizeData(Buffer,SizeOf(Buffer),Count);
  732. end;
  733. function TStream.CopyFrom(Source: TStream; Count: Int64): Int64;
  734. var
  735. Buffer: Pointer;
  736. BufferSize, i: LongInt;
  737. const
  738. MaxSize = $20000;
  739. begin
  740. Result:=0;
  741. if Count=0 then
  742. Source.Position:=0; // This WILL fail for non-seekable streams...
  743. BufferSize:=MaxSize;
  744. if (Count>0) and (Count<BufferSize) then
  745. BufferSize:=Count; // do not allocate more than needed
  746. GetMem(Buffer,BufferSize);
  747. try
  748. if Count=0 then
  749. repeat
  750. i:=Source.Read(buffer^,BufferSize);
  751. if i>0 then
  752. WriteBuffer(buffer^,i);
  753. Inc(Result,i);
  754. until i<BufferSize
  755. else
  756. while Count>0 do
  757. begin
  758. if Count>BufferSize then
  759. i:=BufferSize
  760. else
  761. i:=Count;
  762. Source.ReadBuffer(buffer^,i);
  763. WriteBuffer(buffer^,i);
  764. Dec(count,i);
  765. Inc(Result,i);
  766. end;
  767. finally
  768. FreeMem(Buffer);
  769. end;
  770. end;
  771. function TStream.ReadComponent(Instance: TComponent): TComponent;
  772. var
  773. Reader: TReader;
  774. begin
  775. Reader := TReader.Create(Self, 4096);
  776. try
  777. Result := Reader.ReadRootComponent(Instance);
  778. finally
  779. Reader.Free;
  780. end;
  781. end;
  782. function TStream.ReadComponentRes(Instance: TComponent): TComponent;
  783. begin
  784. ReadResHeader;
  785. Result := ReadComponent(Instance);
  786. end;
  787. procedure TStream.WriteComponent(Instance: TComponent);
  788. begin
  789. WriteDescendent(Instance, nil);
  790. end;
  791. procedure TStream.WriteComponentRes(const ResName: string; Instance: TComponent);
  792. begin
  793. WriteDescendentRes(ResName, Instance, nil);
  794. end;
  795. procedure TStream.WriteDescendent(Instance, Ancestor: TComponent);
  796. var
  797. Driver : TAbstractObjectWriter;
  798. Writer : TWriter;
  799. begin
  800. Driver := TBinaryObjectWriter.Create(Self, 4096);
  801. Try
  802. Writer := TWriter.Create(Driver);
  803. Try
  804. Writer.WriteDescendent(Instance, Ancestor);
  805. Finally
  806. Writer.Destroy;
  807. end;
  808. Finally
  809. Driver.Free;
  810. end;
  811. end;
  812. procedure TStream.WriteDescendentRes(const ResName: string; Instance, Ancestor: TComponent);
  813. var
  814. FixupInfo: Longint;
  815. begin
  816. { Write a resource header }
  817. WriteResourceHeader(ResName, FixupInfo);
  818. { Write the instance itself }
  819. WriteDescendent(Instance, Ancestor);
  820. { Insert the correct resource size into the resource header }
  821. FixupResourceHeader(FixupInfo);
  822. end;
  823. procedure TStream.WriteResourceHeader(const ResName: string; {!!!: out} var FixupInfo: Longint);
  824. var
  825. ResType, Flags : word;
  826. begin
  827. ResType:=NtoLE(word($000A));
  828. Flags:=NtoLE(word($1030));
  829. { Note: This is a Windows 16 bit resource }
  830. { Numeric resource type }
  831. WriteByte($ff);
  832. { Application defined data }
  833. WriteWord(ResType);
  834. { write the name as asciiz }
  835. WriteBuffer(ResName[1],length(ResName));
  836. WriteByte(0);
  837. { Movable, Pure and Discardable }
  838. WriteWord(Flags);
  839. { Placeholder for the resource size }
  840. WriteDWord(0);
  841. { Return current stream position so that the resource size can be
  842. inserted later }
  843. FixupInfo := Position;
  844. end;
  845. procedure TStream.FixupResourceHeader(FixupInfo: Longint);
  846. var
  847. ResSize,TmpResSize : Longint;
  848. begin
  849. ResSize := Position - FixupInfo;
  850. TmpResSize := NtoLE(longword(ResSize));
  851. { Insert the correct resource size into the placeholder written by
  852. WriteResourceHeader }
  853. Position := FixupInfo - 4;
  854. WriteDWord(TmpResSize);
  855. { Seek back to the end of the resource }
  856. Position := FixupInfo + ResSize;
  857. end;
  858. procedure TStream.ReadResHeader;
  859. var
  860. ResType, Flags : word;
  861. begin
  862. try
  863. { Note: This is a Windows 16 bit resource }
  864. { application specific resource ? }
  865. if ReadByte<>$ff then
  866. raise EInvalidImage.Create(SInvalidImage);
  867. ResType:=LEtoN(ReadWord);
  868. if ResType<>$000a then
  869. raise EInvalidImage.Create(SInvalidImage);
  870. { read name }
  871. while ReadByte<>0 do
  872. ;
  873. { check the access specifier }
  874. Flags:=LEtoN(ReadWord);
  875. if Flags<>$1030 then
  876. raise EInvalidImage.Create(SInvalidImage);
  877. { ignore the size }
  878. ReadDWord;
  879. except
  880. on EInvalidImage do
  881. raise;
  882. else
  883. raise EInvalidImage.create(SInvalidImage);
  884. end;
  885. end;
  886. function TStream.ReadByte : Byte;
  887. var
  888. b : Byte;
  889. begin
  890. ReadBuffer(b,1);
  891. ReadByte:=b;
  892. end;
  893. function TStream.ReadWord : Word;
  894. var
  895. w : Word;
  896. begin
  897. ReadBuffer(w,2);
  898. ReadWord:=w;
  899. end;
  900. function TStream.ReadDWord : Cardinal;
  901. var
  902. d : Cardinal;
  903. begin
  904. ReadBuffer(d,4);
  905. ReadDWord:=d;
  906. end;
  907. function TStream.ReadQWord: QWord;
  908. var
  909. q: QWord;
  910. begin
  911. ReadBuffer(q,8);
  912. ReadQWord:=q;
  913. end;
  914. Function TStream.ReadAnsiString : String;
  915. Var
  916. TheSize : Longint;
  917. P : PByte ;
  918. begin
  919. Result:='';
  920. ReadBuffer (TheSize,SizeOf(TheSize));
  921. SetLength(Result,TheSize);
  922. // Illegal typecast if no AnsiStrings defined.
  923. if TheSize>0 then
  924. begin
  925. ReadBuffer (Pointer(Result)^,TheSize);
  926. P:=Pointer(Result)+TheSize;
  927. p^:=0;
  928. end;
  929. end;
  930. Procedure TStream.WriteAnsiString (const S : String);
  931. Var L : Longint;
  932. begin
  933. L:=Length(S);
  934. WriteBuffer (L,SizeOf(L));
  935. WriteBuffer (Pointer(S)^,L);
  936. end;
  937. procedure TStream.WriteByte(b : Byte);
  938. begin
  939. WriteBuffer(b,1);
  940. end;
  941. procedure TStream.WriteWord(w : Word);
  942. begin
  943. WriteBuffer(w,2);
  944. end;
  945. procedure TStream.WriteDWord(d : Cardinal);
  946. begin
  947. WriteBuffer(d,4);
  948. end;
  949. procedure TStream.WriteQWord(q: QWord);
  950. begin
  951. WriteBuffer(q,8);
  952. end;
  953. {****************************************************************************}
  954. {* THandleStream *}
  955. {****************************************************************************}
  956. Constructor THandleStream.Create(AHandle: THandle);
  957. begin
  958. Inherited Create;
  959. FHandle:=AHandle;
  960. end;
  961. function THandleStream.Read(var Buffer; Count: Longint): Longint;
  962. begin
  963. Result:=FileRead(FHandle,Buffer,Count);
  964. If Result=-1 then Result:=0;
  965. end;
  966. function THandleStream.Write(const Buffer; Count: Longint): Longint;
  967. begin
  968. Result:=FileWrite (FHandle,Buffer,Count);
  969. If Result=-1 then Result:=0;
  970. end;
  971. Procedure THandleStream.SetSize(NewSize: Longint);
  972. begin
  973. SetSize(Int64(NewSize));
  974. end;
  975. Procedure THandleStream.SetSize(const NewSize: Int64);
  976. begin
  977. FileTruncate(FHandle,NewSize);
  978. end;
  979. function THandleStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
  980. begin
  981. Result:=FileSeek(FHandle,Offset,ord(Origin));
  982. end;
  983. {****************************************************************************}
  984. {* TFileStream *}
  985. {****************************************************************************}
  986. constructor TFileStream.Create(const AFileName: string; Mode: Word);
  987. begin
  988. Create(AFileName,Mode,438);
  989. end;
  990. constructor TFileStream.Create(const AFileName: string; Mode: Word; Rights: Cardinal);
  991. begin
  992. FFileName:=AFileName;
  993. If (Mode and fmCreate) > 0 then
  994. FHandle:=FileCreate(AFileName,Mode,Rights)
  995. else
  996. FHAndle:=FileOpen(AFileName,Mode);
  997. If (THandle(FHandle)=feInvalidHandle) then
  998. If Mode=fmcreate then
  999. raise EFCreateError.createfmt(SFCreateError,[AFileName])
  1000. else
  1001. raise EFOpenError.Createfmt(SFOpenError,[AFilename]);
  1002. end;
  1003. destructor TFileStream.Destroy;
  1004. begin
  1005. FileClose(FHandle);
  1006. end;
  1007. {****************************************************************************}
  1008. {* TCustomMemoryStream *}
  1009. {****************************************************************************}
  1010. procedure TCustomMemoryStream.SetPointer(Ptr: Pointer; ASize: PtrInt);
  1011. begin
  1012. FMemory:=Ptr;
  1013. FSize:=ASize;
  1014. end;
  1015. function TCustomMemoryStream.GetSize: Int64;
  1016. begin
  1017. Result:=FSize;
  1018. end;
  1019. function TCustomMemoryStream.GetPosition: Int64;
  1020. begin
  1021. Result:=FPosition;
  1022. end;
  1023. function TCustomMemoryStream.Read(var Buffer; Count: LongInt): LongInt;
  1024. begin
  1025. Result:=0;
  1026. If (FSize>0) and (FPosition<Fsize) and (FPosition>=0) then
  1027. begin
  1028. Result:=Count;
  1029. If (Result>(FSize-FPosition)) then
  1030. Result:=(FSize-FPosition);
  1031. Move ((FMemory+FPosition)^,Buffer,Result);
  1032. FPosition:=Fposition+Result;
  1033. end;
  1034. end;
  1035. function TCustomMemoryStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
  1036. begin
  1037. Case Word(Origin) of
  1038. soFromBeginning : FPosition:=Offset;
  1039. soFromEnd : FPosition:=FSize+Offset;
  1040. soFromCurrent : FPosition:=FPosition+Offset;
  1041. end;
  1042. if SizeBoundsSeek and (FPosition>FSize) then
  1043. FPosition:=FSize;
  1044. Result:=FPosition;
  1045. {$IFDEF DEBUG}
  1046. if Result < 0 then
  1047. raise Exception.Create('TCustomMemoryStream');
  1048. {$ENDIF}
  1049. end;
  1050. procedure TCustomMemoryStream.SaveToStream(Stream: TStream);
  1051. begin
  1052. if FSize>0 then Stream.WriteBuffer (FMemory^,FSize);
  1053. end;
  1054. procedure TCustomMemoryStream.SaveToFile(const FileName: string);
  1055. Var S : TFileStream;
  1056. begin
  1057. S:=TFileStream.Create (FileName,fmCreate);
  1058. Try
  1059. SaveToStream(S);
  1060. finally
  1061. S.free;
  1062. end;
  1063. end;
  1064. {****************************************************************************}
  1065. {* TMemoryStream *}
  1066. {****************************************************************************}
  1067. Const TMSGrow = 4096; { Use 4k blocks. }
  1068. procedure TMemoryStream.SetCapacity(NewCapacity: PtrInt);
  1069. begin
  1070. SetPointer (Realloc(NewCapacity),Fsize);
  1071. FCapacity:=NewCapacity;
  1072. end;
  1073. function TMemoryStream.Realloc(var NewCapacity: PtrInt): Pointer;
  1074. Var
  1075. GC : PtrInt;
  1076. begin
  1077. If NewCapacity<0 Then
  1078. NewCapacity:=0
  1079. else
  1080. begin
  1081. GC:=FCapacity + (FCapacity div 4);
  1082. // if growing, grow at least a quarter
  1083. if (NewCapacity>FCapacity) and (NewCapacity < GC) then
  1084. NewCapacity := GC;
  1085. // round off to block size.
  1086. NewCapacity := (NewCapacity + (TMSGrow-1)) and not (TMSGROW-1);
  1087. end;
  1088. // Only now check !
  1089. If NewCapacity=FCapacity then
  1090. Result:=FMemory
  1091. else
  1092. begin
  1093. Result:=Reallocmem(FMemory,Newcapacity);
  1094. If (Result=Nil) and (Newcapacity>0) then
  1095. Raise EStreamError.Create(SMemoryStreamError);
  1096. end;
  1097. end;
  1098. destructor TMemoryStream.Destroy;
  1099. begin
  1100. Clear;
  1101. Inherited Destroy;
  1102. end;
  1103. procedure TMemoryStream.Clear;
  1104. begin
  1105. FSize:=0;
  1106. FPosition:=0;
  1107. SetCapacity (0);
  1108. end;
  1109. procedure TMemoryStream.LoadFromStream(Stream: TStream);
  1110. begin
  1111. Stream.Position:=0;
  1112. SetSize(Stream.Size);
  1113. If FSize>0 then Stream.ReadBuffer(FMemory^,FSize);
  1114. end;
  1115. procedure TMemoryStream.LoadFromFile(const FileName: string);
  1116. Var S : TFileStream;
  1117. begin
  1118. S:=TFileStream.Create (FileName,fmOpenRead or fmShareDenyWrite);
  1119. Try
  1120. LoadFromStream(S);
  1121. finally
  1122. S.free;
  1123. end;
  1124. end;
  1125. procedure TMemoryStream.SetSize({$ifdef CPU64}const NewSize: Int64{$else}NewSize: LongInt{$endif});
  1126. begin
  1127. SetCapacity (NewSize);
  1128. FSize:=NewSize;
  1129. IF FPosition>FSize then
  1130. FPosition:=FSize;
  1131. end;
  1132. function TMemoryStream.Write(const Buffer; Count: LongInt): LongInt;
  1133. Var NewPos : PtrInt;
  1134. begin
  1135. If (Count=0) or (FPosition<0) then
  1136. exit(0);
  1137. NewPos:=FPosition+Count;
  1138. If NewPos>Fsize then
  1139. begin
  1140. IF NewPos>FCapacity then
  1141. SetCapacity (NewPos);
  1142. FSize:=Newpos;
  1143. end;
  1144. System.Move (Buffer,(FMemory+FPosition)^,Count);
  1145. FPosition:=NewPos;
  1146. Result:=Count;
  1147. end;
  1148. {****************************************************************************}
  1149. {* TBytesStream *}
  1150. {****************************************************************************}
  1151. constructor TBytesStream.Create(const ABytes: TBytes);
  1152. begin
  1153. inherited Create;
  1154. FBytes:=ABytes;
  1155. SetPointer(Pointer(FBytes),Length(FBytes));
  1156. FCapacity:=Length(FBytes);
  1157. end;
  1158. function TBytesStream.Realloc(var NewCapacity: PtrInt): Pointer;
  1159. begin
  1160. // adapt TMemoryStream code to use with dynamic array
  1161. if NewCapacity<0 Then
  1162. NewCapacity:=0
  1163. else
  1164. begin
  1165. if (NewCapacity>Capacity) and (NewCapacity < (5*Capacity) div 4) then
  1166. NewCapacity := (5*Capacity) div 4;
  1167. NewCapacity := (NewCapacity + (TMSGrow-1)) and not (TMSGROW-1);
  1168. end;
  1169. if NewCapacity=Capacity then
  1170. Result:=Pointer(FBytes)
  1171. else
  1172. begin
  1173. SetLength(FBytes,Newcapacity);
  1174. Result:=Pointer(FBytes);
  1175. if (Result=nil) and (Newcapacity>0) then
  1176. raise EStreamError.Create(SMemoryStreamError);
  1177. end;
  1178. end;
  1179. {****************************************************************************}
  1180. {* TStringStream *}
  1181. {****************************************************************************}
  1182. function TStringStream.GetDataString: string;
  1183. begin
  1184. Result:=FEncoding.GetAnsiString(Bytes,0,Size);
  1185. end;
  1186. function TStringStream.GetUnicodeDataString: String;
  1187. begin
  1188. Result:=FEncoding.GetString(Bytes, 0, Size);
  1189. end;
  1190. constructor TStringStream.Create(const AString: string = '');
  1191. begin
  1192. Create(AString,TEncoding.Default, False);
  1193. end;
  1194. constructor TStringStream.Create(const ABytes: TBytes);
  1195. begin
  1196. inherited Create(ABytes);
  1197. FEncoding:=TEncoding.Default;
  1198. FOwnsEncoding:=False;
  1199. end;
  1200. constructor TStringStream.CreateRaw(const AString: RawByteString);
  1201. var
  1202. CP: TSystemCodePage;
  1203. begin
  1204. CP:=StringCodePage(AString);
  1205. if (CP=CP_ACP) or (CP=TEncoding.Default.CodePage) then
  1206. begin
  1207. FEncoding:=TEncoding.Default;
  1208. FOwnsEncoding:=False;
  1209. end
  1210. else
  1211. begin
  1212. FEncoding:=TEncoding.GetEncoding(CP);
  1213. FOwnsEncoding:=True;
  1214. end;
  1215. inherited Create(BytesOf(AString));
  1216. end;
  1217. constructor TStringStream.Create(const AString: string; AEncoding: TEncoding; AOwnsEncoding: Boolean);
  1218. begin
  1219. FOwnsEncoding:=AOwnsEncoding and not TEncoding.IsStandardEncoding(AEncoding);
  1220. FEncoding:=AEncoding;
  1221. Inherited Create(AEncoding.GetAnsiBytes(AString));
  1222. end;
  1223. constructor TStringStream.Create(const AString: string; ACodePage: Integer);
  1224. begin
  1225. Create(AString,TEncoding.GetEncoding(ACodePage),true);
  1226. end;
  1227. constructor TStringStream.Create(const AString: UnicodeString);
  1228. begin
  1229. Create(AString,TEncoding.Unicode,false);
  1230. end;
  1231. constructor TStringStream.Create(const AString: UnicodeString; AEncoding: TEncoding; AOwnsEncoding: Boolean);
  1232. begin
  1233. FOwnsEncoding:=AOwnsEncoding and not TEncoding.IsStandardEncoding(AEncoding);
  1234. FEncoding:=AEncoding;
  1235. Inherited Create(AEncoding.GetBytes(AString));
  1236. end;
  1237. constructor TStringStream.Create(const AString: UnicodeString; ACodePage: Integer);
  1238. begin
  1239. Create(AString,TEncoding.GetEncoding(ACodePage),true);
  1240. end;
  1241. destructor TStringStream.Destroy;
  1242. begin
  1243. If FOwnsEncoding then
  1244. FreeAndNil(FEncoding);
  1245. inherited Destroy;
  1246. end;
  1247. function TStringStream.ReadString(Count: Longint): string;
  1248. begin
  1249. Result:=ReadAnsiString(Count);
  1250. end;
  1251. function TStringStream.ReadUnicodeString(Count: Longint): UnicodeString;
  1252. Var
  1253. NewLen,SLen : Longint;
  1254. begin
  1255. NewLen:=Size-FPosition;
  1256. If NewLen>Count then NewLen:=Count;
  1257. Result:=FEncoding.GetString(FBytes,FPosition,NewLen);
  1258. end;
  1259. procedure TStringStream.WriteString(const AString: string);
  1260. begin
  1261. WriteAnsiString(AString);
  1262. end;
  1263. procedure TStringStream.WriteUnicodeString(const AString: UnicodeString);
  1264. Var
  1265. B: TBytes;
  1266. begin
  1267. B:=FEncoding.GetBytes(AString);
  1268. if Length(B)>0 then
  1269. WriteBuffer(B[0],Length(Bytes));
  1270. end;
  1271. function TStringStream.ReadAnsiString(Count: Longint): AnsiString;
  1272. Var
  1273. NewLen : Longint;
  1274. begin
  1275. NewLen:=Size-FPosition;
  1276. If NewLen>Count then NewLen:=Count;
  1277. Result:=FEncoding.GetAnsiString(FBytes,FPosition,NewLen);
  1278. end;
  1279. procedure TStringStream.WriteAnsiString(const AString: AnsiString);
  1280. Var
  1281. B: TBytes;
  1282. begin
  1283. B:=FEncoding.GetAnsiBytes(AString);
  1284. if Length(B)>0 then
  1285. WriteBuffer(B[0],Length(B));
  1286. end;
  1287. {****************************************************************************}
  1288. {* TResourceStream *}
  1289. {****************************************************************************}
  1290. {$ifdef FPC_OS_UNICODE}
  1291. procedure TResourceStream.Initialize(Instance: TFPResourceHMODULE; Name, ResType: PWideChar; NameIsID: Boolean);
  1292. begin
  1293. Res:=FindResource(Instance, Name, ResType);
  1294. if Res=0 then
  1295. if NameIsID then
  1296. raise EResNotFound.CreateFmt(SResNotFound,[IntToStr(PtrInt(Name))])
  1297. else
  1298. raise EResNotFound.CreateFmt(SResNotFound,[Name]);
  1299. Handle:=LoadResource(Instance,Res);
  1300. if Handle=0 then
  1301. if NameIsID then
  1302. raise EResNotFound.CreateFmt(SResNotFound,[IntToStr(PtrInt(Name))])
  1303. else
  1304. raise EResNotFound.CreateFmt(SResNotFound,[Name]);
  1305. SetPointer(LockResource(Handle),SizeOfResource(Instance,Res));
  1306. end;
  1307. constructor TResourceStream.Create(Instance: TFPResourceHMODULE; const ResName: WideString; ResType: PWideChar);
  1308. begin
  1309. inherited create;
  1310. Initialize(Instance,PWideChar(ResName),ResType,False);
  1311. end;
  1312. constructor TResourceStream.CreateFromID(Instance: TFPResourceHMODULE; ResID: Integer; ResType: PWideChar);
  1313. begin
  1314. inherited create;
  1315. Initialize(Instance,PWideChar(ResID),ResType,True);
  1316. end;
  1317. {$else FPC_OS_UNICODE}
  1318. procedure TResourceStream.Initialize(Instance: TFPResourceHMODULE; Name, ResType: PChar; NameIsID: Boolean);
  1319. begin
  1320. Res:=FindResource(Instance, Name, ResType);
  1321. if Res=0 then
  1322. if NameIsID then
  1323. raise EResNotFound.CreateFmt(SResNotFound,[IntToStr(PtrInt(Name))])
  1324. else
  1325. raise EResNotFound.CreateFmt(SResNotFound,[Name]);
  1326. Handle:=LoadResource(Instance,Res);
  1327. if Handle=0 then
  1328. if NameIsID then
  1329. raise EResNotFound.CreateFmt(SResNotFound,[IntToStr(PtrInt(Name))])
  1330. else
  1331. raise EResNotFound.CreateFmt(SResNotFound,[Name]);
  1332. SetPointer(LockResource(Handle),SizeOfResource(Instance,Res));
  1333. end;
  1334. constructor TResourceStream.Create(Instance: TFPResourceHMODULE; const ResName: string; ResType: PChar);
  1335. begin
  1336. inherited create;
  1337. Initialize(Instance,pchar(ResName),ResType,False);
  1338. end;
  1339. constructor TResourceStream.CreateFromID(Instance: TFPResourceHMODULE; ResID: Integer; ResType: PChar);
  1340. begin
  1341. inherited create;
  1342. Initialize(Instance,pchar(PtrInt(ResID)),ResType,True);
  1343. end;
  1344. {$endif FPC_OS_UNICODE}
  1345. destructor TResourceStream.Destroy;
  1346. begin
  1347. UnlockResource(Handle);
  1348. FreeResource(Handle);
  1349. inherited destroy;
  1350. end;
  1351. {****************************************************************************}
  1352. {* TOwnerStream *}
  1353. {****************************************************************************}
  1354. constructor TOwnerStream.Create(ASource: TStream);
  1355. begin
  1356. FSource:=ASource;
  1357. end;
  1358. destructor TOwnerStream.Destroy;
  1359. begin
  1360. If FOwner then
  1361. FreeAndNil(FSource);
  1362. inherited Destroy;
  1363. end;
  1364. {****************************************************************************}
  1365. {* TStreamAdapter *}
  1366. {****************************************************************************}
  1367. constructor TStreamAdapter.Create(Stream: TStream; Ownership: TStreamOwnership = soReference);
  1368. begin
  1369. inherited Create;
  1370. FStream:=Stream;
  1371. FOwnership:=Ownership;
  1372. m_bReverted:=false; // mantis 15003
  1373. // http://www.tech-archive.net/Archive/German/microsoft.public.de.vc/2005-08/msg00791.html
  1374. // http://code.google.com/p/ddab-lib/wiki/TPJIStreamWrapper
  1375. end;
  1376. destructor TStreamAdapter.Destroy;
  1377. begin
  1378. if StreamOwnership=soOwned then
  1379. FreeAndNil(FStream);
  1380. inherited Destroy;
  1381. end;
  1382. {$warnings off}
  1383. function TStreamAdapter.Read(pv: Pointer; cb: DWORD; pcbRead: PDWORD): HResult; stdcall;
  1384. var
  1385. readcount: Longint;
  1386. begin
  1387. if m_bReverted then
  1388. begin
  1389. Result := STG_E_REVERTED;
  1390. Exit;
  1391. end;
  1392. if pv = nil then
  1393. begin
  1394. Result := STG_E_INVALIDPOINTER;
  1395. Exit;
  1396. end;
  1397. readcount := FStream.Read(pv^, cb);
  1398. if pcbRead <> nil then pcbRead^ := readcount;
  1399. Result := S_OK;
  1400. end;
  1401. function TStreamAdapter.Write(pv: Pointer; cb: DWORD; pcbWritten: PDWORD): HResult; stdcall;
  1402. var
  1403. writecount: Longint;
  1404. begin
  1405. if m_bReverted then
  1406. begin
  1407. Result := STG_E_REVERTED;
  1408. Exit;
  1409. end;
  1410. if pv = nil then
  1411. begin
  1412. Result := STG_E_INVALIDPOINTER;
  1413. Exit;
  1414. end;
  1415. writecount := FStream.Write(pv^, cb);
  1416. if pcbWritten <> nil then pcbWritten^ := writecount;
  1417. Result := S_OK;
  1418. end;
  1419. function TStreamAdapter.Seek(dlibMove: LargeInt; dwOrigin: DWORD; out libNewPosition: LargeUint): HResult; stdcall;
  1420. var
  1421. newpos: QWord;
  1422. begin
  1423. if m_bReverted then
  1424. begin
  1425. Result := STG_E_REVERTED;
  1426. Exit;
  1427. end;
  1428. case dwOrigin of
  1429. STREAM_SEEK_SET: newpos := FStream.Seek(dlibMove, soBeginning);
  1430. STREAM_SEEK_CUR: newpos := FStream.Seek(dlibMove, soCurrent);
  1431. STREAM_SEEK_END: newpos := FStream.Seek(dlibMove, soEnd);
  1432. else
  1433. begin
  1434. Result := STG_E_INVALIDFUNCTION;
  1435. Exit;
  1436. end;
  1437. end;
  1438. if @libNewPosition <> nil then
  1439. libNewPosition := newpos;
  1440. Result := S_OK;
  1441. end;
  1442. function TStreamAdapter.SetSize(libNewSize: LargeUint): HResult; stdcall;
  1443. begin
  1444. if m_bReverted then
  1445. begin
  1446. Result := STG_E_REVERTED;
  1447. Exit;
  1448. end;
  1449. if libNewSize<0 then
  1450. begin
  1451. Result := STG_E_INVALIDFUNCTION;
  1452. Exit;
  1453. end;
  1454. try
  1455. FStream.Size := libNewSize;
  1456. Result := S_OK;
  1457. except
  1458. // TODO: return different error value according to exception like STG_E_MEDIUMFULL
  1459. Result := E_FAIL;
  1460. end;
  1461. end;
  1462. function TStreamAdapter.CopyTo(stm: IStream; cb: LargeUint; out cbRead: LargeUint; out cbWritten: Largeuint): HResult; stdcall;
  1463. var
  1464. sz: dword;
  1465. buffer : array[0..1023] of byte;
  1466. begin
  1467. if m_bReverted then
  1468. begin
  1469. Result := STG_E_REVERTED;
  1470. Exit;
  1471. end;
  1472. // the method is similar to TStream.CopyFrom => use CopyFrom implementation
  1473. cbWritten := 0;
  1474. cbRead := 0;
  1475. while cb > 0 do
  1476. begin
  1477. if (cb > sizeof(buffer)) then
  1478. sz := sizeof(Buffer)
  1479. else
  1480. sz := cb;
  1481. sz := FStream.Read(buffer, sz);
  1482. inc(cbRead, sz);
  1483. stm.Write(@buffer[0], sz, @sz);
  1484. inc(cbWritten, sz);
  1485. if sz = 0 then
  1486. begin
  1487. Result := E_FAIL;
  1488. Exit;
  1489. end;
  1490. dec(cb, sz);
  1491. end;
  1492. Result := S_OK;
  1493. end;
  1494. function TStreamAdapter.Commit(grfCommitFlags: DWORD): HResult; stdcall;
  1495. begin
  1496. if m_bReverted then
  1497. Result := STG_E_REVERTED
  1498. else
  1499. Result := S_OK;
  1500. end;
  1501. function TStreamAdapter.Revert: HResult; stdcall;
  1502. begin
  1503. m_bReverted := True;
  1504. Result := S_OK;
  1505. end;
  1506. function TStreamAdapter.LockRegion(libOffset: LargeUint; cb: LargeUint; dwLockType: DWORD): HResult; stdcall;
  1507. begin
  1508. Result := STG_E_INVALIDFUNCTION;
  1509. end;
  1510. function TStreamAdapter.UnlockRegion(libOffset: LargeUint; cb: LargeUint; dwLockType: DWORD): HResult; stdcall;
  1511. begin
  1512. Result := STG_E_INVALIDFUNCTION;
  1513. end;
  1514. function TStreamAdapter.Stat(out statstg: TStatStg; grfStatFlag: DWORD): HResult; stdcall;
  1515. begin
  1516. if m_bReverted then
  1517. begin
  1518. Result := STG_E_REVERTED;
  1519. Exit;
  1520. end;
  1521. if grfStatFlag in [STATFLAG_DEFAULT,STATFLAG_NOOPEN,STATFLAG_NONAME] then
  1522. begin
  1523. if @statstg <> nil then
  1524. begin
  1525. fillchar(statstg, sizeof(TStatStg),#0);
  1526. { //TODO handle pwcsName
  1527. if grfStatFlag = STATFLAG_DEFAULT then
  1528. runerror(217) //Result :={$ifdef windows} STG_E_INVALIDFLAG{$else}E_INVALID_FLAG{$endif}
  1529. }
  1530. statstg.dwType := STGTY_STREAM;
  1531. statstg.cbSize := FStream.Size;
  1532. statstg.grfLocksSupported := LOCK_WRITE;
  1533. end;
  1534. Result := S_OK;
  1535. end else
  1536. Result := STG_E_INVALIDFLAG
  1537. end;
  1538. function TStreamAdapter.Clone(out stm: IStream): HResult; stdcall;
  1539. begin
  1540. if m_bReverted then
  1541. begin
  1542. Result := STG_E_REVERTED;
  1543. Exit;
  1544. end;
  1545. // don't raise an exception here return error value that function is not implemented
  1546. // to implement this we need a clone method for TStream class
  1547. Result := STG_E_UNIMPLEMENTEDFUNCTION;
  1548. end;
  1549. constructor TProxyStream.Create(const Stream: IStream);
  1550. begin
  1551. FStream := Stream;
  1552. end;
  1553. function TProxyStream.Read(var Buffer; Count: Longint): Longint;
  1554. begin
  1555. Check(FStream.Read(@Buffer, Count, @Result));
  1556. end;
  1557. function TProxyStream.Seek(const Offset: int64; Origin: TSeekOrigin): int64;
  1558. begin
  1559. Check(FStream.Seek(Offset, ord(Origin), QWord(result)));
  1560. end;
  1561. function TProxyStream.Write(const Buffer; Count: Longint): Longint;
  1562. begin
  1563. Check(FStream.Write(@Buffer, Count, @Result));
  1564. end;
  1565. function TProxyStream.GetIStream: IStream;
  1566. begin
  1567. Result := FStream;
  1568. end;
  1569. procedure TProxyStream.Check(err:integer);
  1570. var e : EInOutError;
  1571. begin
  1572. e:= EInOutError.Create('Proxystream.Check');
  1573. e.Errorcode:=err;
  1574. raise e;
  1575. end;
  1576. {$warnings on}