bank.bmx 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. Strict
  2. Rem
  3. bbdoc: Miscellaneous/Banks
  4. End Rem
  5. Module BRL.Bank
  6. ModuleInfo "Version: 1.06"
  7. ModuleInfo "Author: Mark Sibly"
  8. ModuleInfo "License: zlib/libpng"
  9. ModuleInfo "Copyright: Blitz Research Ltd"
  10. ModuleInfo "Modserver: BRL"
  11. ModuleInfo "History: 1.06 Release"
  12. ModuleInfo "History: Added Lock/Unlock to replace Buf"
  13. ModuleInfo "History: 1.05 Release"
  14. ModuleInfo "History: Fixed Read/Write using ReadBytes/WriteBytes"
  15. Import BRL.Stream
  16. Rem
  17. bbdoc: Memory bank
  18. end rem
  19. Type TBank
  20. Field _buf:Byte Ptr,_size,_capacity,_locked
  21. Method _pad()
  22. End Method
  23. Method Delete()
  24. Assert Not _locked
  25. If _capacity>=0 MemFree _buf
  26. End Method
  27. Rem
  28. bbdoc: Get a bank's memory pointer
  29. returns: A byte pointer to the memory block controlled by the bank
  30. about:
  31. Please use #Lock and #Unlock instead of this method.
  32. End Rem
  33. Method Buf:Byte Ptr()
  34. Return _buf
  35. End Method
  36. Rem
  37. bbdoc: Lock a bank's memory block
  38. returns: A byte pointer to the memory block controlled by the bank
  39. about:
  40. While locked, a bank cannot be resized.
  41. After you have finished with a bank's memory block, you must use #Unlock
  42. to return it to the bank.
  43. End Rem
  44. Method Lock:Byte Ptr()
  45. _locked:+1
  46. Return _buf
  47. End Method
  48. Rem
  49. bbdoc: Unlock a bank's memory pointer
  50. about:
  51. After you have finished with a bank's memory block, you must use #Unlock
  52. to return it to the bank.
  53. End Rem
  54. Method Unlock()
  55. _locked:-1
  56. End Method
  57. Rem
  58. bbdoc: Get a bank's size
  59. returns: The size, in bytes, of the memory block controlled by the bank
  60. End Rem
  61. Method Size()
  62. Return _size
  63. End Method
  64. Rem
  65. bbdoc: Get capacity of bank
  66. returns: The capacity, in bytes, of the bank's internal memory buffer
  67. end rem
  68. Method Capacity()
  69. Return _capacity
  70. End Method
  71. Rem
  72. bbdoc: Resize a bank
  73. end rem
  74. Method Resize( size )
  75. Assert _locked=0 Else "Locked banks cannot be resize"
  76. Assert _capacity>=0 Else "Static banks cannot be resized"
  77. If size>_capacity
  78. Local n=_capacity*3/2
  79. If n<size n=size
  80. Local tmp:Byte Ptr=MemAlloc(n)
  81. MemCopy tmp,_buf,_size
  82. MemFree _buf
  83. _capacity=n
  84. _buf=tmp
  85. EndIf
  86. _size=size
  87. End Method
  88. Rem
  89. bbdoc: Read bytes from a stream into a bank
  90. end rem
  91. Method Read( stream:TStream,offset,count )
  92. Assert offset>=0 And offset<=_size-count Else "Illegal bank offset"
  93. Return stream.Read( _buf+offset,count )
  94. End Method
  95. Rem
  96. bbdoc: Write bytes in a bank to a stream
  97. end rem
  98. Method Write( stream:TStream,offset,count )
  99. Assert offset>=0 And offset<=_size-count Else "Illegal bank offset"
  100. Return stream.Write( _buf+offset,count )
  101. End Method
  102. Rem
  103. bbdoc: Peek a byte from a bank
  104. returns: The byte value at the specified byte offset within the bank
  105. end rem
  106. Method PeekByte( offset )
  107. Assert offset>=0 And offset<_size Else "Illegal bank offset"
  108. Return _buf[offset]
  109. End Method
  110. Rem
  111. bbdoc: Poke a byte into a bank
  112. end rem
  113. Method PokeByte( offset,value )
  114. Assert offset>=0 And offset<_size Else "Illegal bank offset"
  115. _buf[offset]=value
  116. End Method
  117. Rem
  118. bbdoc: Peek a short from a bank
  119. returns: The short value at the specified byte offset within the bank
  120. end rem
  121. Method PeekShort( offset )
  122. Assert offset>=0 And offset<_size-1 Else "Illegal bank offset"
  123. Return (Short Ptr(_buf+offset))[0]
  124. End Method
  125. Rem
  126. bbdoc: Poke a short into a bank
  127. end rem
  128. Method PokeShort( offset,value )
  129. Assert offset>=0 And offset<_size-1 Else "Illegal bank offset"
  130. (Short Ptr(_buf+offset))[0]=value
  131. End Method
  132. Rem
  133. bbdoc: Peek an int from a bank
  134. returns: The int value at the specified byte offset within the bank
  135. end rem
  136. Method PeekInt( offset )
  137. Assert offset>=0 And offset<_size-3 Else "Illegal bank offset"
  138. Return (Int Ptr(_buf+offset))[0]
  139. End Method
  140. Rem
  141. bbdoc: Poke an int into a bank
  142. end rem
  143. Method PokeInt( offset,value )
  144. Assert offset>=0 And offset<_size-3 Else "Illegal bank offset"
  145. (Int Ptr(_buf+offset))[0]=value
  146. End Method
  147. Rem
  148. bbdoc: Peek a long from a bank
  149. returns: The long value at the specified byte offset within the bank
  150. end rem
  151. Method PeekLong:Long( offset )
  152. Assert offset>=0 And offset<_size-7 Else "Illegal bank offset"
  153. Return (Long Ptr(_buf+offset))[0]
  154. End Method
  155. Rem
  156. bbdoc: Poke a long value into a bank
  157. end rem
  158. Method PokeLong( offset,value:Long )
  159. Assert offset>=0 And offset<_size-7 Else "Illegal bank offset"
  160. (Long Ptr(_buf+offset))[0]=value
  161. End Method
  162. Rem
  163. bbdoc: Peek a float from a bank
  164. returns: The float value at the specified byte offset within the bank
  165. end rem
  166. Method PeekFloat#( offset )
  167. Assert offset>=0 And offset<_size-3 Else "Illegal bank offset"
  168. Return (Float Ptr(_buf+offset))[0]
  169. End Method
  170. Rem
  171. bbdoc: Poke a float value into a bank
  172. end rem
  173. Method PokeFloat( offset,value# )
  174. Assert offset>=0 And offset<_size-3 Else "Illegal bank offset"
  175. (Float Ptr(_buf+offset))[0]=value
  176. End Method
  177. Rem
  178. bbdoc: Peek a double from a bank
  179. returns: The double value at the specified byte offset within the bank
  180. end rem
  181. Method PeekDouble!( offset )
  182. Assert offset>=0 And offset<_size-7 Else "Illegal bank offset"
  183. Return (Double Ptr(_buf+offset))[0]
  184. End Method
  185. Rem
  186. bbdoc: Poke a double value into a bank
  187. end rem
  188. Method PokeDouble( offset,value! )
  189. Assert offset>=0 And offset<_size-7 Else "Illegal bank offset"
  190. (Double Ptr(_buf+offset))[0]=value
  191. End Method
  192. Rem
  193. bbdoc: Save a bank to a stream
  194. about:
  195. Return True if successful, otherwise False.
  196. end rem
  197. Method Save( url:Object )
  198. Local stream:TStream=WriteStream( url )
  199. If Not stream Return
  200. Local n=stream.WriteBytes( _buf,_size )
  201. stream.Close
  202. Return True
  203. End Method
  204. Rem
  205. bbdoc: Load a bank from a stream
  206. returns: A new TBank object
  207. about:
  208. Returns a new TBank object if successfull, otherwise Null.
  209. end rem
  210. Function Load:TBank( url:Object )
  211. Local stream:TStream=ReadStream( url )
  212. If Not stream Return
  213. Local data:Byte[]=LoadByteArray( stream )
  214. Local bank:TBank=Create( data.length )
  215. MemCopy bank.Buf(),data,data.length
  216. stream.Close
  217. Return bank
  218. End Function
  219. Rem
  220. bbdoc: Create a bank
  221. returns: A new TBank object with an initial size of @size
  222. end rem
  223. Function Create:TBank( size )
  224. Assert size>=0 Else "Illegal bank size"
  225. Local bank:TBank=New TBank
  226. bank._buf=MemAlloc( size )
  227. bank._size=size
  228. bank._capacity=size
  229. Return bank
  230. End Function
  231. Rem
  232. bbdoc: Create a bank from an existing block of memory
  233. end rem
  234. Function CreateStatic:TBank( buf:Byte Ptr,size )
  235. Assert size>=0 Else "Illegal bank size"
  236. Local bank:TBank=New TBank
  237. bank._buf=buf
  238. bank._size=size
  239. bank._capacity=-1
  240. Return bank
  241. End Function
  242. End Type
  243. Rem
  244. bbdoc: Create a bank
  245. returns: A bank object with an initial size of @size bytes
  246. about:
  247. #CreateBank creates a Bank allocating a specified amount of memory that
  248. can be used for storage of binary data using the various Poke and
  249. Peek commands.
  250. End Rem
  251. Function CreateBank:TBank( size=0 )
  252. Return TBank.Create( size )
  253. End Function
  254. Rem
  255. bbdoc: Create a bank with existing data
  256. returns: A bank object that references an existing block of memory
  257. about:
  258. The memory referenced by a static bank is not released when the bank is deleted.
  259. A static bank cannot be resized.
  260. End Rem
  261. Function CreateStaticBank:TBank( buf:Byte Ptr,size )
  262. Return TBank.CreateStatic( buf,size )
  263. End Function
  264. Rem
  265. bbdoc: Load a bank
  266. returns: A bank containing the binary contents of @url, or null if @url could not be opened
  267. about:
  268. #LoadBank reads the entire contents of a binary file from a specified @url into a newly
  269. created bank with a size matching that of the file.
  270. end rem
  271. Function LoadBank:TBank( url:Object )
  272. Return TBank.Load( url )
  273. End Function
  274. Rem
  275. bbdoc: Save a bank
  276. returns: True if successful.
  277. about:
  278. #SaveBank writes it's entire contents to a @url. If the @url is a file path a new
  279. file is created.
  280. end rem
  281. Function SaveBank( bank:TBank,url:Object )
  282. Return bank.Save( url )
  283. End Function
  284. Rem
  285. bbdoc: Get bank's memory buffer
  286. returns: A byte pointer to the bank's internal memory buffer
  287. about:
  288. Please use #LockBank and #UnlockBank instead of this method.
  289. End Rem
  290. Function BankBuf:Byte Ptr( bank:TBank )
  291. Return bank.Buf()
  292. End Function
  293. Rem
  294. bbdoc: Lock a bank's memory block
  295. returns: A byte pointer to the memory block controlled by the bank.
  296. about:
  297. While locked, a bank cannot be resized.
  298. After you have finished with a bank's memory block, you must use #UnlockBank
  299. to return it to the bank.
  300. End Rem
  301. Function LockBank:Byte Ptr( bank:TBank )
  302. Return bank.Lock()
  303. End Function
  304. Rem
  305. bbdoc: Unlock a bank's memory block
  306. about:
  307. After you have finished with a bank's memory block, you must use #UnlockBank
  308. to return it to the bank.
  309. End Rem
  310. Function UnlockBank( bank:TBank )
  311. bank.Unlock
  312. End Function
  313. Rem
  314. bbdoc: Get size of bank
  315. returns: The size, in bytes, of the bank's internal memory buffer
  316. end rem
  317. Function BankSize( bank:TBank )
  318. Return bank.Size()
  319. End Function
  320. Rem
  321. bbdoc: Get capacity of bank
  322. returns: The capacity, in bytes, of the bank's internal memory buffer
  323. about:
  324. The capacity of a bank is the size limit before a bank must allocate
  325. more memory due to a resize. Bank capacity may be increased due to a call
  326. to #ResizeBank by either 50% or the requested amount, whichever is greater.
  327. Capacity never decreases.
  328. end rem
  329. Function BankCapacity( bank:TBank )
  330. Return bank.Capacity()
  331. End Function
  332. Rem
  333. bbdoc: Resize a bank
  334. about:
  335. #ResizeBank modifies the size limit of a bank. This may cause memory to be
  336. allocated if the requested size is greater than the bank's current capacity,
  337. see #BankCapacity for more information.
  338. end rem
  339. Function ResizeBank( bank:TBank,size )
  340. bank.Resize size
  341. End Function
  342. Rem
  343. bbdoc: Copy bank contents
  344. about:
  345. #CopyBank copies @count bytes from @src_offset in @src_bank to @dst_offset
  346. in @dst_bank.
  347. end rem
  348. Function CopyBank( src_bank:TBank,src_offset,dst_bank:TBank,dst_offset,count )
  349. Assert..
  350. count>=0 And..
  351. src_offset>=0 And..
  352. dst_offset>=0 And..
  353. src_offset+count<=src_bank.Size() And..
  354. dst_offset+count<=dst_bank.size() Else "Illegal range for CopyBank"
  355. MemCopy( dst_bank.Buf()+dst_offset,src_bank.Buf()+src_offset,count )
  356. End Function
  357. Rem
  358. bbdoc: Peek a byte from a bank
  359. returns: The byte value at the specified byte offset within the bank
  360. about:
  361. A byte is an unsigned 8 bit value with a range of 0..255.
  362. end rem
  363. Function PeekByte( bank:TBank,offset )
  364. Return bank.PeekByte( offset )
  365. End Function
  366. Rem
  367. bbdoc: Poke a byte into a bank
  368. end rem
  369. Function PokeByte( bank:TBank,offset,value )
  370. bank.PokeByte offset,value
  371. End Function
  372. Rem
  373. bbdoc: Peek a short from a bank
  374. returns: The short value at the specified byte offset within the bank
  375. about:
  376. A short is an unsigned 16 bit (2 bytes) value with a range of 0..65535.
  377. end rem
  378. Function PeekShort( bank:TBank,offset )
  379. Return bank.PeekShort( offset )
  380. End Function
  381. Rem
  382. bbdoc: Poke a short into a bank
  383. about:
  384. An short is an unsigned 16 bit value that requires 2 bytes of storage.
  385. end rem
  386. Function PokeShort( bank:TBank,offset,value )
  387. bank.PokeShort offset,value
  388. End Function
  389. Rem
  390. bbdoc: Peek an int from a bank
  391. returns: The int value at the specified byte offset within the bank
  392. about:
  393. An int is a signed 32 bit value (4 bytes).
  394. end rem
  395. Function PeekInt( bank:TBank,offset )
  396. Return bank.PeekInt( offset )
  397. End Function
  398. Rem
  399. bbdoc: Poke an int into a bank
  400. about:
  401. An int is a signed 32 bit value that requires 4 bytes of storage.
  402. end rem
  403. Function PokeInt( bank:TBank,offset,value )
  404. bank.PokeInt offset,value
  405. End Function
  406. Rem
  407. bbdoc: Peek a long integer from a bank
  408. returns: The long integer value at the specified byte offset within the bank
  409. about:
  410. A long is a 64 bit integer that requires 8 bytes of memory.
  411. end rem
  412. Function PeekLong:Long( bank:TBank,offset )
  413. Return bank.PeekLong( offset )
  414. End Function
  415. Rem
  416. bbdoc: Poke a long integer int into a bank
  417. about:
  418. A long is a 64 bit integer that requires 8 bytes of storage.
  419. end rem
  420. Function PokeLong( bank:TBank,offset,value:Long )
  421. bank.PokeLong offset,value
  422. End Function
  423. Rem
  424. bbdoc: Peek a float from a bank
  425. returns: The float value at the specified byte offset within the bank
  426. about:
  427. A float requires 4 bytes of storage
  428. end rem
  429. Function PeekFloat#( bank:TBank,offset )
  430. Return bank.PeekFloat( offset )
  431. End Function
  432. Rem
  433. bbdoc: Poke a float into a bank
  434. about:
  435. A float requires 4 bytes of storage
  436. end rem
  437. Function PokeFloat( bank:TBank,offset,value# )
  438. bank.PokeFloat offset,value
  439. End Function
  440. Rem
  441. bbdoc: Peek a double from a bank
  442. returns: The double value at the specified byte offset within the bank
  443. about:
  444. A double requires 8 bytes of storage
  445. end rem
  446. Function PeekDouble!( bank:TBank,offset )
  447. Return bank.PeekDouble( offset )
  448. End Function
  449. Rem
  450. bbdoc: Poke a double into a bank
  451. about:
  452. A double requires 8 bytes of storage
  453. end rem
  454. Function PokeDouble( bank:TBank,offset,value! )
  455. bank.PokeDouble offset,value
  456. End Function
  457. Rem
  458. bbdoc: Read bytes from a Stream to a Bank
  459. returns: The number of bytes successfully read from the Stream
  460. end rem
  461. Function ReadBank( bank:TBank,stream:TStream,offset,count )
  462. Return bank.Read( stream,offset,count )
  463. End Function
  464. Rem
  465. bbdoc: Write bytes from a Bank to a Stream
  466. returns: The number of bytes successfully written to the Stream
  467. end rem
  468. Function WriteBank( bank:TBank,stream:TStream,offset,count )
  469. Return bank.Write( stream,offset,count )
  470. End Function