package avro

import (
	
	
	
	
	

	
)

func createDecoderOfArray( *decoderContext,  *ArraySchema,  reflect2.Type) ValDecoder {
	if .Kind() == reflect.Slice {
		return decoderOfArray(, , )
	}

	return &errorDecoder{err: fmt.Errorf("avro: %s is unsupported for Avro %s", .String(), .Type())}
}

func createEncoderOfArray( *encoderContext,  *ArraySchema,  reflect2.Type) ValEncoder {
	if .Kind() == reflect.Slice {
		return encoderOfArray(, , )
	}

	return &errorEncoder{err: fmt.Errorf("avro: %s is unsupported for Avro %s", .String(), .Type())}
}

func decoderOfArray( *decoderContext,  *ArraySchema,  reflect2.Type) ValDecoder {
	 := .(*reflect2.UnsafeSliceType)
	 := decoderOfType(, .Items(), .Elem())

	return &arrayDecoder{typ: , decoder: }
}

type arrayDecoder struct {
	typ     *reflect2.UnsafeSliceType
	decoder ValDecoder
}

func ( *arrayDecoder) ( unsafe.Pointer,  *Reader) {
	var  int
	 := .typ

	if .UnsafeIsNil() {
		.UnsafeSet(, .UnsafeMakeSlice(0, 0))
	}

	for {
		,  := .ReadBlockHeader()
		if  == 0 {
			break
		}

		 := 
		 += int()

		if  > .cfg.getMaxSliceAllocSize() {
			.ReportError("decode array", "size is greater than `Config.MaxSliceAllocSize`")
			return
		}

		.UnsafeGrow(, )

		for  := ;  < ; ++ {
			 := .UnsafeGetIndex(, )
			.decoder.Decode(, )
			if .Error != nil {
				.Error = fmt.Errorf("reading %s: %w", .typ.String(), .Error)
				return
			}
		}
	}

	if .Error != nil && !errors.Is(.Error, io.EOF) {
		.Error = fmt.Errorf("%v: %w", .typ, .Error)
	}
}

func encoderOfArray( *encoderContext,  *ArraySchema,  reflect2.Type) ValEncoder {
	 := .(*reflect2.UnsafeSliceType)
	 := encoderOfType(, .Items(), .Elem())

	return &arrayEncoder{
		blockLength: .cfg.getBlockLength(),
		typ:         ,
		encoder:     ,
	}
}

type arrayEncoder struct {
	blockLength int
	typ         *reflect2.UnsafeSliceType
	encoder     ValEncoder
}

func ( *arrayEncoder) ( unsafe.Pointer,  *Writer) {
	 := .blockLength
	 := .typ.UnsafeLengthOf()

	for  := 0;  < ;  +=  {
		.WriteBlockCB(func( *Writer) int64 {
			 := int64(0)
			for  := ;  < + &&  < ; ++ {
				 := .typ.UnsafeGetIndex(, )
				.encoder.Encode(, )
				if .Error != nil && !errors.Is(.Error, io.EOF) {
					.Error = fmt.Errorf("%s: %w", .typ.String(), .Error)
					return 
				}
				++
			}

			return 
		})
	}

	.WriteBlockHeader(0, 0)

	if .Error != nil && !errors.Is(.Error, io.EOF) {
		.Error = fmt.Errorf("%v: %w", .typ, .Error)
	}
}