Add Arborix section directory byte readers
This commit is contained in:
@@ -20,3 +20,58 @@ readArborixHeader = (bs :
|
|||||||
(pair majorVersion
|
(pair majorVersion
|
||||||
(pair minorVersion sectionCount))
|
(pair minorVersion sectionCount))
|
||||||
afterSectionCount)))))
|
afterSectionCount)))))
|
||||||
|
|
||||||
|
readSectionRecord = (bs :
|
||||||
|
bindResult (readBytes 2 bs)
|
||||||
|
(sectionId afterSectionId :
|
||||||
|
bindResult (readBytes 4 afterSectionId)
|
||||||
|
(offset afterOffset :
|
||||||
|
bindResult (readBytes 4 afterOffset)
|
||||||
|
(length afterLength :
|
||||||
|
ok
|
||||||
|
(pair sectionId
|
||||||
|
(pair offset length))
|
||||||
|
afterLength))))
|
||||||
|
|
||||||
|
readSectionDirectory_ = y (self sectionCount i bs acc :
|
||||||
|
matchBool
|
||||||
|
(ok (reverse acc) bs)
|
||||||
|
(bindResult (readSectionRecord bs)
|
||||||
|
(sectionRecord afterSectionRecord :
|
||||||
|
self sectionCount (succ i) afterSectionRecord (pair sectionRecord acc)))
|
||||||
|
(equal? i sectionCount))
|
||||||
|
|
||||||
|
readSectionDirectory = (sectionCount bs : readSectionDirectory_ sectionCount 0 bs t)
|
||||||
|
|
||||||
|
sectionRecordId = (sectionRecord :
|
||||||
|
matchPair
|
||||||
|
(sectionId _ : sectionId)
|
||||||
|
sectionRecord)
|
||||||
|
|
||||||
|
sectionRecordOffset = (sectionRecord :
|
||||||
|
matchPair
|
||||||
|
(_ payload :
|
||||||
|
matchPair
|
||||||
|
(offset _ : offset)
|
||||||
|
payload)
|
||||||
|
sectionRecord)
|
||||||
|
|
||||||
|
sectionRecordLength = (sectionRecord :
|
||||||
|
matchPair
|
||||||
|
(_ payload :
|
||||||
|
matchPair
|
||||||
|
(_ length : length)
|
||||||
|
payload)
|
||||||
|
sectionRecord)
|
||||||
|
|
||||||
|
lookupSectionRecord = y (self sectionId directory :
|
||||||
|
matchList
|
||||||
|
nothing
|
||||||
|
(sectionRecord rest :
|
||||||
|
matchBool
|
||||||
|
(just sectionRecord)
|
||||||
|
(self sectionId rest)
|
||||||
|
(bytesEq? sectionId (sectionRecordId sectionRecord)))
|
||||||
|
directory)
|
||||||
|
|
||||||
|
byteSlice = (offset length bytes : bytesTake length (bytesDrop offset bytes))
|
||||||
|
|||||||
122
test/Spec.hs
122
test/Spec.hs
@@ -1554,4 +1554,126 @@ binaryReaderTests = testGroup "Binary Reader Tests"
|
|||||||
library <- evaluateFile "./lib/arborix.tri"
|
library <- evaluateFile "./lib/arborix.tri"
|
||||||
let env = evalTricu library (parseTricu input)
|
let env = evalTricu library (parseTricu input)
|
||||||
result env @?= errT eofT (bytesT [65,82])
|
result env @?= errT eofT (bytesT [65,82])
|
||||||
|
|
||||||
|
-- ------------------------------------------------------------------------
|
||||||
|
-- Arborix section directory record parsing
|
||||||
|
-- ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
, testCase "readSectionRecord: parses raw section id offset and length" $ do
|
||||||
|
let input = "readSectionRecord [(0) (2) (0) (0) (0) (16) (0) (0) (0) (32)]"
|
||||||
|
library <- evaluateFile "./lib/arborix.tri"
|
||||||
|
let env = evalTricu library (parseTricu input)
|
||||||
|
result env @?= okT
|
||||||
|
(pairT (bytesT [0,2])
|
||||||
|
(pairT (bytesT [0,0,0,16])
|
||||||
|
(bytesT [0,0,0,32])))
|
||||||
|
(bytesT [])
|
||||||
|
|
||||||
|
, testCase "readSectionRecord: preserves trailing bytes" $ do
|
||||||
|
let input = "readSectionRecord [(0) (2) (0) (0) (0) (16) (0) (0) (0) (32) (9) (8)]"
|
||||||
|
library <- evaluateFile "./lib/arborix.tri"
|
||||||
|
let env = evalTricu library (parseTricu input)
|
||||||
|
result env @?= okT
|
||||||
|
(pairT (bytesT [0,2])
|
||||||
|
(pairT (bytesT [0,0,0,16])
|
||||||
|
(bytesT [0,0,0,32])))
|
||||||
|
(bytesT [9,8])
|
||||||
|
|
||||||
|
, testCase "readSectionRecord: empty input returns EOF" $ do
|
||||||
|
let input = "readSectionRecord []"
|
||||||
|
library <- evaluateFile "./lib/arborix.tri"
|
||||||
|
let env = evalTricu library (parseTricu input)
|
||||||
|
result env @?= errT eofT (bytesT [])
|
||||||
|
|
||||||
|
, testCase "readSectionRecord: short section id returns EOF preserving input" $ do
|
||||||
|
let input = "readSectionRecord [(0)]"
|
||||||
|
library <- evaluateFile "./lib/arborix.tri"
|
||||||
|
let env = evalTricu library (parseTricu input)
|
||||||
|
result env @?= errT eofT (bytesT [0])
|
||||||
|
|
||||||
|
, testCase "readSectionRecord: missing offset returns EOF preserving unread offset bytes" $ do
|
||||||
|
let input = "readSectionRecord [(0) (2)]"
|
||||||
|
library <- evaluateFile "./lib/arborix.tri"
|
||||||
|
let env = evalTricu library (parseTricu input)
|
||||||
|
result env @?= errT eofT (bytesT [])
|
||||||
|
|
||||||
|
, testCase "readSectionRecord: short offset returns EOF preserving unread offset bytes" $ do
|
||||||
|
let input = "readSectionRecord [(0) (2) (0) (0) (0)]"
|
||||||
|
library <- evaluateFile "./lib/arborix.tri"
|
||||||
|
let env = evalTricu library (parseTricu input)
|
||||||
|
result env @?= errT eofT (bytesT [0,0,0])
|
||||||
|
|
||||||
|
, testCase "readSectionRecord: missing length returns EOF preserving unread length bytes" $ do
|
||||||
|
let input = "readSectionRecord [(0) (2) (0) (0) (0) (16)]"
|
||||||
|
library <- evaluateFile "./lib/arborix.tri"
|
||||||
|
let env = evalTricu library (parseTricu input)
|
||||||
|
result env @?= errT eofT (bytesT [])
|
||||||
|
|
||||||
|
, testCase "readSectionRecord: short length returns EOF preserving unread length bytes" $ do
|
||||||
|
let input = "readSectionRecord [(0) (2) (0) (0) (0) (16) (0) (0) (0)]"
|
||||||
|
library <- evaluateFile "./lib/arborix.tri"
|
||||||
|
let env = evalTricu library (parseTricu input)
|
||||||
|
result env @?= errT eofT (bytesT [0,0,0])
|
||||||
|
|
||||||
|
-- ------------------------------------------------------------------------
|
||||||
|
-- Arborix section directory parsing
|
||||||
|
-- ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
, testCase "readSectionDirectory: zero records preserves input" $ do
|
||||||
|
let input = "readSectionDirectory 0 [(9) (8)]"
|
||||||
|
library <- evaluateFile "./lib/arborix.tri"
|
||||||
|
let env = evalTricu library (parseTricu input)
|
||||||
|
result env @?= okT (ofList []) (bytesT [9,8])
|
||||||
|
|
||||||
|
, testCase "readSectionDirectory: reads requested records and preserves trailing bytes" $ do
|
||||||
|
let input = "readSectionDirectory 2 [(0) (1) (0) (0) (0) (10) (0) (0) (0) (20) (0) (2) (0) (0) (0) (30) (0) (0) (0) (40) (9)]"
|
||||||
|
library <- evaluateFile "./lib/arborix.tri"
|
||||||
|
let env = evalTricu library (parseTricu input)
|
||||||
|
result env @?= okT
|
||||||
|
(ofList
|
||||||
|
[ pairT (bytesT [0,1])
|
||||||
|
(pairT (bytesT [0,0,0,10])
|
||||||
|
(bytesT [0,0,0,20]))
|
||||||
|
, pairT (bytesT [0,2])
|
||||||
|
(pairT (bytesT [0,0,0,30])
|
||||||
|
(bytesT [0,0,0,40]))
|
||||||
|
])
|
||||||
|
(bytesT [9])
|
||||||
|
|
||||||
|
, testCase "readSectionDirectory: truncated record returns EOF" $ do
|
||||||
|
let input = "readSectionDirectory 2 [(0) (1) (0) (0) (0) (10) (0) (0) (0) (20) (0) (2) (0) (0)]"
|
||||||
|
library <- evaluateFile "./lib/arborix.tri"
|
||||||
|
let env = evalTricu library (parseTricu input)
|
||||||
|
result env @?= errT eofT (bytesT [0,0])
|
||||||
|
|
||||||
|
-- ------------------------------------------------------------------------
|
||||||
|
-- Arborix section lookup and raw byte slicing
|
||||||
|
-- ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
, testCase "lookupSectionRecord: finds record by raw section id" $ do
|
||||||
|
let input = "lookupSectionRecord [(0) (2)] [(pair [(0) (1)] (pair [(0) (0) (0) (10)] [(0) (0) (0) (20)])) (pair [(0) (2)] (pair [(0) (0) (0) (30)] [(0) (0) (0) (40)]))]"
|
||||||
|
library <- evaluateFile "./lib/arborix.tri"
|
||||||
|
let env = evalTricu library (parseTricu input)
|
||||||
|
result env @?= justT
|
||||||
|
(pairT (bytesT [0,2])
|
||||||
|
(pairT (bytesT [0,0,0,30])
|
||||||
|
(bytesT [0,0,0,40])))
|
||||||
|
|
||||||
|
, testCase "lookupSectionRecord: missing section id returns nothing" $ do
|
||||||
|
let input = "lookupSectionRecord [(0) (3)] [(pair [(0) (1)] (pair [(0) (0) (0) (10)] [(0) (0) (0) (20)])) (pair [(0) (2)] (pair [(0) (0) (0) (30)] [(0) (0) (0) (40)]))]"
|
||||||
|
library <- evaluateFile "./lib/arborix.tri"
|
||||||
|
let env = evalTricu library (parseTricu input)
|
||||||
|
result env @?= nothingT
|
||||||
|
|
||||||
|
, testCase "byteSlice: extracts requested byte range" $ do
|
||||||
|
let input = "byteSlice 2 3 [(10) (11) (12) (13) (14) (15)]"
|
||||||
|
library <- evaluateFile "./lib/arborix.tri"
|
||||||
|
let env = evalTricu library (parseTricu input)
|
||||||
|
result env @?= bytesT [12,13,14]
|
||||||
|
|
||||||
|
, testCase "byteSlice: overlong length returns remaining bytes" $ do
|
||||||
|
let input = "byteSlice 4 9 [(10) (11) (12) (13) (14) (15)]"
|
||||||
|
library <- evaluateFile "./lib/arborix.tri"
|
||||||
|
let env = evalTricu library (parseTricu input)
|
||||||
|
result env @?= bytesT [14,15]
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user