streams.inc 49 KB

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