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

package tables

import (
	"encoding/binary"
	"fmt"
)

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

func (item *CmapSubtable0) mustParse(src []byte) {
	_ = src[261] // early bound checking
	item.format = binary.BigEndian.Uint16(src[0:])
	item.length = binary.BigEndian.Uint16(src[2:])
	item.language = binary.BigEndian.Uint16(src[4:])
	item.GlyphIdArray[0] = src[6]
	item.GlyphIdArray[1] = src[7]
	item.GlyphIdArray[2] = src[8]
	item.GlyphIdArray[3] = src[9]
	item.GlyphIdArray[4] = src[10]
	item.GlyphIdArray[5] = src[11]
	item.GlyphIdArray[6] = src[12]
	item.GlyphIdArray[7] = src[13]
	item.GlyphIdArray[8] = src[14]
	item.GlyphIdArray[9] = src[15]
	item.GlyphIdArray[10] = src[16]
	item.GlyphIdArray[11] = src[17]
	item.GlyphIdArray[12] = src[18]
	item.GlyphIdArray[13] = src[19]
	item.GlyphIdArray[14] = src[20]
	item.GlyphIdArray[15] = src[21]
	item.GlyphIdArray[16] = src[22]
	item.GlyphIdArray[17] = src[23]
	item.GlyphIdArray[18] = src[24]
	item.GlyphIdArray[19] = src[25]
	item.GlyphIdArray[20] = src[26]
	item.GlyphIdArray[21] = src[27]
	item.GlyphIdArray[22] = src[28]
	item.GlyphIdArray[23] = src[29]
	item.GlyphIdArray[24] = src[30]
	item.GlyphIdArray[25] = src[31]
	item.GlyphIdArray[26] = src[32]
	item.GlyphIdArray[27] = src[33]
	item.GlyphIdArray[28] = src[34]
	item.GlyphIdArray[29] = src[35]
	item.GlyphIdArray[30] = src[36]
	item.GlyphIdArray[31] = src[37]
	item.GlyphIdArray[32] = src[38]
	item.GlyphIdArray[33] = src[39]
	item.GlyphIdArray[34] = src[40]
	item.GlyphIdArray[35] = src[41]
	item.GlyphIdArray[36] = src[42]
	item.GlyphIdArray[37] = src[43]
	item.GlyphIdArray[38] = src[44]
	item.GlyphIdArray[39] = src[45]
	item.GlyphIdArray[40] = src[46]
	item.GlyphIdArray[41] = src[47]
	item.GlyphIdArray[42] = src[48]
	item.GlyphIdArray[43] = src[49]
	item.GlyphIdArray[44] = src[50]
	item.GlyphIdArray[45] = src[51]
	item.GlyphIdArray[46] = src[52]
	item.GlyphIdArray[47] = src[53]
	item.GlyphIdArray[48] = src[54]
	item.GlyphIdArray[49] = src[55]
	item.GlyphIdArray[50] = src[56]
	item.GlyphIdArray[51] = src[57]
	item.GlyphIdArray[52] = src[58]
	item.GlyphIdArray[53] = src[59]
	item.GlyphIdArray[54] = src[60]
	item.GlyphIdArray[55] = src[61]
	item.GlyphIdArray[56] = src[62]
	item.GlyphIdArray[57] = src[63]
	item.GlyphIdArray[58] = src[64]
	item.GlyphIdArray[59] = src[65]
	item.GlyphIdArray[60] = src[66]
	item.GlyphIdArray[61] = src[67]
	item.GlyphIdArray[62] = src[68]
	item.GlyphIdArray[63] = src[69]
	item.GlyphIdArray[64] = src[70]
	item.GlyphIdArray[65] = src[71]
	item.GlyphIdArray[66] = src[72]
	item.GlyphIdArray[67] = src[73]
	item.GlyphIdArray[68] = src[74]
	item.GlyphIdArray[69] = src[75]
	item.GlyphIdArray[70] = src[76]
	item.GlyphIdArray[71] = src[77]
	item.GlyphIdArray[72] = src[78]
	item.GlyphIdArray[73] = src[79]
	item.GlyphIdArray[74] = src[80]
	item.GlyphIdArray[75] = src[81]
	item.GlyphIdArray[76] = src[82]
	item.GlyphIdArray[77] = src[83]
	item.GlyphIdArray[78] = src[84]
	item.GlyphIdArray[79] = src[85]
	item.GlyphIdArray[80] = src[86]
	item.GlyphIdArray[81] = src[87]
	item.GlyphIdArray[82] = src[88]
	item.GlyphIdArray[83] = src[89]
	item.GlyphIdArray[84] = src[90]
	item.GlyphIdArray[85] = src[91]
	item.GlyphIdArray[86] = src[92]
	item.GlyphIdArray[87] = src[93]
	item.GlyphIdArray[88] = src[94]
	item.GlyphIdArray[89] = src[95]
	item.GlyphIdArray[90] = src[96]
	item.GlyphIdArray[91] = src[97]
	item.GlyphIdArray[92] = src[98]
	item.GlyphIdArray[93] = src[99]
	item.GlyphIdArray[94] = src[100]
	item.GlyphIdArray[95] = src[101]
	item.GlyphIdArray[96] = src[102]
	item.GlyphIdArray[97] = src[103]
	item.GlyphIdArray[98] = src[104]
	item.GlyphIdArray[99] = src[105]
	item.GlyphIdArray[100] = src[106]
	item.GlyphIdArray[101] = src[107]
	item.GlyphIdArray[102] = src[108]
	item.GlyphIdArray[103] = src[109]
	item.GlyphIdArray[104] = src[110]
	item.GlyphIdArray[105] = src[111]
	item.GlyphIdArray[106] = src[112]
	item.GlyphIdArray[107] = src[113]
	item.GlyphIdArray[108] = src[114]
	item.GlyphIdArray[109] = src[115]
	item.GlyphIdArray[110] = src[116]
	item.GlyphIdArray[111] = src[117]
	item.GlyphIdArray[112] = src[118]
	item.GlyphIdArray[113] = src[119]
	item.GlyphIdArray[114] = src[120]
	item.GlyphIdArray[115] = src[121]
	item.GlyphIdArray[116] = src[122]
	item.GlyphIdArray[117] = src[123]
	item.GlyphIdArray[118] = src[124]
	item.GlyphIdArray[119] = src[125]
	item.GlyphIdArray[120] = src[126]
	item.GlyphIdArray[121] = src[127]
	item.GlyphIdArray[122] = src[128]
	item.GlyphIdArray[123] = src[129]
	item.GlyphIdArray[124] = src[130]
	item.GlyphIdArray[125] = src[131]
	item.GlyphIdArray[126] = src[132]
	item.GlyphIdArray[127] = src[133]
	item.GlyphIdArray[128] = src[134]
	item.GlyphIdArray[129] = src[135]
	item.GlyphIdArray[130] = src[136]
	item.GlyphIdArray[131] = src[137]
	item.GlyphIdArray[132] = src[138]
	item.GlyphIdArray[133] = src[139]
	item.GlyphIdArray[134] = src[140]
	item.GlyphIdArray[135] = src[141]
	item.GlyphIdArray[136] = src[142]
	item.GlyphIdArray[137] = src[143]
	item.GlyphIdArray[138] = src[144]
	item.GlyphIdArray[139] = src[145]
	item.GlyphIdArray[140] = src[146]
	item.GlyphIdArray[141] = src[147]
	item.GlyphIdArray[142] = src[148]
	item.GlyphIdArray[143] = src[149]
	item.GlyphIdArray[144] = src[150]
	item.GlyphIdArray[145] = src[151]
	item.GlyphIdArray[146] = src[152]
	item.GlyphIdArray[147] = src[153]
	item.GlyphIdArray[148] = src[154]
	item.GlyphIdArray[149] = src[155]
	item.GlyphIdArray[150] = src[156]
	item.GlyphIdArray[151] = src[157]
	item.GlyphIdArray[152] = src[158]
	item.GlyphIdArray[153] = src[159]
	item.GlyphIdArray[154] = src[160]
	item.GlyphIdArray[155] = src[161]
	item.GlyphIdArray[156] = src[162]
	item.GlyphIdArray[157] = src[163]
	item.GlyphIdArray[158] = src[164]
	item.GlyphIdArray[159] = src[165]
	item.GlyphIdArray[160] = src[166]
	item.GlyphIdArray[161] = src[167]
	item.GlyphIdArray[162] = src[168]
	item.GlyphIdArray[163] = src[169]
	item.GlyphIdArray[164] = src[170]
	item.GlyphIdArray[165] = src[171]
	item.GlyphIdArray[166] = src[172]
	item.GlyphIdArray[167] = src[173]
	item.GlyphIdArray[168] = src[174]
	item.GlyphIdArray[169] = src[175]
	item.GlyphIdArray[170] = src[176]
	item.GlyphIdArray[171] = src[177]
	item.GlyphIdArray[172] = src[178]
	item.GlyphIdArray[173] = src[179]
	item.GlyphIdArray[174] = src[180]
	item.GlyphIdArray[175] = src[181]
	item.GlyphIdArray[176] = src[182]
	item.GlyphIdArray[177] = src[183]
	item.GlyphIdArray[178] = src[184]
	item.GlyphIdArray[179] = src[185]
	item.GlyphIdArray[180] = src[186]
	item.GlyphIdArray[181] = src[187]
	item.GlyphIdArray[182] = src[188]
	item.GlyphIdArray[183] = src[189]
	item.GlyphIdArray[184] = src[190]
	item.GlyphIdArray[185] = src[191]
	item.GlyphIdArray[186] = src[192]
	item.GlyphIdArray[187] = src[193]
	item.GlyphIdArray[188] = src[194]
	item.GlyphIdArray[189] = src[195]
	item.GlyphIdArray[190] = src[196]
	item.GlyphIdArray[191] = src[197]
	item.GlyphIdArray[192] = src[198]
	item.GlyphIdArray[193] = src[199]
	item.GlyphIdArray[194] = src[200]
	item.GlyphIdArray[195] = src[201]
	item.GlyphIdArray[196] = src[202]
	item.GlyphIdArray[197] = src[203]
	item.GlyphIdArray[198] = src[204]
	item.GlyphIdArray[199] = src[205]
	item.GlyphIdArray[200] = src[206]
	item.GlyphIdArray[201] = src[207]
	item.GlyphIdArray[202] = src[208]
	item.GlyphIdArray[203] = src[209]
	item.GlyphIdArray[204] = src[210]
	item.GlyphIdArray[205] = src[211]
	item.GlyphIdArray[206] = src[212]
	item.GlyphIdArray[207] = src[213]
	item.GlyphIdArray[208] = src[214]
	item.GlyphIdArray[209] = src[215]
	item.GlyphIdArray[210] = src[216]
	item.GlyphIdArray[211] = src[217]
	item.GlyphIdArray[212] = src[218]
	item.GlyphIdArray[213] = src[219]
	item.GlyphIdArray[214] = src[220]
	item.GlyphIdArray[215] = src[221]
	item.GlyphIdArray[216] = src[222]
	item.GlyphIdArray[217] = src[223]
	item.GlyphIdArray[218] = src[224]
	item.GlyphIdArray[219] = src[225]
	item.GlyphIdArray[220] = src[226]
	item.GlyphIdArray[221] = src[227]
	item.GlyphIdArray[222] = src[228]
	item.GlyphIdArray[223] = src[229]
	item.GlyphIdArray[224] = src[230]
	item.GlyphIdArray[225] = src[231]
	item.GlyphIdArray[226] = src[232]
	item.GlyphIdArray[227] = src[233]
	item.GlyphIdArray[228] = src[234]
	item.GlyphIdArray[229] = src[235]
	item.GlyphIdArray[230] = src[236]
	item.GlyphIdArray[231] = src[237]
	item.GlyphIdArray[232] = src[238]
	item.GlyphIdArray[233] = src[239]
	item.GlyphIdArray[234] = src[240]
	item.GlyphIdArray[235] = src[241]
	item.GlyphIdArray[236] = src[242]
	item.GlyphIdArray[237] = src[243]
	item.GlyphIdArray[238] = src[244]
	item.GlyphIdArray[239] = src[245]
	item.GlyphIdArray[240] = src[246]
	item.GlyphIdArray[241] = src[247]
	item.GlyphIdArray[242] = src[248]
	item.GlyphIdArray[243] = src[249]
	item.GlyphIdArray[244] = src[250]
	item.GlyphIdArray[245] = src[251]
	item.GlyphIdArray[246] = src[252]
	item.GlyphIdArray[247] = src[253]
	item.GlyphIdArray[248] = src[254]
	item.GlyphIdArray[249] = src[255]
	item.GlyphIdArray[250] = src[256]
	item.GlyphIdArray[251] = src[257]
	item.GlyphIdArray[252] = src[258]
	item.GlyphIdArray[253] = src[259]
	item.GlyphIdArray[254] = src[260]
	item.GlyphIdArray[255] = src[261]
}

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

	{
		arrayLength := int(item.numTables)

		offset := 4
		for i := 0; i < arrayLength; i++ {
			elem, read, err := ParseEncodingRecord(src[offset:], src)
			if err != nil {
				return item, 0, fmt.Errorf("reading Cmap: %s", err)
			}
			item.Records = append(item.Records, elem)
			offset += read
		}
		n = offset
	}
	return item, n, nil
}

