streams.inc 48 KB

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