!import "base.tri" !Local !import "list.tri" !Local !import "bytes.tri" !Local !import "binary.tri" !Local arborixMagic = [(65) (82) (66) (79) (82) (73) (88) (0)] readArborixMagic = (bs : expectBytes arborixMagic bs) readArborixHeader = (bs : bindResult (readArborixMagic bs) (_ afterMagic : bindResult (readBytes 2 afterMagic) (majorVersion afterMajor : bindResult (readBytes 2 afterMajor) (minorVersion afterMinor : bindResult (readBytes 4 afterMinor) (sectionCount afterSectionCount : ok (pair majorVersion (pair minorVersion sectionCount)) 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))