func ParseCmapSubtable(src []byte) (CmapSubtable, int, error) {
	var item CmapSubtable

	if L := len(src); L < 2 {
		return item, 0, fmt.Errorf("reading CmapSubtable: "+"EOF: expected length: 2, got %d", L)
	}
	format := uint16(binary.BigEndian.Uint16(src[0:]))
	var (
		read int
		err  error
	)
	switch format {
	case 0:
		item, read, err = ParseCmapSubtable0(src[0:])
	case 10:
		item, read, err = ParseCmapSubtable10(src[0:])
	case 12:
		item, read, err = ParseCmapSubtable12(src[0:])
	case 13:
		item, read, err = ParseCmapSubtable13(src[0:])
	case 14:
		item, read, err = ParseCmapSubtable14(src[0:])
	case 2:
		item, read, err = ParseCmapSubtable2(src[0:])
	case 4:
		item, read, err = ParseCmapSubtable4(src[0:])
	case 6:
		item, read, err = ParseCmapSubtable6(src[0:])
	default:
		err = fmt.Errorf("unsupported CmapSubtable format %d", format)
	}
	if err != nil {
		return item, 0, fmt.Errorf("reading CmapSubtable: %s", err)
	}

	return item, read, nil
}

func ParseCmapSubtable0(src []byte) (CmapSubtable0, int, error) {
	var item CmapSubtable0
	n := 0
	if L := len(src); L < 262 {
		return item, 0, fmt.Errorf("reading CmapSubtable0: "+"EOF: expected length: 262, got %d", L)
	}
	item.mustParse(src)
	n += 262
	return item, n, nil
}

