streams.inc 47 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987
  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. {* TResourceStream *}
  1297. {****************************************************************************}
  1298. {$ifdef FPC_OS_UNICODE}
  1299. procedure TResourceStream.Initialize(Instance: TFPResourceHMODULE; Name, ResType: PWideChar; NameIsID: Boolean);
  1300. begin
  1301. Res:=FindResource(Instance, Name, ResType);
  1302. if Res=0 then
  1303. if NameIsID then
  1304. raise EResNotFound.CreateFmt(SResNotFound,[IntToStr(PtrInt(Name))])
  1305. else
  1306. raise EResNotFound.CreateFmt(SResNotFound,[Name]);
  1307. Handle:=LoadResource(Instance,Res);
  1308. if Handle=0 then
  1309. if NameIsID then
  1310. raise EResNotFound.CreateFmt(SResNotFound,[IntToStr(PtrInt(Name))])
  1311. else
  1312. raise EResNotFound.CreateFmt(SResNotFound,[Name]);
  1313. SetPointer(LockResource(Handle),SizeOfResource(Instance,Res));
  1314. end;
  1315. constructor TResourceStream.Create(Instance: TFPResourceHMODULE; const ResName: WideString; ResType: PWideChar);
  1316. begin
  1317. inherited create;
  1318. Initialize(Instance,PWideChar(ResName),ResType,False);
  1319. end;
  1320. constructor TResourceStream.CreateFromID(Instance: TFPResourceHMODULE; ResID: Integer; ResType: PWideChar);
  1321. begin
  1322. inherited create;
  1323. Initialize(Instance,PWideChar(ResID),ResType,True);
  1324. end;
  1325. {$else FPC_OS_UNICODE}
  1326. procedure TResourceStream.Initialize(Instance: TFPResourceHMODULE; Name, ResType: PChar; NameIsID: Boolean);
  1327. begin
  1328. Res:=FindResource(Instance, Name, ResType);
  1329. if Res=0 then
  1330. if NameIsID then
  1331. raise EResNotFound.CreateFmt(SResNotFound,[IntToStr(PtrInt(Name))])
  1332. else
  1333. raise EResNotFound.CreateFmt(SResNotFound,[Name]);
  1334. Handle:=LoadResource(Instance,Res);
  1335. if Handle=0 then
  1336. if NameIsID then
  1337. raise EResNotFound.CreateFmt(SResNotFound,[IntToStr(PtrInt(Name))])
  1338. else
  1339. raise EResNotFound.CreateFmt(SResNotFound,[Name]);
  1340. SetPointer(LockResource(Handle),SizeOfResource(Instance,Res));
  1341. end;
  1342. constructor TResourceStream.Create(Instance: TFPResourceHMODULE; const ResName: string; ResType: PChar);
  1343. begin
  1344. inherited create;
  1345. Initialize(Instance,pchar(ResName),ResType,False);
  1346. end;
  1347. constructor TResourceStream.CreateFromID(Instance: TFPResourceHMODULE; ResID: Integer; ResType: PChar);
  1348. begin
  1349. inherited create;
  1350. Initialize(Instance,pchar(PtrInt(ResID)),ResType,True);
  1351. end;
  1352. {$endif FPC_OS_UNICODE}
  1353. destructor TResourceStream.Destroy;
  1354. begin
  1355. UnlockResource(Handle);
  1356. FreeResource(Handle);
  1357. inherited destroy;
  1358. end;
  1359. {****************************************************************************}
  1360. {* TOwnerStream *}
  1361. {****************************************************************************}
  1362. constructor TOwnerStream.Create(ASource: TStream);
  1363. begin
  1364. FSource:=ASource;
  1365. end;
  1366. destructor TOwnerStream.Destroy;
  1367. begin
  1368. If FOwner then
  1369. FreeAndNil(FSource);
  1370. inherited Destroy;
  1371. end;
  1372. {****************************************************************************}
  1373. {* TStreamAdapter *}
  1374. {****************************************************************************}
  1375. constructor TStreamAdapter.Create(Stream: TStream; Ownership: TStreamOwnership = soReference);
  1376. begin
  1377. inherited Create;
  1378. FStream:=Stream;
  1379. FOwnership:=Ownership;
  1380. m_bReverted:=false; // mantis 15003
  1381. // http://www.tech-archive.net/Archive/German/microsoft.public.de.vc/2005-08/msg00791.html
  1382. // http://code.google.com/p/ddab-lib/wiki/TPJIStreamWrapper
  1383. end;
  1384. destructor TStreamAdapter.Destroy;
  1385. begin
  1386. if StreamOwnership=soOwned then
  1387. FreeAndNil(FStream);
  1388. inherited Destroy;
  1389. end;
  1390. {$push}
  1391. {$warnings off}
  1392. function TStreamAdapter.Read(pv: Pointer; cb: DWORD; pcbRead: PDWORD): HResult; stdcall;
  1393. var
  1394. readcount: Longint;
  1395. begin
  1396. if m_bReverted then
  1397. begin
  1398. Result := STG_E_REVERTED;
  1399. Exit;
  1400. end;
  1401. if pv = nil then
  1402. begin
  1403. Result := STG_E_INVALIDPOINTER;
  1404. Exit;
  1405. end;
  1406. readcount := FStream.Read(pv^, cb);
  1407. if pcbRead <> nil then pcbRead^ := readcount;
  1408. Result := S_OK;
  1409. end;
  1410. function TStreamAdapter.Write(pv: Pointer; cb: DWORD; pcbWritten: PDWORD): HResult; stdcall;
  1411. var
  1412. writecount: Longint;
  1413. begin
  1414. if m_bReverted then
  1415. begin
  1416. Result := STG_E_REVERTED;
  1417. Exit;
  1418. end;
  1419. if pv = nil then
  1420. begin
  1421. Result := STG_E_INVALIDPOINTER;
  1422. Exit;
  1423. end;
  1424. writecount := FStream.Write(pv^, cb);
  1425. if pcbWritten <> nil then pcbWritten^ := writecount;
  1426. Result := S_OK;
  1427. end;
  1428. function TStreamAdapter.Seek(dlibMove: LargeInt; dwOrigin: DWORD; out libNewPosition: LargeUint): HResult; stdcall;
  1429. var
  1430. newpos: QWord;
  1431. begin
  1432. if m_bReverted then
  1433. begin
  1434. Result := STG_E_REVERTED;
  1435. Exit;
  1436. end;
  1437. case dwOrigin of
  1438. STREAM_SEEK_SET: newpos := FStream.Seek(dlibMove, soBeginning);
  1439. STREAM_SEEK_CUR: newpos := FStream.Seek(dlibMove, soCurrent);
  1440. STREAM_SEEK_END: newpos := FStream.Seek(dlibMove, soEnd);
  1441. else
  1442. begin
  1443. Result := STG_E_INVALIDFUNCTION;
  1444. Exit;
  1445. end;
  1446. end;
  1447. if @libNewPosition <> nil then
  1448. libNewPosition := newpos;
  1449. Result := S_OK;
  1450. end;
  1451. function TStreamAdapter.SetSize(libNewSize: LargeUint): HResult; stdcall;
  1452. begin
  1453. if m_bReverted then
  1454. begin
  1455. Result := STG_E_REVERTED;
  1456. Exit;
  1457. end;
  1458. if libNewSize<0 then
  1459. begin
  1460. Result := STG_E_INVALIDFUNCTION;
  1461. Exit;
  1462. end;
  1463. try
  1464. FStream.Size := libNewSize;
  1465. Result := S_OK;
  1466. except
  1467. // TODO: return different error value according to exception like STG_E_MEDIUMFULL
  1468. Result := E_FAIL;
  1469. end;
  1470. end;
  1471. function TStreamAdapter.CopyTo(stm: IStream; cb: LargeUint; out cbRead: LargeUint; out cbWritten: Largeuint): HResult; stdcall;
  1472. var
  1473. sz: dword;
  1474. buffer : array[0..1023] of byte;
  1475. begin
  1476. if m_bReverted then
  1477. begin
  1478. Result := STG_E_REVERTED;
  1479. Exit;
  1480. end;
  1481. // the method is similar to TStream.CopyFrom => use CopyFrom implementation
  1482. cbWritten := 0;
  1483. cbRead := 0;
  1484. while cb > 0 do
  1485. begin
  1486. if (cb > sizeof(buffer)) then
  1487. sz := sizeof(Buffer)
  1488. else
  1489. sz := cb;
  1490. sz := FStream.Read(buffer[0],sz);
  1491. inc(cbRead, sz);
  1492. stm.Write(@buffer[0], sz, @sz);
  1493. inc(cbWritten, sz);
  1494. if sz = 0 then
  1495. begin
  1496. Result := E_FAIL;
  1497. Exit;
  1498. end;
  1499. dec(cb, sz);
  1500. end;
  1501. Result := S_OK;
  1502. end;
  1503. function TStreamAdapter.Commit(grfCommitFlags: DWORD): HResult; stdcall;
  1504. begin
  1505. if m_bReverted then
  1506. Result := STG_E_REVERTED
  1507. else
  1508. Result := S_OK;
  1509. end;
  1510. function TStreamAdapter.Revert: HResult; stdcall;
  1511. begin
  1512. m_bReverted := True;
  1513. Result := S_OK;
  1514. end;
  1515. function TStreamAdapter.LockRegion(libOffset: LargeUint; cb: LargeUint; dwLockType: DWORD): HResult; stdcall;
  1516. begin
  1517. Result := STG_E_INVALIDFUNCTION;
  1518. end;
  1519. function TStreamAdapter.UnlockRegion(libOffset: LargeUint; cb: LargeUint; dwLockType: DWORD): HResult; stdcall;
  1520. begin
  1521. Result := STG_E_INVALIDFUNCTION;
  1522. end;
  1523. function TStreamAdapter.Stat(out statstg: TStatStg; grfStatFlag: DWORD): HResult; stdcall;
  1524. begin
  1525. if m_bReverted then
  1526. begin
  1527. Result := STG_E_REVERTED;
  1528. Exit;
  1529. end;
  1530. if grfStatFlag in [STATFLAG_DEFAULT,STATFLAG_NOOPEN,STATFLAG_NONAME] then
  1531. begin
  1532. if @statstg <> nil then
  1533. begin
  1534. fillchar(statstg, sizeof(TStatStg),#0);
  1535. { //TODO handle pwcsName
  1536. if grfStatFlag = STATFLAG_DEFAULT then
  1537. runerror(217) //Result :={$ifdef windows} STG_E_INVALIDFLAG{$else}E_INVALID_FLAG{$endif}
  1538. }
  1539. statstg.dwType := STGTY_STREAM;
  1540. statstg.cbSize := FStream.Size;
  1541. statstg.grfLocksSupported := LOCK_WRITE;
  1542. end;
  1543. Result := S_OK;
  1544. end else
  1545. Result := STG_E_INVALIDFLAG
  1546. end;
  1547. function TStreamAdapter.Clone(out stm: IStream): HResult; stdcall;
  1548. begin
  1549. if m_bReverted then
  1550. begin
  1551. Result := STG_E_REVERTED;
  1552. Exit;
  1553. end;
  1554. // don't raise an exception here return error value that function is not implemented
  1555. // to implement this we need a clone method for TStream class
  1556. Result := STG_E_UNIMPLEMENTEDFUNCTION;
  1557. end;
  1558. constructor TProxyStream.Create(const Stream: IStream);
  1559. begin
  1560. FStream := Stream;
  1561. end;
  1562. function TProxyStream.Read(var Buffer; Count: Longint): Longint;
  1563. begin
  1564. Check(FStream.Read(@Buffer, Count, @Result));
  1565. end;
  1566. function TProxyStream.Seek(const Offset: int64; Origin: TSeekOrigin): int64;
  1567. begin
  1568. Check(FStream.Seek(Offset, ord(Origin), QWord(result)));
  1569. end;
  1570. function TProxyStream.Write(const Buffer; Count: Longint): Longint;
  1571. begin
  1572. Check(FStream.Write(@Buffer, Count, @Result));
  1573. end;
  1574. function TProxyStream.GetIStream: IStream;
  1575. begin
  1576. Result := FStream;
  1577. end;
  1578. procedure TProxyStream.Check(err:integer);
  1579. var e : EInOutError;
  1580. begin
  1581. e:= EInOutError.Create('Proxystream.Check');
  1582. e.Errorcode:=err;
  1583. raise e;
  1584. end;
  1585. {$pop}