streams.inc 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074
  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. {****************************************************************************}
  1063. {* TCustomMemoryStream *}
  1064. {****************************************************************************}
  1065. procedure TCustomMemoryStream.SetPointer(Ptr: Pointer; ASize: PtrInt);
  1066. begin
  1067. FMemory:=Ptr;
  1068. FSize:=ASize;
  1069. end;
  1070. function TCustomMemoryStream.GetSize: Int64;
  1071. begin
  1072. Result:=FSize;
  1073. end;
  1074. function TCustomMemoryStream.GetPosition: Int64;
  1075. begin
  1076. Result:=FPosition;
  1077. end;
  1078. function TCustomMemoryStream.Read(var Buffer; Count: LongInt): LongInt;
  1079. begin
  1080. Result:=0;
  1081. If (FSize>0) and (FPosition<Fsize) and (FPosition>=0) then
  1082. begin
  1083. Result:=Count;
  1084. If (Result>(FSize-FPosition)) then
  1085. Result:=(FSize-FPosition);
  1086. Move ((FMemory+FPosition)^,Buffer,Result);
  1087. FPosition:=Fposition+Result;
  1088. end;
  1089. end;
  1090. function TCustomMemoryStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
  1091. begin
  1092. Case Word(Origin) of
  1093. soFromBeginning : FPosition:=Offset;
  1094. soFromEnd : FPosition:=FSize+Offset;
  1095. soFromCurrent : FPosition:=FPosition+Offset;
  1096. end;
  1097. if SizeBoundsSeek and (FPosition>FSize) then
  1098. FPosition:=FSize;
  1099. Result:=FPosition;
  1100. {$IFDEF DEBUG}
  1101. if Result < 0 then
  1102. raise Exception.Create('TCustomMemoryStream');
  1103. {$ENDIF}
  1104. end;
  1105. procedure TCustomMemoryStream.SaveToStream(Stream: TStream);
  1106. begin
  1107. if FSize>0 then Stream.WriteBuffer (FMemory^,FSize);
  1108. end;
  1109. procedure TCustomMemoryStream.SaveToFile(const FileName: string);
  1110. Var S : TFileStream;
  1111. begin
  1112. S:=TFileStream.Create (FileName,fmCreate);
  1113. Try
  1114. SaveToStream(S);
  1115. finally
  1116. S.free;
  1117. end;
  1118. end;
  1119. {****************************************************************************}
  1120. {* TMemoryStream *}
  1121. {****************************************************************************}
  1122. Const TMSGrow = 4096; { Use 4k blocks. }
  1123. procedure TMemoryStream.SetCapacity(NewCapacity: PtrInt);
  1124. begin
  1125. SetPointer (Realloc(NewCapacity),Fsize);
  1126. FCapacity:=NewCapacity;
  1127. end;
  1128. function TMemoryStream.Realloc(var NewCapacity: PtrInt): Pointer;
  1129. Var
  1130. GC : PtrInt;
  1131. begin
  1132. If NewCapacity<0 Then
  1133. NewCapacity:=0
  1134. else
  1135. begin
  1136. GC:=FCapacity + (FCapacity div 4);
  1137. // if growing, grow at least a quarter
  1138. if (NewCapacity>FCapacity) and (NewCapacity < GC) then
  1139. NewCapacity := GC;
  1140. // round off to block size.
  1141. NewCapacity := (NewCapacity + (TMSGrow-1)) and not (TMSGROW-1);
  1142. end;
  1143. // Only now check !
  1144. If NewCapacity=FCapacity then
  1145. Result:=FMemory
  1146. else
  1147. begin
  1148. Result:=Reallocmem(FMemory,Newcapacity);
  1149. If (Result=Nil) and (Newcapacity>0) then
  1150. Raise EStreamError.Create(SMemoryStreamError);
  1151. end;
  1152. end;
  1153. destructor TMemoryStream.Destroy;
  1154. begin
  1155. Clear;
  1156. Inherited Destroy;
  1157. end;
  1158. procedure TMemoryStream.Clear;
  1159. begin
  1160. FSize:=0;
  1161. FPosition:=0;
  1162. SetCapacity (0);
  1163. end;
  1164. procedure TMemoryStream.LoadFromStream(Stream: TStream);
  1165. begin
  1166. Stream.Position:=0;
  1167. SetSize(Stream.Size);
  1168. If FSize>0 then Stream.ReadBuffer(FMemory^,FSize);
  1169. end;
  1170. procedure TMemoryStream.LoadFromFile(const FileName: string);
  1171. Var S : TFileStream;
  1172. begin
  1173. S:=TFileStream.Create (FileName,fmOpenRead or fmShareDenyWrite);
  1174. Try
  1175. LoadFromStream(S);
  1176. finally
  1177. S.free;
  1178. end;
  1179. end;
  1180. procedure TMemoryStream.SetSize({$ifdef CPU64}const NewSize: Int64{$else}NewSize: LongInt{$endif});
  1181. begin
  1182. SetCapacity (NewSize);
  1183. FSize:=NewSize;
  1184. IF FPosition>FSize then
  1185. FPosition:=FSize;
  1186. end;
  1187. function TMemoryStream.Write(const Buffer; Count: LongInt): LongInt;
  1188. Var NewPos : PtrInt;
  1189. begin
  1190. If (Count=0) or (FPosition<0) then
  1191. exit(0);
  1192. NewPos:=FPosition+Count;
  1193. If NewPos>Fsize then
  1194. begin
  1195. IF NewPos>FCapacity then
  1196. SetCapacity (NewPos);
  1197. FSize:=Newpos;
  1198. end;
  1199. System.Move (Buffer,(FMemory+FPosition)^,Count);
  1200. FPosition:=NewPos;
  1201. Result:=Count;
  1202. end;
  1203. {****************************************************************************}
  1204. {* TBytesStream *}
  1205. {****************************************************************************}
  1206. constructor TBytesStream.Create(const ABytes: TBytes);
  1207. begin
  1208. inherited Create;
  1209. FBytes:=ABytes;
  1210. SetPointer(Pointer(FBytes),Length(FBytes));
  1211. FCapacity:=Length(FBytes);
  1212. end;
  1213. function TBytesStream.Realloc(var NewCapacity: PtrInt): Pointer;
  1214. begin
  1215. // adapt TMemoryStream code to use with dynamic array
  1216. if NewCapacity<0 Then
  1217. NewCapacity:=0
  1218. else
  1219. begin
  1220. if (NewCapacity>Capacity) and (NewCapacity < (5*Capacity) div 4) then
  1221. NewCapacity := (5*Capacity) div 4;
  1222. NewCapacity := (NewCapacity + (TMSGrow-1)) and not (TMSGROW-1);
  1223. end;
  1224. if NewCapacity=Capacity then
  1225. Result:=Pointer(FBytes)
  1226. else
  1227. begin
  1228. SetLength(FBytes,Newcapacity);
  1229. Result:=Pointer(FBytes);
  1230. if (Result=nil) and (Newcapacity>0) then
  1231. raise EStreamError.Create(SMemoryStreamError);
  1232. end;
  1233. end;
  1234. {****************************************************************************}
  1235. {* TStringStream *}
  1236. {****************************************************************************}
  1237. function TStringStream.GetDataString: string;
  1238. begin
  1239. Result:=FEncoding.GetAnsiString(Bytes,0,Size);
  1240. end;
  1241. function TStringStream.GetUnicodeDataString: UnicodeString;
  1242. begin
  1243. Result:=FEncoding.GetString(Bytes, 0, Size);
  1244. end;
  1245. constructor TStringStream.Create(const AString: string = '');
  1246. begin
  1247. Create(AString,TEncoding.Default, False);
  1248. end;
  1249. constructor TStringStream.Create(const ABytes: TBytes);
  1250. begin
  1251. inherited Create(ABytes);
  1252. FEncoding:=TEncoding.Default;
  1253. FOwnsEncoding:=False;
  1254. end;
  1255. constructor TStringStream.CreateRaw(const AString: RawByteString);
  1256. var
  1257. CP: TSystemCodePage;
  1258. begin
  1259. CP:=StringCodePage(AString);
  1260. if (CP=CP_ACP) or (CP=TEncoding.Default.CodePage) then
  1261. begin
  1262. FEncoding:=TEncoding.Default;
  1263. FOwnsEncoding:=False;
  1264. end
  1265. else
  1266. begin
  1267. FEncoding:=TEncoding.GetEncoding(CP);
  1268. FOwnsEncoding:=True;
  1269. end;
  1270. inherited Create(BytesOf(AString));
  1271. end;
  1272. constructor TStringStream.Create(const AString: string; AEncoding: TEncoding; AOwnsEncoding: Boolean);
  1273. begin
  1274. FOwnsEncoding:=AOwnsEncoding and not TEncoding.IsStandardEncoding(AEncoding);
  1275. FEncoding:=AEncoding;
  1276. Inherited Create(AEncoding.GetAnsiBytes(AString));
  1277. end;
  1278. constructor TStringStream.Create(const AString: string; ACodePage: Integer);
  1279. begin
  1280. Create(AString,TEncoding.GetEncoding(ACodePage),true);
  1281. end;
  1282. constructor TStringStream.Create(const AString: UnicodeString);
  1283. begin
  1284. Create(AString,TEncoding.Unicode,false);
  1285. end;
  1286. constructor TStringStream.Create(const AString: UnicodeString; AEncoding: TEncoding; AOwnsEncoding: Boolean);
  1287. begin
  1288. FOwnsEncoding:=AOwnsEncoding and not TEncoding.IsStandardEncoding(AEncoding);
  1289. FEncoding:=AEncoding;
  1290. Inherited Create(AEncoding.GetBytes(AString));
  1291. end;
  1292. constructor TStringStream.Create(const AString: UnicodeString; ACodePage: Integer);
  1293. begin
  1294. Create(AString,TEncoding.GetEncoding(ACodePage),true);
  1295. end;
  1296. destructor TStringStream.Destroy;
  1297. begin
  1298. If FOwnsEncoding then
  1299. FreeAndNil(FEncoding);
  1300. inherited Destroy;
  1301. end;
  1302. function TStringStream.ReadString(Count: Longint): string;
  1303. begin
  1304. Result:=ReadAnsiString(Count);
  1305. end;
  1306. function TStringStream.ReadUnicodeString(Count: Longint): UnicodeString;
  1307. Var
  1308. NewLen,SLen : Longint;
  1309. begin
  1310. NewLen:=Size-FPosition;
  1311. If NewLen>Count then NewLen:=Count;
  1312. Result:=FEncoding.GetString(FBytes,FPosition,NewLen);
  1313. end;
  1314. procedure TStringStream.WriteString(const AString: string);
  1315. begin
  1316. WriteAnsiString(AString);
  1317. end;
  1318. procedure TStringStream.WriteUnicodeString(const AString: UnicodeString);
  1319. Var
  1320. B: TBytes;
  1321. begin
  1322. B:=FEncoding.GetBytes(AString);
  1323. if Length(B)>0 then
  1324. WriteBuffer(B[0],Length(B));
  1325. end;
  1326. function TStringStream.ReadAnsiString(Count: Longint): AnsiString;
  1327. Var
  1328. NewLen : Longint;
  1329. begin
  1330. NewLen:=Size-FPosition;
  1331. If NewLen>Count then NewLen:=Count;
  1332. Result:=FEncoding.GetAnsiString(FBytes,FPosition,NewLen);
  1333. Inc(FPosition,NewLen);
  1334. end;
  1335. procedure TStringStream.WriteAnsiString(const AString: AnsiString);
  1336. Var
  1337. B: TBytes;
  1338. begin
  1339. B:=FEncoding.GetAnsiBytes(AString);
  1340. if Length(B)>0 then
  1341. WriteBuffer(B[0],Length(B));
  1342. end;
  1343. {****************************************************************************}
  1344. {* TRawByteStringStream *}
  1345. {****************************************************************************}
  1346. constructor TRawByteStringStream.Create(const aData: RawByteString);
  1347. begin
  1348. Inherited Create;
  1349. If Length(aData)>0 then
  1350. begin
  1351. WriteBuffer(aData[1],Length(aData));
  1352. Position:=0;
  1353. end;
  1354. end;
  1355. function TRawByteStringStream.DataString: RawByteString;
  1356. begin
  1357. Result:='';
  1358. SetLength(Result,Size);
  1359. if Size>0 then
  1360. Move(Memory^, Result[1], Size);
  1361. end;
  1362. function TRawByteStringStream.ReadString(Count: Longint): RawByteString;
  1363. Var
  1364. NewLen : Longint;
  1365. begin
  1366. NewLen:=Size-FPosition;
  1367. If NewLen>Count then NewLen:=Count;
  1368. Result:='';
  1369. if NewLen>0 then
  1370. begin
  1371. SetLength(Result, NewLen);
  1372. Move(FBytes[FPosition],Result[1],NewLen);
  1373. inc(FPosition,Newlen);
  1374. end;
  1375. end;
  1376. procedure TRawByteStringStream.WriteString(const AString: RawByteString);
  1377. begin
  1378. if Length(AString)>0 then
  1379. WriteBuffer(AString[1],Length(AString));
  1380. end;
  1381. {****************************************************************************}
  1382. {* TResourceStream *}
  1383. {****************************************************************************}
  1384. {$ifdef FPC_OS_UNICODE}
  1385. procedure TResourceStream.Initialize(Instance: TFPResourceHMODULE; Name, ResType: PWideChar; NameIsID: Boolean);
  1386. begin
  1387. Res:=FindResource(Instance, Name, ResType);
  1388. if Res=0 then
  1389. if NameIsID then
  1390. raise EResNotFound.CreateFmt(SResNotFound,[IntToStr(PtrInt(Name))])
  1391. else
  1392. raise EResNotFound.CreateFmt(SResNotFound,[Name]);
  1393. Handle:=LoadResource(Instance,Res);
  1394. if Handle=0 then
  1395. if NameIsID then
  1396. raise EResNotFound.CreateFmt(SResNotFound,[IntToStr(PtrInt(Name))])
  1397. else
  1398. raise EResNotFound.CreateFmt(SResNotFound,[Name]);
  1399. SetPointer(LockResource(Handle),SizeOfResource(Instance,Res));
  1400. end;
  1401. constructor TResourceStream.Create(Instance: TFPResourceHMODULE; const ResName: WideString; ResType: PWideChar);
  1402. begin
  1403. inherited create;
  1404. Initialize(Instance,PWideChar(ResName),ResType,False);
  1405. end;
  1406. constructor TResourceStream.CreateFromID(Instance: TFPResourceHMODULE; ResID: Integer; ResType: PWideChar);
  1407. begin
  1408. inherited create;
  1409. Initialize(Instance,PWideChar(ResID),ResType,True);
  1410. end;
  1411. {$else FPC_OS_UNICODE}
  1412. procedure TResourceStream.Initialize(Instance: TFPResourceHMODULE; Name, ResType: PChar; NameIsID: Boolean);
  1413. begin
  1414. Res:=FindResource(Instance, Name, ResType);
  1415. if Res=0 then
  1416. if NameIsID then
  1417. raise EResNotFound.CreateFmt(SResNotFound,[IntToStr(PtrInt(Name))])
  1418. else
  1419. raise EResNotFound.CreateFmt(SResNotFound,[Name]);
  1420. Handle:=LoadResource(Instance,Res);
  1421. if Handle=0 then
  1422. if NameIsID then
  1423. raise EResNotFound.CreateFmt(SResNotFound,[IntToStr(PtrInt(Name))])
  1424. else
  1425. raise EResNotFound.CreateFmt(SResNotFound,[Name]);
  1426. SetPointer(LockResource(Handle),SizeOfResource(Instance,Res));
  1427. end;
  1428. constructor TResourceStream.Create(Instance: TFPResourceHMODULE; const ResName: string; ResType: PChar);
  1429. begin
  1430. inherited create;
  1431. Initialize(Instance,pchar(ResName),ResType,False);
  1432. end;
  1433. constructor TResourceStream.CreateFromID(Instance: TFPResourceHMODULE; ResID: Integer; ResType: PChar);
  1434. begin
  1435. inherited create;
  1436. Initialize(Instance,pchar(PtrInt(ResID)),ResType,True);
  1437. end;
  1438. {$endif FPC_OS_UNICODE}
  1439. destructor TResourceStream.Destroy;
  1440. begin
  1441. UnlockResource(Handle);
  1442. FreeResource(Handle);
  1443. inherited destroy;
  1444. end;
  1445. {****************************************************************************}
  1446. {* TOwnerStream *}
  1447. {****************************************************************************}
  1448. constructor TOwnerStream.Create(ASource: TStream);
  1449. begin
  1450. FSource:=ASource;
  1451. end;
  1452. destructor TOwnerStream.Destroy;
  1453. begin
  1454. If FOwner then
  1455. FreeAndNil(FSource);
  1456. inherited Destroy;
  1457. end;
  1458. {****************************************************************************}
  1459. {* TStreamAdapter *}
  1460. {****************************************************************************}
  1461. constructor TStreamAdapter.Create(Stream: TStream; Ownership: TStreamOwnership = soReference);
  1462. begin
  1463. inherited Create;
  1464. FStream:=Stream;
  1465. FOwnership:=Ownership;
  1466. m_bReverted:=false; // mantis 15003
  1467. // http://www.tech-archive.net/Archive/German/microsoft.public.de.vc/2005-08/msg00791.html
  1468. // http://code.google.com/p/ddab-lib/wiki/TPJIStreamWrapper
  1469. end;
  1470. destructor TStreamAdapter.Destroy;
  1471. begin
  1472. if StreamOwnership=soOwned then
  1473. FreeAndNil(FStream);
  1474. inherited Destroy;
  1475. end;
  1476. {$push}
  1477. {$warnings off}
  1478. function TStreamAdapter.Read(pv: Pointer; cb: DWORD; pcbRead: PDWORD): HResult; stdcall;
  1479. var
  1480. readcount: Longint;
  1481. begin
  1482. if m_bReverted then
  1483. begin
  1484. Result := STG_E_REVERTED;
  1485. Exit;
  1486. end;
  1487. if pv = nil then
  1488. begin
  1489. Result := STG_E_INVALIDPOINTER;
  1490. Exit;
  1491. end;
  1492. readcount := FStream.Read(pv^, cb);
  1493. if pcbRead <> nil then pcbRead^ := readcount;
  1494. Result := S_OK;
  1495. end;
  1496. function TStreamAdapter.Write(pv: Pointer; cb: DWORD; pcbWritten: PDWORD): HResult; stdcall;
  1497. var
  1498. writecount: Longint;
  1499. begin
  1500. if m_bReverted then
  1501. begin
  1502. Result := STG_E_REVERTED;
  1503. Exit;
  1504. end;
  1505. if pv = nil then
  1506. begin
  1507. Result := STG_E_INVALIDPOINTER;
  1508. Exit;
  1509. end;
  1510. writecount := FStream.Write(pv^, cb);
  1511. if pcbWritten <> nil then pcbWritten^ := writecount;
  1512. Result := S_OK;
  1513. end;
  1514. function TStreamAdapter.Seek(dlibMove: LargeInt; dwOrigin: DWORD; out libNewPosition: LargeUint): HResult; stdcall;
  1515. var
  1516. newpos: QWord;
  1517. begin
  1518. if m_bReverted then
  1519. begin
  1520. Result := STG_E_REVERTED;
  1521. Exit;
  1522. end;
  1523. case dwOrigin of
  1524. STREAM_SEEK_SET: newpos := FStream.Seek(dlibMove, soBeginning);
  1525. STREAM_SEEK_CUR: newpos := FStream.Seek(dlibMove, soCurrent);
  1526. STREAM_SEEK_END: newpos := FStream.Seek(dlibMove, soEnd);
  1527. else
  1528. begin
  1529. Result := STG_E_INVALIDFUNCTION;
  1530. Exit;
  1531. end;
  1532. end;
  1533. if @libNewPosition <> nil then
  1534. libNewPosition := newpos;
  1535. Result := S_OK;
  1536. end;
  1537. function TStreamAdapter.SetSize(libNewSize: LargeUint): HResult; stdcall;
  1538. begin
  1539. if m_bReverted then
  1540. begin
  1541. Result := STG_E_REVERTED;
  1542. Exit;
  1543. end;
  1544. if libNewSize<0 then
  1545. begin
  1546. Result := STG_E_INVALIDFUNCTION;
  1547. Exit;
  1548. end;
  1549. try
  1550. FStream.Size := libNewSize;
  1551. Result := S_OK;
  1552. except
  1553. // TODO: return different error value according to exception like STG_E_MEDIUMFULL
  1554. Result := E_FAIL;
  1555. end;
  1556. end;
  1557. function TStreamAdapter.CopyTo(stm: IStream; cb: LargeUint; out cbRead: LargeUint; out cbWritten: Largeuint): HResult; stdcall;
  1558. var
  1559. sz: dword;
  1560. buffer : array[0..1023] of byte;
  1561. begin
  1562. if m_bReverted then
  1563. begin
  1564. Result := STG_E_REVERTED;
  1565. Exit;
  1566. end;
  1567. // the method is similar to TStream.CopyFrom => use CopyFrom implementation
  1568. cbWritten := 0;
  1569. cbRead := 0;
  1570. while cb > 0 do
  1571. begin
  1572. if (cb > sizeof(buffer)) then
  1573. sz := sizeof(Buffer)
  1574. else
  1575. sz := cb;
  1576. sz := FStream.Read(buffer[0],sz);
  1577. inc(cbRead, sz);
  1578. stm.Write(@buffer[0], sz, @sz);
  1579. inc(cbWritten, sz);
  1580. if sz = 0 then
  1581. begin
  1582. Result := E_FAIL;
  1583. Exit;
  1584. end;
  1585. dec(cb, sz);
  1586. end;
  1587. Result := S_OK;
  1588. end;
  1589. function TStreamAdapter.Commit(grfCommitFlags: DWORD): HResult; stdcall;
  1590. begin
  1591. if m_bReverted then
  1592. Result := STG_E_REVERTED
  1593. else
  1594. Result := S_OK;
  1595. end;
  1596. function TStreamAdapter.Revert: HResult; stdcall;
  1597. begin
  1598. m_bReverted := True;
  1599. Result := S_OK;
  1600. end;
  1601. function TStreamAdapter.LockRegion(libOffset: LargeUint; cb: LargeUint; dwLockType: DWORD): HResult; stdcall;
  1602. begin
  1603. Result := STG_E_INVALIDFUNCTION;
  1604. end;
  1605. function TStreamAdapter.UnlockRegion(libOffset: LargeUint; cb: LargeUint; dwLockType: DWORD): HResult; stdcall;
  1606. begin
  1607. Result := STG_E_INVALIDFUNCTION;
  1608. end;
  1609. function TStreamAdapter.Stat(out statstg: TStatStg; grfStatFlag: DWORD): HResult; stdcall;
  1610. begin
  1611. if m_bReverted then
  1612. begin
  1613. Result := STG_E_REVERTED;
  1614. Exit;
  1615. end;
  1616. if grfStatFlag in [STATFLAG_DEFAULT,STATFLAG_NOOPEN,STATFLAG_NONAME] then
  1617. begin
  1618. if @statstg <> nil then
  1619. begin
  1620. fillchar(statstg, sizeof(TStatStg),#0);
  1621. { //TODO handle pwcsName
  1622. if grfStatFlag = STATFLAG_DEFAULT then
  1623. runerror(217) //Result :={$ifdef windows} STG_E_INVALIDFLAG{$else}E_INVALID_FLAG{$endif}
  1624. }
  1625. statstg.dwType := STGTY_STREAM;
  1626. statstg.cbSize := FStream.Size;
  1627. statstg.grfLocksSupported := LOCK_WRITE;
  1628. end;
  1629. Result := S_OK;
  1630. end else
  1631. Result := STG_E_INVALIDFLAG
  1632. end;
  1633. function TStreamAdapter.Clone(out stm: IStream): HResult; stdcall;
  1634. begin
  1635. if m_bReverted then
  1636. begin
  1637. Result := STG_E_REVERTED;
  1638. Exit;
  1639. end;
  1640. // don't raise an exception here return error value that function is not implemented
  1641. // to implement this we need a clone method for TStream class
  1642. Result := STG_E_UNIMPLEMENTEDFUNCTION;
  1643. end;
  1644. constructor TProxyStream.Create(const Stream: IStream);
  1645. begin
  1646. FStream := Stream;
  1647. end;
  1648. function TProxyStream.Read(var Buffer; Count: Longint): Longint;
  1649. begin
  1650. Check(FStream.Read(@Buffer, Count, @Result));
  1651. end;
  1652. function TProxyStream.Seek(const Offset: int64; Origin: TSeekOrigin): int64;
  1653. begin
  1654. Check(FStream.Seek(Offset, ord(Origin), QWord(result)));
  1655. end;
  1656. function TProxyStream.Write(const Buffer; Count: Longint): Longint;
  1657. begin
  1658. Check(FStream.Write(@Buffer, Count, @Result));
  1659. end;
  1660. function TProxyStream.GetIStream: IStream;
  1661. begin
  1662. Result := FStream;
  1663. end;
  1664. {$pop}