package ndr

import (
	
	
	
)

// Byte sizes of primitive types
const (
	SizeBool   = 1
	SizeChar   = 1
	SizeUint8  = 1
	SizeUint16 = 2
	SizeUint32 = 4
	SizeUint64 = 8
	SizeEnum   = 2
	SizeSingle = 4
	SizeDouble = 8
	SizePtr    = 4
)

// Bool is an NDR Boolean which is a logical quantity that assumes one of two values: TRUE or FALSE.
// NDR represents a Boolean as one octet.
// It represents a value of FALSE as a zero octet, an octet in which every bit is reset.
// It represents a value of TRUE as a non-zero octet, an octet in which one or more bits are set.

// Char is an NDR character.
// NDR represents a character as one octet.
// Characters have two representation formats: ASCII and EBCDIC.

// USmall is an unsigned 8 bit integer

// UShort is an unsigned 16 bit integer

// ULong is an unsigned 32 bit integer

// UHyper is an unsigned 64 bit integer

// Small is an signed 8 bit integer

// Short is an signed 16 bit integer

// Long is an signed 32 bit integer

// Hyper is an signed 64 bit integer

// Enum is the NDR representation of enumerated types as signed short integers (2 octets)

// Single is an NDR defined single-precision floating-point data type

// Double is an NDR defined double-precision floating-point data type

// readBool reads a byte representing a boolean.
// NDR represents a Boolean as one octet.
// It represents a value of FALSE as a zero octet, an octet in which every bit is reset.
// It represents a value of TRUE as a non-zero octet, an octet in which one or more bits are set.
func ( *Decoder) () (bool, error) {
	,  := .readUint8()
	if  != nil {
		return false, 
	}
	if  != 0 {
		return true, nil
	}
	return false, nil
}

// readChar reads bytes representing a 8bit ASCII integer cast to a rune.
func ( *Decoder) () (rune, error) {
	var  rune
	,  := .readUint8()
	if  != nil {
		return , 
	}
	return rune(), nil
}

// readUint8 reads bytes representing a 8bit unsigned integer.
func ( *Decoder) () (uint8, error) {
	,  := .r.ReadByte()
	if  != nil {
		return uint8(0), 
	}
	return uint8(), nil
}

// readUint16 reads bytes representing a 16bit unsigned integer.
func ( *Decoder) () (uint16, error) {
	.ensureAlignment(SizeUint16)
	,  := .readBytes(SizeUint16)
	if  != nil {
		return uint16(0), 
	}
	return .ch.Endianness.Uint16(), nil
}

// readUint32 reads bytes representing a 32bit unsigned integer.
func ( *Decoder) () (uint32, error) {
	.ensureAlignment(SizeUint32)
	,  := .readBytes(SizeUint32)
	if  != nil {
		return uint32(0), 
	}
	return .ch.Endianness.Uint32(), nil
}

// readUint32 reads bytes representing a 32bit unsigned integer.
func ( *Decoder) () (uint64, error) {
	.ensureAlignment(SizeUint64)
	,  := .readBytes(SizeUint64)
	if  != nil {
		return uint64(0), 
	}
	return .ch.Endianness.Uint64(), nil
}

func ( *Decoder) () (int8, error) {
	.ensureAlignment(SizeUint8)
	,  := .readBytes(SizeUint8)
	if  != nil {
		return 0, 
	}
	var  int8
	 := bytes.NewReader()
	 = binary.Read(, .ch.Endianness, &)
	if  != nil {
		return 0, 
	}
	return , nil
}

func ( *Decoder) () (int16, error) {
	.ensureAlignment(SizeUint16)
	,  := .readBytes(SizeUint16)
	if  != nil {
		return 0, 
	}
	var  int16
	 := bytes.NewReader()
	 = binary.Read(, .ch.Endianness, &)
	if  != nil {
		return 0, 
	}
	return , nil
}

func ( *Decoder) () (int32, error) {
	.ensureAlignment(SizeUint32)
	,  := .readBytes(SizeUint32)
	if  != nil {
		return 0, 
	}
	var  int32
	 := bytes.NewReader()
	 = binary.Read(, .ch.Endianness, &)
	if  != nil {
		return 0, 
	}
	return , nil
}

func ( *Decoder) () (int64, error) {
	.ensureAlignment(SizeUint64)
	,  := .readBytes(SizeUint64)
	if  != nil {
		return 0, 
	}
	var  int64
	 := bytes.NewReader()
	 = binary.Read(, .ch.Endianness, &)
	if  != nil {
		return 0, 
	}
	return , nil
}

// https://en.wikipedia.org/wiki/IEEE_754-1985
func ( *Decoder) () ( float32,  error) {
	.ensureAlignment(SizeSingle)
	,  := .readBytes(SizeSingle)
	if  != nil {
		return
	}
	 := .ch.Endianness.Uint32()
	 = math.Float32frombits()
	return
}

func ( *Decoder) () ( float64,  error) {
	.ensureAlignment(SizeDouble)
	,  := .readBytes(SizeDouble)
	if  != nil {
		return
	}
	 := .ch.Endianness.Uint64()
	 = math.Float64frombits()
	return
}

// NDR enforces NDR alignment of primitive data; that is, any primitive of size n octets is aligned at a octet stream
// index that is a multiple of n. (In this version of NDR, n is one of {1, 2, 4, 8}.) An octet stream index indicates
// the number of an octet in an octet stream when octets are numbered, beginning with 0, from the first octet in the
// stream. Where necessary, an alignment gap, consisting of octets of unspecified value, precedes the representation
// of a primitive. The gap is of the smallest size sufficient to align the primitive.
func ( *Decoder) ( int) {
	 := .size - .r.Buffered()
	if  :=  % ;  != 0 {
		.r.Discard( - )
	}
}