// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package variant

import (
	
	
	

	
	
)

func readLEU32( []byte) uint32 {
	debug.Assert(len() <= 4, "buffer too large")
	debug.Assert(len() >= 1, "buffer too small")

	var  uint32
	 := (*[4]byte)(unsafe.Pointer(&))
	copy([:], )

	return endian.FromLE()
}

func readLEU64( []byte) uint64 {
	debug.Assert(len() <= 8, "buffer too large")
	debug.Assert(len() >= 1, "buffer too small")

	var  uint64
	 := (*[8]byte)(unsafe.Pointer(&))
	copy([:], )

	return endian.FromLE()
}

func readExact[ int8 | int16 | int32 | int64 | float32 | float64]( []byte)  {
	debug.Assert(len() >= binary.Size((0)), "buffer size mismatch")
	var  
	binary.Decode(, binary.LittleEndian, &)
	return 
}

func primitiveHeader( PrimitiveType) byte {
	return (byte()<<2 | byte(BasicPrimitive))
}

func shortStrHeader( int) byte {
	return byte(<<2) | byte(BasicShortString)
}

func arrayHeader( bool,  uint8) byte {
	var  byte
	if  {
		 = 1
	}

	return ( << (basicTypeBits + 2)) |
		(( - 1) << basicTypeBits) | byte(BasicArray)
}

func objectHeader( bool, ,  uint8) byte {
	var  byte
	if  {
		 = 1
	}

	return ( << (basicTypeBits + 4)) |
		(( - 1) << (basicTypeBits + 2)) |
		(( - 1) << basicTypeBits) | byte(BasicObject)
}

func intSize( int) uint8 {
	debug.Assert( <= metadataMaxSizeLimit, "size too large")
	debug.Assert( >= 0, "size cannot be negative")

	switch {
	case  <= math.MaxUint8:
		return 1
	case  <= math.MaxUint16:
		return 2
	case  <= 0xFFFFFF: // MaxUint24
		return 3
	default:
		return 4
	}
}

func writeOffset( []byte,  int,  uint8) {
	debug.Assert( <= 4, "nbytes size too large")
	debug.Assert( >= 1, "nbytes size too small")

	for  := range  {
		[] = byte(( >> ( * 8)) & 0xFF)
	}
}

func valueSize( []byte) int {
	,  := [0]&basicTypeMask, ([0]>>basicTypeBits)&typeInfoMask
	switch  {
	case byte(BasicShortString):
		return 1 + int()
	case byte(BasicObject):
		var  uint8 = 1
		if (( >> 4) & 0x1) != 0 {
			 = 4
		}

		 := readLEU32([1 : 1+])
		,  := ((>>2)&0b11)+1, uint32((&0b11)+1)
		 := 1 + 
		 := uint32() + *uint32()
		 :=  + (+1)*

		 :=  + *uint32()
		return int( + readLEU32([:+]))
	case byte(BasicArray):
		var  uint8 = 1
		if (( >> 4) & 0x1) != 0 {
			 = 4
		}

		 := readLEU32([1 : 1+])
		,  := uint32((&0b11)+1), uint32(1+)
		 :=  + (+1)*

		 :=  + *uint32()
		return int( + readLEU32([:+]))
	default:
		switch PrimitiveType() {
		case PrimitiveNull, PrimitiveBoolTrue, PrimitiveBoolFalse:
			return 1
		case PrimitiveInt8:
			return 2
		case PrimitiveInt16:
			return 3
		case PrimitiveInt32, PrimitiveDate, PrimitiveFloat:
			return 5
		case PrimitiveInt64, PrimitiveDouble, PrimitiveTimeMicrosNTZ,
			PrimitiveTimestampMicros, PrimitiveTimestampMicrosNTZ,
			PrimitiveTimestampNanos, PrimitiveTimestampNanosNTZ:
			return 9
		case PrimitiveDecimal4:
			return 6
		case PrimitiveDecimal8:
			return 10
		case PrimitiveDecimal16:
			return 18
		case PrimitiveBinary, PrimitiveString:
			return 5 + int(readLEU32([1:5]))
		case PrimitiveUUID:
			return 17
		default:
			panic("unknown primitive type")
		}
	}
}