(bytes: Uint8Array)
| 89 | } |
| 90 | |
| 91 | export function parseCommandHeaders(bytes: Uint8Array): readonly DrawlistCommandHeader[] { |
| 92 | const { cmdOffset, cmdEnd } = readCommandBounds(bytes); |
| 93 | const out: DrawlistCommandHeader[] = []; |
| 94 | |
| 95 | let off = cmdOffset; |
| 96 | while (off < cmdEnd) { |
| 97 | const opcode = u16(bytes, off); |
| 98 | const size = u32(bytes, off + 4); |
| 99 | if (size < MIN_CMD_SIZE) { |
| 100 | throw new Error(`command size below minimum at offset ${String(off)} (size=${String(size)})`); |
| 101 | } |
| 102 | if ((size & 3) !== 0) { |
| 103 | throw new Error( |
| 104 | `command size not 4-byte aligned at offset ${String(off)} (size=${String(size)})`, |
| 105 | ); |
| 106 | } |
| 107 | const next = off + size; |
| 108 | if (next > cmdEnd) { |
| 109 | throw new Error( |
| 110 | `command overruns cmd section at offset ${String(off)} (size=${String(size)}, cmdEnd=${String(cmdEnd)})`, |
| 111 | ); |
| 112 | } |
| 113 | out.push({ |
| 114 | opcode, |
| 115 | size, |
| 116 | offset: off, |
| 117 | payloadOffset: off + MIN_CMD_SIZE, |
| 118 | payloadSize: size - MIN_CMD_SIZE, |
| 119 | }); |
| 120 | off = next; |
| 121 | } |
| 122 | |
| 123 | if (off !== cmdEnd) { |
| 124 | throw new Error( |
| 125 | `command parse did not end exactly at cmdEnd (off=${String(off)}, cmdEnd=${String(cmdEnd)})`, |
| 126 | ); |
| 127 | } |
| 128 | |
| 129 | return Object.freeze(out); |
| 130 | } |
| 131 | |
| 132 | function parseResourceState(bytes: Uint8Array): ResourceState { |
| 133 | const headers = parseCommandHeaders(bytes); |
no test coverage detected