57393cc4f6684bab60a98387056bf71dc673fcbc10482a3dd16bec270675e8ab.tri (11047B)
1 !import prelude * 2 !import binary * 3 !export * 4 5 6 arboricxMagic = [(65) (82) (66) (79) (82) (73) (67) (88)] 7 arboricxMajorVersion = [(0) (1)] 8 arboricxMinorVersion = [(0) (0)] 9 arboricxManifestSectionId = [(0) (0) (0) (1)] 10 arboricxNodesSectionId = [(0) (0) (0) (2)] 11 12 -- Manifest magic and version constants 13 arboricxManifestMagic = [(65) (82) (66) (77) (78) (70) (83) (84)] 14 arboricxManifestMajorVersion = [(0) (1)] 15 arboricxManifestMinorVersion = [(0) (0)] 16 17 errMissingSection = 4 18 errUnsupportedVersion = 5 19 errDuplicateSection = 6 20 errDuplicateNode = 7 21 errInvalidNodePayload = 8 22 errMissingNode = 9 23 errInvalidManifestMagic = 10 24 errUnsupportedManifestVersion = 11 25 errTrailingManifestBytes = 12 26 errManifestValidationFailed = 13 27 28 nodePayloadLeafTag = 0 29 nodePayloadStemTag = 1 30 nodePayloadForkTag = 2 31 32 readArboricxMagic = (bs : expectBytes arboricxMagic bs) 33 34 readArboricxHeader = (do bindParser 35 readArboricxMagic 36 majorVersion <- readBytes 2 37 minorVersion <- readBytes 2 38 sectionCount <- readBytes 4 39 flags <- readBytes 8 40 dirOffset <- readBytes 8 41 pureParser (pair majorVersion (pair minorVersion (pair sectionCount (pair flags dirOffset))))) 42 43 readSectionRecord = (do bindParser 44 sectionId <- readBytes 4 45 sectionVersion <- readBytes 2 46 sectionFlags <- readBytes 2 47 compression <- readBytes 2 48 reserved1 <- readBytes 2 49 offset <- readBytes 8 50 length <- readBytes 8 51 reserved2 <- readBytes 4 52 pureParser (pair sectionId (pair sectionVersion (pair sectionFlags (pair compression (pair reserved1 (pair offset (pair length reserved2)))))))) 53 54 readSectionDirectory_ bs sectionCount i acc = (matchBool 55 (ok (reverse acc) bs) 56 (bindResult (readSectionRecord bs) 57 (sectionRecord afterSectionRecord : 58 readSectionDirectory_ afterSectionRecord sectionCount (succ i) (pair sectionRecord acc))) 59 (equal? i sectionCount)) 60 61 readSectionDirectory = (sectionCount bs : readSectionDirectory_ bs sectionCount 0 t) 62 63 sectionRecordId = (sectionRecord : 64 matchPair 65 (sectionId _ : sectionId) 66 sectionRecord) 67 68 sectionRecordVersion = (sectionRecord : 69 matchPair 70 (_ payload : 71 matchPair 72 (sectionVersion _ : sectionVersion) 73 payload) 74 sectionRecord) 75 76 sectionRecordFlags = (sectionRecord : 77 matchPair 78 (_ payload : 79 matchPair 80 (_ payload2 : 81 matchPair 82 (sectionFlags _ : sectionFlags) 83 payload2) 84 payload) 85 sectionRecord) 86 87 sectionRecordCompression = (sectionRecord : 88 matchPair 89 (_ payload : 90 matchPair 91 (_ payload2 : 92 matchPair 93 (_ payload3 : 94 matchPair 95 (compression _ : compression) 96 payload3) 97 payload2) 98 payload) 99 sectionRecord) 100 101 sectionRecordReserved1 = (sectionRecord : 102 matchPair 103 (_ payload : 104 matchPair 105 (_ payload2 : 106 matchPair 107 (_ payload3 : 108 matchPair 109 (_ payload4 : 110 matchPair 111 (reserved1 _ : reserved1) 112 payload4) 113 payload3) 114 payload2) 115 payload) 116 sectionRecord) 117 118 sectionRecordOffset = (sectionRecord : 119 matchPair 120 (_ payload : 121 matchPair 122 (_ payload2 : 123 matchPair 124 (_ payload3 : 125 matchPair 126 (_ payload4 : 127 matchPair 128 (_ payload5 : 129 matchPair 130 (offset _ : offset) 131 payload5) 132 payload4) 133 payload3) 134 payload2) 135 payload) 136 sectionRecord) 137 138 sectionRecordLength = (sectionRecord : 139 matchPair 140 (_ payload : 141 matchPair 142 (_ payload2 : 143 matchPair 144 (_ payload3 : 145 matchPair 146 (_ payload4 : 147 matchPair 148 (_ payload5 : 149 matchPair 150 (_ payload6 : 151 matchPair 152 (length _ : length) 153 payload6) 154 payload5) 155 payload4) 156 payload3) 157 payload2) 158 payload) 159 sectionRecord) 160 161 sectionRecordReserved2 = (sectionRecord : 162 matchPair 163 (_ payload : 164 matchPair 165 (_ payload2 : 166 matchPair 167 (_ payload3 : 168 matchPair 169 (_ payload4 : 170 matchPair 171 (_ payload5 : 172 matchPair 173 (_ payload6 : 174 matchPair 175 (_ reserved2 : reserved2) 176 payload6) 177 payload5) 178 payload4) 179 payload3) 180 payload2) 181 payload) 182 sectionRecord) 183 184 lookupSectionRecord_ directory sectionId = (matchList 185 nothing 186 (sectionRecord rest : 187 matchBool 188 (just sectionRecord) 189 (lookupSectionRecord_ rest sectionId) 190 (bytesEq? sectionId (sectionRecordId sectionRecord))) 191 directory) 192 193 lookupSectionRecord = (sectionId directory : lookupSectionRecord_ directory sectionId) 194 195 sectionDirectoryHasId?_ directory sectionId = (matchList 196 false 197 (sectionRecord rest : 198 or? 199 (bytesEq? sectionId (sectionRecordId sectionRecord)) 200 (sectionDirectoryHasId?_ rest sectionId)) 201 directory) 202 203 sectionDirectoryHasId? = (sectionId directory : sectionDirectoryHasId?_ directory sectionId) 204 205 sectionDirectoryHasDuplicateIds? directory = (matchList 206 false 207 (sectionRecord rest : 208 or? 209 (sectionDirectoryHasId?_ rest (sectionRecordId sectionRecord)) 210 (sectionDirectoryHasDuplicateIds? rest)) 211 directory) 212 213 validateSectionDirectory = (directory rest : 214 matchBool 215 (err errDuplicateSection rest) 216 (ok directory rest) 217 (sectionDirectoryHasDuplicateIds? directory)) 218 219 byteSlice = (offset length bytes : bytesTake length (bytesDrop offset bytes)) 220 221 natMake = (bit rest : 222 matchBool 223 0 224 (pair bit rest) 225 (and? (equal? bit 0) (equal? rest 0))) 226 227 natAdd = y (self a b : 228 triage 229 b 230 (_ : b) 231 (aBit aRest : 232 triage 233 a 234 (_ : a) 235 (bBit bRest : 236 matchBool 237 (natMake 0 (succ (self aRest bRest))) 238 (natMake (matchBool (matchBool 0 1 bBit) (matchBool 1 0 bBit) aBit) 239 (self aRest bRest)) 240 (and? (equal? aBit 1) (equal? bBit 1))) 241 b) 242 a) 243 244 natDouble = (n : matchBool 0 (pair 0 n) (equal? n 0)) 245 246 natTimes256 = (n : 247 natDouble 248 (natDouble 249 (natDouble 250 (natDouble 251 (natDouble 252 (natDouble 253 (natDouble 254 (natDouble n)))))))) 255 256 byteNatShiftAppend_ byte acc i = (matchBool 257 acc 258 (triage 259 (natMake 0 (byteNatShiftAppend_ 0 acc (succ i))) 260 (_ : acc) 261 (bit rest : natMake bit (byteNatShiftAppend_ rest acc (succ i))) 262 byte) 263 (equal? i 8)) 264 265 byteNatShiftAppend = (byte acc : byteNatShiftAppend_ byte acc 0) 266 267 beBytesToNat = (bytes : 268 foldl 269 (acc byte : byteNatShiftAppend byte acc) 270 0 271 bytes) 272 273 u32BEBytesToNat = beBytesToNat 274 u64BEBytesToNat = beBytesToNat 275 276 arboricxHeaderMajorVersion = (header : 277 matchPair 278 (majorVersion _ : majorVersion) 279 header) 280 281 arboricxHeaderMinorVersion = (header : 282 matchPair 283 (_ payload : 284 matchPair 285 (minorVersion _ : minorVersion) 286 payload) 287 header) 288 289 arboricxHeaderSectionCount = (header : 290 matchPair 291 (_ payload : 292 matchPair 293 (_ payload2 : 294 matchPair 295 (sectionCount _ : sectionCount) 296 payload2) 297 payload) 298 header) 299 300 arboricxHeaderFlags = (header : 301 matchPair 302 (_ payload : 303 matchPair 304 (_ payload2 : 305 matchPair 306 (_ payload3 : 307 matchPair 308 (flags _ : flags) 309 payload3) 310 payload2) 311 payload) 312 header) 313 314 arboricxHeaderDirOffset = (header : 315 matchPair 316 (_ payload : 317 matchPair 318 (_ payload2 : 319 matchPair 320 (_ payload3 : 321 matchPair 322 (_ dirOffset : dirOffset) 323 payload3) 324 payload2) 325 payload) 326 header) 327 328 validateArboricxHeader = (header rest : 329 matchBool 330 (ok header rest) 331 (err errUnsupportedVersion rest) 332 (and? 333 (bytesEq? arboricxMajorVersion (arboricxHeaderMajorVersion header)) 334 (bytesEq? arboricxMinorVersion (arboricxHeaderMinorVersion header)))) 335 336 readArboricxContainer = (bs : 337 bindResult (readArboricxHeader bs) 338 (header afterHeader : 339 bindResult (validateArboricxHeader header afterHeader) 340 (validHeader afterValidHeader : 341 bindResult (readSectionDirectory 342 (u32BEBytesToNat (arboricxHeaderSectionCount validHeader)) 343 (bytesDrop (u64BEBytesToNat (arboricxHeaderDirOffset validHeader)) bs)) 344 (directory afterDirectory : 345 bindResult (validateSectionDirectory directory afterDirectory) 346 (validDirectory afterValidDirectory : 347 ok (pair validHeader validDirectory) afterValidDirectory))))) 348 349 sectionRecordOffsetNat = (sectionRecord : 350 u64BEBytesToNat (sectionRecordOffset sectionRecord)) 351 352 sectionRecordLengthNat = (sectionRecord : 353 u64BEBytesToNat (sectionRecordLength sectionRecord)) 354 355 extractSectionBytes = (sectionRecord containerBytes : 356 byteSlice 357 (sectionRecordOffsetNat sectionRecord) 358 (sectionRecordLengthNat sectionRecord) 359 containerBytes) 360 361 extractSectionBytesResult = (sectionRecord containerBytes rest : 362 (sectionBytes : 363 matchBool 364 (ok sectionBytes rest) 365 (err errUnexpectedEof rest) 366 (equal? (bytesLength sectionBytes) (sectionRecordLengthNat sectionRecord))) 367 (extractSectionBytes sectionRecord containerBytes)) 368 369 lookupSectionBytes = (sectionId directory containerBytes : 370 triage 371 nothing 372 (sectionRecord : just (extractSectionBytes sectionRecord containerBytes)) 373 (_ _ : nothing) 374 (lookupSectionRecord sectionId directory)) 375 376 sectionBytesOrErr = (sectionId directory containerBytes rest : 377 triage 378 (err errMissingSection rest) 379 (sectionRecord : extractSectionBytesResult sectionRecord containerBytes rest) 380 (_ _ : err errMissingSection rest) 381 (lookupSectionRecord sectionId directory)) 382 383 readArboricxSectionBytes = (sectionId bs : 384 bindResult (readArboricxContainer bs) 385 (container afterContainer : 386 matchPair 387 (_ directory : sectionBytesOrErr sectionId directory bs afterContainer) 388 container)) 389 390 readArboricxRequiredSections = (bs : 391 bindResult (readArboricxContainer bs) 392 (container afterContainer : 393 matchPair 394 (_ directory : 395 bindResult (sectionBytesOrErr arboricxManifestSectionId directory bs afterContainer) 396 (manifestBytes _ : 397 bindResult (sectionBytesOrErr arboricxNodesSectionId directory bs afterContainer) 398 (nodesBytes _ : 399 ok (pair manifestBytes nodesBytes) afterContainer))) 400 container))