func ParseCmapSubtable10(src []byte) (CmapSubtable10, int, error) {
	var item CmapSubtable10
	n := 0
	if L := len(src); L < 20 {
		return item, 0, fmt.Errorf("reading CmapSubtable10: "+"EOF: expected length: 20, got %d", L)
	}
	_ = src[19] // early bound checking
	item.format = binary.BigEndian.Uint16(src[0:])
	item.reserved = binary.BigEndian.Uint16(src[2:])
	item.length = binary.BigEndian.Uint32(src[4:])
	item.language = binary.BigEndian.Uint32(src[8:])
	item.StartCharCode = binary.BigEndian.Uint32(src[12:])
	arrayLengthGlyphIdArray := int(binary.BigEndian.Uint32(src[16:]))
	n += 20

	{

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

		item.GlyphIdArray = make([]uint16, arrayLengthGlyphIdArray) // allocation guarded by the previous check
		for i := range item.GlyphIdArray {
			item.GlyphIdArray[i] = binary.BigEndian.Uint16(src[20+i*2:])
		}
		n += arrayLengthGlyphIdArray * 2
	}
	return item, n, nil
}

func ParseCmapSubtable12(src []byte) (CmapSubtable12, int, error) {
	var item CmapSubtable12
	n := 0
	if L := len(src); L < 16 {
		return item, 0, fmt.Errorf("reading CmapSubtable12: "+"EOF: expected length: 16, got %d", L)
	}
	_ = src[15] // early bound checking
	item.format = binary.BigEndian.Uint16(src[0:])
	item.reserved = binary.BigEndian.Uint16(src[2:])
	item.length = binary.BigEndian.Uint32(src[4:])
	item.language = binary.BigEndian.Uint32(src[8:])
	arrayLengthGroups := int(binary.BigEndian.Uint32(src[12:]))
	n += 16

	{

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

		item.Groups = make([]SequentialMapGroup, arrayLengthGroups) // allocation guarded by the previous check
		for i := range item.Groups {
			item.Groups[i].mustParse(src[16+i*12:])
		}
		n += arrayLengthGroups * 12
	}
	return item, n, nil
}

