Advertisement
Guest User

Untitled

a guest
Dec 14th, 2014
246
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.34 KB | None | 0 0
  1. --[[
  2. 1 minute - 240 KiB - 480 blocks
  3. block pinters - 2 byte - 65536 blocks max
  4.  
  5. Bytes in block starts from 1
  6.  
  7. root block:
  8. 1-3 string: 3 bytes \236\32\45 (yes, it's a just 3 random bytes)
  9. 4 block size multiplier (m): default 1 (1 byte)
  10. 5-36 partiton component id (32 bytes)
  11. 38-68 partiotion name (32 bytes)
  12. 69-(m*512-2) list of dir/file headers (which have parent 0)
  13. (m*512-2)-(m*512) pointer to next block (type 3) or end block if this is end of list (2 bytes)
  14.  
  15. file/dir block:
  16. 1-2 block type
  17. 3-4 parent block id: 2 bytes (if type is 3 or 4, points to header block, else points to parent dir header (if in root directory, then 0))
  18. 5-68 file/dir name: 64 bytes (header only)
  19. 69-70 size in blocks, type 5 only
  20. 69-(m*512-2) content of file or list of child dirs (2 bytes per entry)
  21. (m*512-1)-(m*512) pointer to next block or 0 if this is end of list/content (2 bytes)
  22.  
  23. types
  24. 0: empty
  25. 1: dir header
  26. 2: dir childs
  27. 3: file header
  28. 4: file content
  29. 5: audio file -- somewhen
  30.  
  31. 65535: partition end
  32. ]]--
  33.  
  34. local component = component or require("component")
  35.  
  36. local function nt2(n) --number to symbols (2 byte)
  37. return string.char(bit32.rshift(bit32.band(n,0xFF00),8), bit32.band(n,0xFF))
  38. end
  39.  
  40. local function nt1(n) --number to symbol
  41. return string.char(bit32.band(n,0xFF))
  42. end
  43.  
  44. local function nf2(s) --symbols to number (2 byte)
  45. local b1, b2 = string.byte(s,1,2)
  46. return bit32.bor(bit32.lshift(b1,8), b2)
  47. end
  48.  
  49. local function nf1(s) --symbol to number
  50. return string.byte(s)
  51. end
  52.  
  53. -------varuables-------
  54.  
  55. local ufs = {}
  56. ufs.cache = {} --[block] fields: name:string, type:number, parent:number, next:number
  57. ufs.blocks = {} --blocks info
  58. --ufs.dirs = {} --dirs functions
  59. --ufs.files = {} --files functions
  60. ufs.fs = {} --fs functions
  61. ufs.tape = {} --use ufs.tape(address) to set tape address
  62. ufs.start = nil --root block/partition start offset
  63. ufs.endoff = nil --end offset
  64. ufs.pos = 0 --current position on tape
  65.  
  66. ------blocks info------
  67. ufs.blocks[0] = {} --empty block
  68. ufs.blocks[0].name = false --name?
  69. ufs.blocks[0].next = false --next block?
  70. ufs.blocks[0].header = true --is header?
  71. ufs.blocks[0].cont = false --continue of header?
  72.  
  73. ufs.blocks[1] = {}
  74. ufs.blocks[1].name = true
  75. ufs.blocks[1].next = true
  76. ufs.blocks[1].header = true
  77. ufs.blocks[1].cont = false
  78.  
  79. ufs.blocks[2] = {}
  80. ufs.blocks[2].name = true
  81. ufs.blocks[2].next = true
  82. ufs.blocks[2].header = true
  83. ufs.blocks[2].cont = false
  84.  
  85. ufs.blocks[3] = {}
  86. ufs.blocks[3].name = false
  87. ufs.blocks[3].next = true
  88. ufs.blocks[3].header = false
  89. ufs.blocks[3].cont = true
  90.  
  91. ufs.blocks[4] = {}
  92. ufs.blocks[4].name = false
  93. ufs.blocks[4].next = true
  94. ufs.blocks[4].header = false
  95. ufs.blocks[4].cont = true
  96.  
  97. ufs.blocks[5] = {}
  98. ufs.blocks[5].name = true
  99. ufs.blocks[5].next = false
  100. ufs.blocks[5].header = true
  101. ufs.blocks[5].cont = false
  102.  
  103. ufs.blocks[65535] = {}
  104. ufs.blocks[65535].name = false
  105. ufs.blocks[65535].next = false
  106. ufs.blocks[65535].header= false
  107. ufs.blocks[65535].cont = false
  108. -----------------------
  109.  
  110. setmetatable(ufs.tape,{
  111. __call = function(address)
  112. if type(ufs.tape.address) == "string" and ufs.tape.address ~= address and component.list()[address] == "tape_drive" then
  113. ufs.cache = {} --clear cache and positions because we will use different tape
  114. ufs.start = nil
  115. ufs.endoff = nil
  116. ufs.pos = 0
  117. --nah? ufs.fs.loaded = nil
  118.  
  119. local mt = getmetatable(ufs.tape)
  120. ufs.tape = {}
  121. ufs.tape = component.proxy(address)
  122. setmetatable(ufs.tape,mt)
  123. mt = {}
  124.  
  125. ufs.tape.address = address
  126. return true
  127. elseif ufs.tape.address == address then
  128. return false,"tape already set"
  129. elseif type(ufs.tape.address) ~= "string" then
  130. error("Address is not a string")
  131. else
  132. error("Component is not a tape drive")
  133. end
  134. end
  135. })
  136.  
  137. function ufs.findRoot()
  138. ufs.tape.seek(ufs.tape.getSize())
  139. ufs.pos = 0
  140. ufs.start = nil
  141. ufs.endoff = nil
  142.  
  143. repeat
  144. local b3 = ufs.tape.read(3)
  145. ufs.tape.seek(-2)
  146. ufs.pos = ufs.pos + 1
  147.  
  148. if "\236\32\45" == b3 then
  149. ufs.start = ufs.pos - 1
  150. break
  151. end
  152. until ufs.tape.getSize() - 1024 == pos
  153. end
  154.  
  155. function ufs.getMultiplier()
  156. if ufs.multiplier then
  157. return ufs.nultiplier, "use ufs.multiplier"
  158. end
  159. ufs.tape.seek(ufs.start - ufs.pos + 3)
  160. ufs.multiplier = read(1)
  161. ufs.pos = ufs.start + 3
  162. return ufs.multiplier
  163. end
  164.  
  165. function ufs.getType(block)
  166. if block < 0 or block * ufs.multiplier * 512 >= ufs.endoff then
  167. return false, "not a ufs block"
  168. end
  169.  
  170. if ufs.cache[block] and ufs.cache[block].type then --check cache
  171. return ufs.cache[block].type
  172. end
  173.  
  174. ufs.pos = ufs.pos + ufs.tape.seek(ufs.start - ufs.pos + ufs.multiplier * 512 * block) + 2
  175. local btype = (ufs.cache[block] and ufs.cache[block].type) or nf2(ufs.tape.read(2))
  176.  
  177. if ufs.cache[block] == nil then
  178. ufs.cache[block] = {}
  179. end
  180. if ufs.cache[block].type == nil then
  181. ufs.cache[block].type = btype
  182. end
  183. return btype
  184. end
  185.  
  186. function ufs.isBlock(block)
  187. if ufs.block[(ufs.getType(block))] ~= nil then
  188. return true
  189. end
  190. return false
  191. end
  192.  
  193. function ufs.getNext(block)
  194. if ufs.isBlocks(block) and ufs.blocks[ufs.getType(block)].next then
  195. if ufs.cache[block] and ufs.cache[block].next then
  196. return ufs.cache[block].next
  197. end
  198.  
  199. ufs.pos = ufs.pos + ufs.tape.seek(ufs.start - ufs.pos + ufs.multiplier * 512 * (block + 1) - 2) + 2
  200. local nextb = nf2(ufs.tape.read(2))
  201. if ufs.cache[block] == nil then --cache for block exists?
  202. ufs.cache[block] = {}
  203. end
  204. ufs.cache[block].next = nextb
  205. return nextb
  206. end
  207. return false
  208. end
  209.  
  210. function ufs.setNext(block)
  211. if ufs.isBlock(block) then
  212. if ufs.block[ufs.getType(block)].next then
  213.  
  214. end
  215. end
  216. end
  217.  
  218. function ufs.getParrent(block)
  219. if block == 0 then
  220. return false, "root block"
  221. elseif ufs.isBlock(block) then
  222. if ufs.cache[block] and ufs.cache[block].parrent then
  223. return ufs.cache[block].parrent
  224. end
  225.  
  226. ufs.pos = ufs.pos + ufs.tape.seek(ufs.start - ufs.pos + ufs.multiplier * 512 * block + 2) + 2
  227. local parrent = nf2(ufs.tape.read(2))
  228.  
  229. if ufs.cache[block] == nil then
  230. ufs.cache[block] = {}
  231. end
  232. if ufs.cache[block].parrent == nil then
  233. ufs.cache[block].parrent = parrent
  234. end
  235. return parrent
  236. end
  237. return false, "not a ufs block"
  238. end
  239.  
  240. function ufs.getName(block) --get file/folder name
  241. if ufs.isBlock(block) and ufs.blocks[ufs.getType(block)].cont and block ~= 0 then
  242. return ufs.getName(ufs.getParrent(block)) --get name from header
  243. elseif ufs.isBlock(block) and blocks[ufs.getType(block)].name then --named block
  244. if ufs.cache[block] and ufs.cache[block].name then --check cache
  245. return ufs.cache[block].name
  246. end
  247.  
  248. ufs.pos = ufs.pos + ufs.tape.seek(ufs.start - ufs.pos + ufs.multiplier * 512 * block + 4) + 64
  249. local name = string.grep(ufs.tape.read(64), "[\0/]", "")
  250.  
  251. if ufs.cache[block] == nil then --cache for block exists?
  252. ufs.cache[block] = {}
  253. end
  254. ufs.cache[block].name = name
  255.  
  256. return name
  257. else
  258. return false,(ufs.blocks[ufs.getType(block)] == nil and "not a ufs block") or "no field name on block"
  259. end
  260. end
  261.  
  262. function ufs.setName(block,name) --set file/folder name
  263. if type(name) ~= "string" then
  264. error("Invalid argument #2: string expected, got " .. type(name))
  265. end
  266. if #name > 64 then
  267. error("Invalid argument #2: name cant be longer than 64 symbols")
  268. end
  269.  
  270. if ufs.isBlock(block) and ufs.blocks[ufs.getType(block)].name then
  271. if ufs.cache[block] == nil then
  272. ufs.cache[block] = {}
  273. end
  274. if ufs.cache[block].name ~= name then
  275. ufs.pos = ufs.pos + ufs.tape.seek(ufs.start - ufs.pos + ufs.multiplier * 512 * block + 4) + 64
  276. ufs.tape.write(name .. string.rep("\0", 64 - #name))
  277. ufs.cache[block].name = name
  278. return true
  279. end
  280. return false, "name already set"
  281. elseif ufs.isBlock(block) then
  282. return false, "no field name on block"
  283. end
  284.  
  285. end
  286.  
  287. function ufs.findEnd()
  288. if ufs.endoff then
  289. return ufs.endoff, "use ufs.endoff"
  290. end
  291.  
  292. local nblock = ufs.getNext(0)
  293. while ufs.getType(nblock) ~= 65535 do
  294. nblock = ufs.getNext(nblock)
  295. end
  296. if ufs.getType(nblock) == 65535 then
  297. ufs.endoff = ufs.start + ufs.multiplier * 512 * nblock
  298. else
  299. error("No end of partition found")
  300. end
  301. end
  302.  
  303. function ufs.pathBlock(path) --returns path's block
  304. if path == "/" then
  305. return 0
  306. else
  307.  
  308. end
  309. end
  310.  
  311. function ufs.blockPath(block) --returns block's path
  312. if ufs.isBlock(block) and block ~= 0 then
  313. local bpath = ufs.getName(block)
  314. repeat
  315. local bparrent = ufs.getParrent(bparrent or block)
  316. bpath = (brappent ~= 0 and (ufs.getName(bparrent))) or "" .. "/" .. bpath
  317. until bparrent == 0
  318. return bpath
  319. elseif block == 0 then --so we wont add more if's to .fs path functions
  320. return "/"
  321. end
  322. end
  323.  
  324. function ufs.childs(block) --returns table with addresses of child blocks, type
  325. local offs = 4
  326. if ufs.isBlock(block) == false then
  327. return false,"not a ufs block"
  328. elseif ufs.isBlock(block) and (ufs.getType(block) == 1 or ufs.getType(block) == 0) then
  329. offs = 68
  330. end
  331.  
  332. local childs = {}
  333. for i=0,(ufs.multiplier * 256 - 3) do
  334. ufs.pos = ufs.pos + ufs.tape.seek(ufs.start - ufs.pos + ufs.multiplier * 512 * block + offs + i * 2) + 2
  335. local ch = nf2(ufs.tape.read(2))
  336. if ch ~= 0 then
  337. childs[#childs + 1] = ch
  338. end
  339. end
  340.  
  341. return childs
  342. end
  343.  
  344. function ufs.fs.list(path)
  345.  
  346. end
  347.  
  348. return ufs
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement