streams.inc 48 KB

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