1
0
mirror of https://github.com/garraflavatra/go-fmp.git synced 2025-07-07 07:34:05 +00:00

Chunk fixes

This commit is contained in:
2025-06-13 17:23:58 +02:00
parent ba62b66f63
commit 17a3664e42

View File

@ -6,178 +6,177 @@ func (ctx *FmpFile) readChunk(payload []byte) (*FmpChunk, error) {
// https://github.com/Rasmus20B/fmplib/blob/66245e5269275724bacfe1437fb1f73bc587a2f3/src/fmp_format/chunk.rs#L57-L60 // https://github.com/Rasmus20B/fmplib/blob/66245e5269275724bacfe1437fb1f73bc587a2f3/src/fmp_format/chunk.rs#L57-L60
chunk := &FmpChunk{} chunk := &FmpChunk{}
chunkCode := payload[0]
if (payload[0] & 0xC0) == 0xC0 { if (chunkCode & 0xC0) == 0xC0 {
payload[0] &= 0x3F chunkCode &= 0x3F
chunk.Delayed = true chunk.Delayed = true
} }
switch payload[0] { switch chunkCode {
case 0x00: case 0x00:
chunk.Type = FMP_CHUNK_SIMPLE_DATA
chunk.Value = payload[1 : 1+1]
chunk.Length = 2 chunk.Length = 2
chunk.Type = FMP_CHUNK_SIMPLE_DATA
chunk.Value = payload[1:chunk.Length]
case 0x01: case 0x01:
chunk.Length = 3
chunk.Type = FMP_CHUNK_SIMPLE_KEY_VALUE chunk.Type = FMP_CHUNK_SIMPLE_KEY_VALUE
chunk.Key = uint64(payload[1]) chunk.Key = uint64(payload[1])
chunk.Value = payload[2 : 2+1] chunk.Value = payload[2:chunk.Length]
chunk.Length = 3
case 0x02, 0x03, 0x04, 0x05: case 0x02, 0x03, 0x04, 0x05:
valueLength := uint64(2 * (payload[0] - 1)) valueLength := uint64(2 * (chunkCode - 1))
chunk.Length = 2 + valueLength
chunk.Type = FMP_CHUNK_SIMPLE_KEY_VALUE chunk.Type = FMP_CHUNK_SIMPLE_KEY_VALUE
chunk.Key = uint64(payload[1]) chunk.Key = uint64(payload[1])
chunk.Value = payload[2 : 2+valueLength] chunk.Value = payload[2:chunk.Length]
chunk.Length = 2 + uint64(valueLength)
case 0x06: case 0x06:
valueLength := uint64(payload[2]) valueLength := uint64(payload[2])
chunk.Length = 3 + valueLength
chunk.Type = FMP_CHUNK_SIMPLE_KEY_VALUE chunk.Type = FMP_CHUNK_SIMPLE_KEY_VALUE
chunk.Key = uint64(payload[1]) chunk.Key = uint64(payload[1])
chunk.Value = payload[3 : 3+valueLength] chunk.Value = payload[3:chunk.Length]
chunk.Length = 3 + uint64(valueLength)
case 0x07: case 0x07:
valueLength := parseVarUint64(payload[2 : 2+2]) valueLength := parseVarUint64(payload[2 : 2+2])
payloadLimit := min(4+valueLength, uint64(len(payload))) chunk.Length = min(4+valueLength, uint64(len(payload)))
chunk.Type = FMP_CHUNK_SEGMENTED_DATA chunk.Type = FMP_CHUNK_SEGMENTED_DATA
chunk.Index = uint64(payload[1]) chunk.Index = uint64(payload[1])
chunk.Value = payload[4:payloadLimit] chunk.Value = payload[4:chunk.Length]
chunk.Length = 4 + uint64(valueLength)
case 0x08: case 0x08:
chunk.Type = FMP_CHUNK_SIMPLE_DATA
chunk.Value = payload[1 : 1+2]
chunk.Length = 3 chunk.Length = 3
chunk.Type = FMP_CHUNK_SIMPLE_DATA
chunk.Value = payload[1:chunk.Length]
case 0x09: case 0x09:
chunk.Length = 4
chunk.Type = FMP_CHUNK_SIMPLE_KEY_VALUE chunk.Type = FMP_CHUNK_SIMPLE_KEY_VALUE
chunk.Key = parseVarUint64(payload[1 : 1+2]) chunk.Key = parseVarUint64(payload[1 : 1+2])
chunk.Value = payload[3 : 3+1] chunk.Value = payload[3:chunk.Length]
chunk.Length = 4
case 0x0A, 0x0B, 0x0C, 0x0D: case 0x0A, 0x0B, 0x0C, 0x0D:
valueLength := uint64(2 * (payload[0] - 0x09)) valueLength := uint64(2 * (chunkCode - 0x09))
chunk.Length = 3 + valueLength
chunk.Type = FMP_CHUNK_SIMPLE_KEY_VALUE chunk.Type = FMP_CHUNK_SIMPLE_KEY_VALUE
chunk.Key = parseVarUint64(payload[1 : 1+2]) chunk.Key = parseVarUint64(payload[1 : 1+2])
chunk.Value = payload[3 : 3+valueLength] chunk.Value = payload[3:chunk.Length]
chunk.Length = 3 + uint64(valueLength)
case 0x0E: case 0x0E:
if payload[1] == 0xFE { if payload[1] == 0xFE {
chunk.Type = FMP_CHUNK_PATH_PUSH
chunk.Value = payload[1 : 1+8]
chunk.Length = 10 chunk.Length = 10
chunk.Type = FMP_CHUNK_PATH_PUSH
chunk.Value = payload[2:chunk.Length]
break break
} }
if payload[1] == 0xFF { if payload[1] == 0xFF {
chunk.Type = FMP_CHUNK_SIMPLE_DATA
chunk.Value = payload[2 : 2+5]
chunk.Length = 7 chunk.Length = 7
chunk.Type = FMP_CHUNK_SIMPLE_DATA
chunk.Value = payload[2:chunk.Length]
break break
} }
valueLength := uint64(payload[2]) valueLength := uint64(payload[2])
chunk.Length = 4 + valueLength
chunk.Type = FMP_CHUNK_SIMPLE_KEY_VALUE chunk.Type = FMP_CHUNK_SIMPLE_KEY_VALUE
chunk.Key = parseVarUint64(payload[1 : 1+2]) chunk.Key = parseVarUint64(payload[1 : 1+2])
chunk.Value = payload[4 : 4+valueLength] chunk.Value = payload[4:chunk.Length]
chunk.Length = 4 + uint64(valueLength)
case 0x0F: case 0x0F:
valueLength := parseVarUint64(payload[3 : 3+2]) valueLength := parseVarUint64(payload[3 : 3+2])
payloadLimit := min(5+valueLength, uint64(len(payload))) chunk.Length = min(5+valueLength, uint64(len(payload)))
chunk.Type = FMP_CHUNK_SEGMENTED_DATA chunk.Type = FMP_CHUNK_SEGMENTED_DATA
chunk.Index = parseVarUint64(payload[1 : 1+2]) chunk.Index = parseVarUint64(payload[1 : 1+2])
chunk.Value = payload[5:payloadLimit] chunk.Value = payload[5:chunk.Length]
chunk.Length = 5 + valueLength
case 0x10, 0x11: case 0x10, 0x11:
valueLength := 3 + (uint64(payload[0]) - 0x10) valueLength := 3 + (uint64(chunkCode) - 0x10)
chunk.Length = 1 + valueLength
chunk.Type = FMP_CHUNK_SIMPLE_DATA chunk.Type = FMP_CHUNK_SIMPLE_DATA
chunk.Value = payload[1 : 1+valueLength] chunk.Value = payload[1:chunk.Length]
chunk.Length = 1 + uint64(valueLength)
case 0x12, 0x13, 0x14, 0x15: case 0x12, 0x13, 0x14, 0x15:
valueLength := 1 + 2*(uint64(payload[0])-0x10) valueLength := 1 + 2*(uint64(chunkCode)-0x10)
chunk.Length = 1 + valueLength
chunk.Type = FMP_CHUNK_SIMPLE_DATA chunk.Type = FMP_CHUNK_SIMPLE_DATA
chunk.Value = payload[1 : 1+valueLength] chunk.Value = payload[1:chunk.Length]
chunk.Length = 1 + uint64(valueLength)
case 0x16: case 0x16:
valueLength := uint64(payload[4]) valueLength := uint64(payload[4])
chunk.Type = FMP_CHUNK_LONG_KEY_VALUE chunk.Type = FMP_CHUNK_LONG_KEY_VALUE
chunk.Length = 5 + valueLength
chunk.Key = parseVarUint64(payload[1 : 1+3]) chunk.Key = parseVarUint64(payload[1 : 1+3])
chunk.Value = payload[5 : 5+valueLength] chunk.Value = payload[5:chunk.Length]
chunk.Length = 5 + uint64(valueLength)
case 0x17: case 0x17:
valueLength := parseVarUint64(payload[4 : 4+2]) valueLength := parseVarUint64(payload[4 : 4+2])
chunk.Length = 6 + valueLength
chunk.Type = FMP_CHUNK_LONG_KEY_VALUE chunk.Type = FMP_CHUNK_LONG_KEY_VALUE
chunk.Key = parseVarUint64(payload[1 : 1+3]) chunk.Key = parseVarUint64(payload[1 : 1+3])
chunk.Value = payload[6 : 6+valueLength] chunk.Value = payload[6:chunk.Length]
chunk.Length = 6 + uint64(valueLength)
case 0x19: case 0x19:
chunk.Type = FMP_CHUNK_SIMPLE_DATA chunk.Type = FMP_CHUNK_SIMPLE_DATA
chunk.Value = payload[1 : 1+1]
chunk.Length = 2 chunk.Length = 2
chunk.Value = payload[1:chunk.Length]
case 0x1A, 0x1B, 0x1C, 0x1D: case 0x1A, 0x1B, 0x1C, 0x1D:
valueLength := 2 * uint64(payload[0]-0x19) valueLength := 2 * uint64(chunkCode-0x19)
chunk.Type = FMP_CHUNK_SIMPLE_DATA
chunk.Value = payload[1 : 1+valueLength]
chunk.Length = 1 + valueLength chunk.Length = 1 + valueLength
chunk.Type = FMP_CHUNK_SIMPLE_DATA
chunk.Value = payload[1:chunk.Length]
case 0x1E: case 0x1E:
keyLength := uint64(payload[1]) keyLength := uint64(payload[1])
valueLength := uint64(payload[2+keyLength]) valueLength := uint64(payload[2+keyLength])
chunk.Length = 2 + keyLength + 1 + valueLength
chunk.Type = FMP_CHUNK_LONG_KEY_VALUE chunk.Type = FMP_CHUNK_LONG_KEY_VALUE
chunk.Key = parseVarUint64(payload[2 : 2+keyLength]) chunk.Key = parseVarUint64(payload[2 : 2+keyLength])
chunk.Value = payload[2+keyLength+1 : 2+keyLength+1+valueLength] chunk.Value = payload[2+keyLength+1 : chunk.Length]
chunk.Length = 2 + uint64(keyLength) + 1 + uint64(valueLength)
case 0x1F: case 0x1F:
keyLength := uint64(uint64(payload[1])) keyLength := uint64(uint64(payload[1]))
valueLength := parseVarUint64(payload[2+keyLength : 2+keyLength+2+1]) valueLength := parseVarUint64(payload[2+keyLength : 2+keyLength+2+1])
chunk.Length = 2 + keyLength + 2 + valueLength
chunk.Type = FMP_CHUNK_LONG_KEY_VALUE chunk.Type = FMP_CHUNK_LONG_KEY_VALUE
chunk.Key = parseVarUint64(payload[2 : 2+keyLength]) chunk.Key = parseVarUint64(payload[2 : 2+keyLength])
chunk.Value = payload[2+keyLength+2 : 2+keyLength+2+valueLength] chunk.Value = payload[2+keyLength+2 : chunk.Length]
chunk.Length = 2 + uint64(keyLength) + 2 + uint64(valueLength)
case 0x20: case 0x20:
if payload[1] == 0xFE { if payload[1] == 0xFE {
chunk.Type = FMP_CHUNK_PATH_PUSH
chunk.Value = payload[1 : 1+8]
chunk.Length = 10 chunk.Length = 10
chunk.Type = FMP_CHUNK_PATH_PUSH
chunk.Value = payload[1:chunk.Length]
break break
} }
chunk.Type = FMP_CHUNK_PATH_PUSH
chunk.Value = payload[1 : 1+1]
chunk.Length = 2 chunk.Length = 2
chunk.Type = FMP_CHUNK_PATH_PUSH
chunk.Value = payload[1:chunk.Length]
case 0x23: case 0x23:
chunk.Type = FMP_CHUNK_SIMPLE_DATA
chunk.Value = payload[1 : 1+1]
chunk.Length = 2 chunk.Length = 2
chunk.Type = FMP_CHUNK_SIMPLE_DATA
chunk.Value = payload[1:chunk.Length]
case 0x28: case 0x28:
chunk.Type = FMP_CHUNK_PATH_PUSH
chunk.Value = payload[1 : 1+2]
chunk.Length = 3 chunk.Length = 3
chunk.Type = FMP_CHUNK_PATH_PUSH
chunk.Value = payload[1:chunk.Length]
case 0x30: case 0x30:
chunk.Type = FMP_CHUNK_PATH_PUSH
chunk.Value = payload[1 : 1+3]
chunk.Length = 4 chunk.Length = 4
chunk.Type = FMP_CHUNK_PATH_PUSH
chunk.Value = payload[1:chunk.Length]
case 0x38: case 0x38:
valueLength := uint64(payload[1]) valueLength := uint64(payload[1])
chunk.Length = 2 + valueLength
chunk.Type = FMP_CHUNK_PATH_PUSH chunk.Type = FMP_CHUNK_PATH_PUSH
chunk.Value = payload[2 : 2+valueLength] chunk.Value = payload[2:chunk.Length]
chunk.Length = 2 + uint64(valueLength)
case 0x3D, 0x40: case 0x3D, 0x40:
chunk.Type = FMP_CHUNK_PATH_POP chunk.Type = FMP_CHUNK_PATH_POP