// SPDX-License-Identifier: Unlicense OR BSD-3-Clause

package cff

import (
	"encoding/binary"
	"fmt"
)

// Code generated by binarygen from cff2_src.go. DO NOT EDIT

func (item *header2) mustParse(src []byte) {
	_ = src[4] // early bound checking
	item.majorVersion = src[0]
	item.minorVersion = src[1]
	item.headerSize = src[2]
	item.topDictLength = binary.BigEndian.Uint16(src[3:])
}

func (item *indexStart) mustParse(src []byte) {
	_ = src[4] // early bound checking
	item.count = binary.BigEndian.Uint32(src[0:])
	item.offSize = src[4]
}

func parseFdSelect(src []byte, fdsCount int) (fdSelect, int, error) {
	var item fdSelect

	if L := len(src); L < 1 {
		return item, 0, fmt.Errorf("reading fdSelect: "+"EOF: expected length: 1, got %d", L)
	}
	format := uint8(src[0])
	var (
		read int
		err  error
	)
	switch format {
	case 0:
		item, read, err = parseFdSelect0(src[0:], fdsCount)
	case 3:
		item, read, err = parseFdSelect3(src[0:])
	case 4:
		item, read, err = parseFdSelect4(src[0:])
	default:
		err = fmt.Errorf("unsupported fdSelect format %d", format)
	}
	if err != nil {
		return item, 0, fmt.Errorf("reading fdSelect: %s", err)
	}

	return item, read, nil
}

func parseFdSelect0(src []byte, fdsCount int) (fdSelect0, int, error) {
	var item fdSelect0
	n := 0
	if L := len(src); L < 1 {
		return item, 0, fmt.Errorf("reading fdSelect0: "+"EOF: expected length: 1, got %d", L)
	}
	item.format = src[0]
	n += 1

	{

		L := int(1 + fdsCount)
		if len(src) < L {
			return item, 0, fmt.Errorf("reading fdSelect0: "+"EOF: expected length: %d, got %d", L, len(src))
		}
		item.fds = src[1:L]
		n = L
	}
	return item, n, nil
}

func parseFdSelect3(src []byte) (fdSelect3, int, error) {
	var item fdSelect3
	n := 0
	if L := len(src); L < 3 {
		return item, 0, fmt.Errorf("reading fdSelect3: "+"EOF: expected length: 3, got %d", L)
	}
	_ = src[2] // early bound checking
	item.format = src[0]
	item.nRanges = binary.BigEndian.Uint16(src[1:])
	n += 3

	{
		arrayLength := int(item.nRanges)

		if L := len(src); L < 3+arrayLength*3 {
			return item, 0, fmt.Errorf("reading fdSelect3: "+"EOF: expected length: %d, got %d", 3+arrayLength*3, L)
		}

		item.ranges = make([]range3, arrayLength) // allocation guarded by the previous check
		for i := range item.ranges {
			item.ranges[i].mustParse(src[3+i*3:])
		}
		n += arrayLength * 3
	}
	if L := len(src); L < n+2 {
		return item, 0, fmt.Errorf("reading fdSelect3: "+"EOF: expected length: n + 2, got %d", L)
	}
	item.sentinel = binary.BigEndian.Uint16(src[n:])
	n += 2

	return item, n, nil
}

func parseFdSelect4(src []byte) (fdSelect4, int, error) {
	var item fdSelect4
	n := 0
	if L := len(src); L < 5 {
		return item, 0, fmt.Errorf("reading fdSelect4: "+"EOF: expected length: 5, got %d", L)
	}
	_ = src[4] // early bound checking
	item.format = src[0]
	item.nRanges = binary.BigEndian.Uint32(src[1:])
	n += 5

	{
		arrayLength := int(item.nRanges)

		if L := len(src); L < 5+arrayLength*6 {
			return item, 0, fmt.Errorf("reading fdSelect4: "+"EOF: expected length: %d, got %d", 5+arrayLength*6, L)
		}

		item.ranges = make([]range4, arrayLength) // allocation guarded by the previous check
		for i := range item.ranges {
			item.ranges[i].mustParse(src[5+i*6:])
		}
		n += arrayLength * 6
	}
	if L := len(src); L < n+4 {
		return item, 0, fmt.Errorf("reading fdSelect4: "+"EOF: expected length: n + 4, got %d", L)
	}
	item.sentinel = binary.BigEndian.Uint32(src[n:])
	n += 4

	return item, n, nil
}

func (item *range3) mustParse(src []byte) {
	_ = src[2] // early bound checking
	item.first = binary.BigEndian.Uint16(src[0:])
	item.fd = src[2]
}

func (item *range4) mustParse(src []byte) {
	_ = src[5] // early bound checking
	item.first = binary.BigEndian.Uint32(src[0:])
	item.fd = binary.BigEndian.Uint16(src[4:])
}