func ParseCmapSubtable13(src []byte) (CmapSubtable13, int, error) {
	var item CmapSubtable13
	n := 0
	if L := len(src); L < 16 {
		return item, 0, fmt.Errorf("reading CmapSubtable13: "+"EOF: expected length: 16, got %d", L)
	}
	_ = src[15] // early bound checking
	item.format = binary.BigEndian.Uint16(src[0:])
	item.reserved = binary.BigEndian.Uint16(src[2:])
	item.length = binary.BigEndian.Uint32(src[4:])
	item.language = binary.BigEndian.Uint32(src[8:])
	arrayLengthGroups := int(binary.BigEndian.Uint32(src[12:]))
	n += 16

	{

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

		item.Groups = make([]SequentialMapGroup, arrayLengthGroups) // allocation guarded by the previous check
		for i := range item.Groups {
			item.Groups[i].mustParse(src[16+i*12:])
		}
		n += arrayLengthGroups * 12
	}
	return item, n, nil
}

func ParseCmapSubtable14(src []byte) (CmapSubtable14, int, error) {
	var item CmapSubtable14
	n := 0
	if L := len(src); L < 10 {
		return item, 0, fmt.Errorf("reading CmapSubtable14: "+"EOF: expected length: 10, got %d", L)
	}
	_ = src[9] // early bound checking
	item.format = binary.BigEndian.Uint16(src[0:])
	item.length = binary.BigEndian.Uint32(src[2:])
	arrayLengthVarSelectors := int(binary.BigEndian.Uint32(src[6:]))
	n += 10

	{

		offset := 10
		for i := 0; i < arrayLengthVarSelectors; i++ {
			elem, read, err := ParseVariationSelector(src[offset:], src)
			if err != nil {
				return item, 0, fmt.Errorf("reading CmapSubtable14: %s", err)
			}
			item.VarSelectors = append(item.VarSelectors, elem)
			offset += read
		}
		n = offset
	}
	return item, n, nil
}

