streams.inc 51 KB

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