streams.inc 48 KB

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