func ParseCmapSubtable2(src []byte) (CmapSubtable2, int, error) {
	var item CmapSubtable2
	n := 0
	if L := len(src); L < 2 {
		return item, 0, fmt.Errorf("reading CmapSubtable2: "+"EOF: expected length: 2, got %d", L)
	}
	item.format = binary.BigEndian.Uint16(src[0:])
	n += 2

	{

		item.rawData = src[2:]
		n = len(src)
	}
	return item, n, nil
}

func ParseCmapSubtable4(src []byte) (CmapSubtable4, int, error) {
	var item CmapSubtable4
	n := 0
	if L := len(src); L < 14 {
		return item, 0, fmt.Errorf("reading CmapSubtable4: "+"EOF: expected length: 14, got %d", L)
	}
	_ = src[13] // early bound checking
	item.format = binary.BigEndian.Uint16(src[0:])
	item.length = binary.BigEndian.Uint16(src[2:])
	item.language = binary.BigEndian.Uint16(src[4:])
	item.segCountX2 = binary.BigEndian.Uint16(src[6:])
	item.searchRange = binary.BigEndian.Uint16(src[8:])
	item.entrySelector = binary.BigEndian.Uint16(src[10:])
	item.rangeShift = binary.BigEndian.Uint16(src[12:])
	n += 14

	{
		arrayLength := int(item.segCountX2 / 2)

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

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

	{
		arrayLength := int(item.segCountX2 / 2)

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

		item.StartCode = make([]uint16, arrayLength) // allocation guarded by the previous check
		for i := range item.StartCode {
			item.StartCode[i] = binary.BigEndian.Uint16(src[n+i*2:])
		}
		n += arrayLength * 2
	}
	{
		arrayLength := int(item.segCountX2 / 2)

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

		item.IdDelta = make([]uint16, arrayLength) // allocation guarded by the previous check
		for i := range item.IdDelta {
			item.IdDelta[i] = binary.BigEndian.Uint16(src[n+i*2:])
		}
		n += arrayLength * 2
	}
	{
		arrayLength := int(item.segCountX2 / 2)

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

		item.IdRangeOffsets = make([]uint16, arrayLength) // allocation guarded by the previous check
		for i := range item.IdRangeOffsets {
			item.IdRangeOffsets[i] = binary.BigEndian.Uint16(src[n+i*2:])
		}
		n += arrayLength * 2
	}
	{

		item.GlyphIDArray = src[n:]
		n = len(src)
	}
	return item, n, nil
}

func ParseCmapSubtable6(src []byte) (CmapSubtable6, int, error) {
	var item CmapSubtable6
	n := 0
	if L := len(src); L < 10 {
		return item, 0, fmt.Errorf("reading CmapSubtable6: "+"EOF: expected length: 10, got %d", L)
	}
	_ = src[9] // early bound checking
	item.format = binary.BigEndian.Uint16(src[0:])
	item.length = binary.BigEndian.Uint16(src[2:])
	item.language = binary.BigEndian.Uint16(src[4:])
	item.FirstCode = binary.BigEndian.Uint16(src[6:])
	arrayLengthGlyphIdArray := int(binary.BigEndian.Uint16(src[8:]))
	n += 10

	{

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

		item.GlyphIdArray = make([]uint16, arrayLengthGlyphIdArray) // allocation guarded by the previous check
		for i := range item.GlyphIdArray {
			item.GlyphIdArray[i] = binary.BigEndian.Uint16(src[10+i*2:])
		}
		n += arrayLengthGlyphIdArray * 2
	}
	return item, n, nil
}

func ParseDefaultUVSTable(src []byte) (DefaultUVSTable, int, error) {
	var item DefaultUVSTable
	n := 0
	if L := len(src); L < 4 {
		return item, 0, fmt.Errorf("reading DefaultUVSTable: "+"EOF: expected length: 4, got %d", L)
	}
	arrayLengthRanges := int(binary.BigEndian.Uint32(src[0:]))
	n += 4

	{

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

		item.Ranges = make([]UnicodeRange, arrayLengthRanges) // allocation guarded by the previous check
		for i := range item.Ranges {
			item.Ranges[i].mustParse(src[4+i*4:])
		}
		n += arrayLengthRanges * 4
	}
	return item, n, nil
}

func ParseEncodingRecord(src []byte, parentSrc []byte) (EncodingRecord, int, error) {
	var item EncodingRecord
	n := 0
	if L := len(src); L < 8 {
		return item, 0, fmt.Errorf("reading EncodingRecord: "+"EOF: expected length: 8, got %d", L)
	}
	_ = src[7] // early bound checking
	item.PlatformID = PlatformID(binary.BigEndian.Uint16(src[0:]))
	item.EncodingID = EncodingID(binary.BigEndian.Uint16(src[2:]))
	offsetSubtable := int(binary.BigEndian.Uint32(src[4:]))
	n += 8

	{
		if offsetSubtable != 0 { // ignore null offset
			if L := len(parentSrc); L < offsetSubtable {
				return item, 0, fmt.Errorf("reading EncodingRecord: "+"EOF: expected length: %d, got %d", offsetSubtable, L)
			}

			var (
				err  error
				read int
			)
			item.Subtable, read, err = ParseCmapSubtable(parentSrc[offsetSubtable:])
			if err != nil {
				return item, 0, fmt.Errorf("reading EncodingRecord: %s", err)
			}
			offsetSubtable += read
		}
	}
	return item, n, nil
}

func ParseUVSMappingTable(src []byte) (UVSMappingTable, int, error) {
	var item UVSMappingTable
	n := 0
	if L := len(src); L < 4 {
		return item, 0, fmt.Errorf("reading UVSMappingTable: "+"EOF: expected length: 4, got %d", L)
	}
	arrayLengthRanges := int(binary.BigEndian.Uint32(src[0:]))
	n += 4

	{

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

		item.Ranges = make([]UvsMappingRecord, arrayLengthRanges) // allocation guarded by the previous check
		for i := range item.Ranges {
			item.Ranges[i].mustParse(src[4+i*5:])
		}
		n += arrayLengthRanges * 5
	}
	return item, n, nil
}

func ParseVariationSelector(src []byte, parentSrc []byte) (VariationSelector, int, error) {
	var item VariationSelector
	n := 0
	if L := len(src); L < 11 {
		return item, 0, fmt.Errorf("reading VariationSelector: "+"EOF: expected length: 11, got %d", L)
	}
	_ = src[10] // early bound checking
	item.VarSelector[0] = src[0]
	item.VarSelector[1] = src[1]
	item.VarSelector[2] = src[2]
	offsetDefaultUVS := int(binary.BigEndian.Uint32(src[3:]))
	offsetNonDefaultUVS := int(binary.BigEndian.Uint32(src[7:]))
	n += 11

	{
		if offsetDefaultUVS != 0 { // ignore null offset
			if L := len(parentSrc); L < offsetDefaultUVS {
				return item, 0, fmt.Errorf("reading VariationSelector: "+"EOF: expected length: %d, got %d", offsetDefaultUVS, L)
			}

			var err error
			item.DefaultUVS, _, err = ParseDefaultUVSTable(parentSrc[offsetDefaultUVS:])
			if err != nil {
				return item, 0, fmt.Errorf("reading VariationSelector: %s", err)
			}

		}
	}
	{
		if offsetNonDefaultUVS != 0 { // ignore null offset
			if L := len(parentSrc); L < offsetNonDefaultUVS {
				return item, 0, fmt.Errorf("reading VariationSelector: "+"EOF: expected length: %d, got %d", offsetNonDefaultUVS, L)
			}

			var err error
			item.NonDefaultUVS, _, err = ParseUVSMappingTable(parentSrc[offsetNonDefaultUVS:])
			if err != nil {
				return item, 0, fmt.Errorf("reading VariationSelector: %s", err)
			}

		}
	}
	return item, n, nil
}

func (item *SequentialMapGroup) mustParse(src []byte) {
	_ = src[11] // early bound checking
	item.StartCharCode = binary.BigEndian.Uint32(src[0:])
	item.EndCharCode = binary.BigEndian.Uint32(src[4:])
	item.StartGlyphID = binary.BigEndian.Uint32(src[8:])
}

func (item *UnicodeRange) mustParse(src []byte) {
	_ = src[3] // early bound checking
	item.StartUnicodeValue[0] = src[0]
	item.StartUnicodeValue[1] = src[1]
	item.StartUnicodeValue[2] = src[2]
	item.AdditionalCount = src[3]
}

func (item *UvsMappingRecord) mustParse(src []byte) {
	_ = src[4] // early bound checking
	item.UnicodeValue[0] = src[0]
	item.UnicodeValue[1] = src[1]
	item.UnicodeValue[2] = src[2]
	item.GlyphID = binary.BigEndian.Uint16(src[3:])
}
