{{- /*gotype: github.com/ClickHouse/ch-go/proto/cmd/ch-gen-col.Variant*/ -}}
//go:build (amd64 || arm64 || riscv64) && !purego
// Code generated by ./cmd/ch-gen-col, DO NOT EDIT.

package proto

import (
	"unsafe"

	"github.com/go-faster/errors"
)

// DecodeColumn decodes {{ .Name }} rows from *Reader.
func (c *{{ .Type }}) DecodeColumn(r *Reader, rows int) error {
	if rows == 0 {
		return nil
	}
	{{- if .DateTime }}
	c.Data = append(c.Data, make([]{{ .ElemType }}, rows)...)
	s := *(*slice)(unsafe.Pointer(&c.Data))
	{{- else }}
	*c = append(*c, make([]{{ .ElemType }}, rows)...)
	s := *(*slice)(unsafe.Pointer(c))
	{{- end }}
	{{- if not .SingleByte }}
	{{- if .FixedStr }}
	const size = {{ .Bytes }}
	{{- else }}
	const size = {{ .Bits }} / 8
	{{- end }}
	s.Len *= size
	s.Cap *= size
	{{- end }}
	dst := *(*[]byte)(unsafe.Pointer(&s))
	if err := r.ReadFull(dst); err != nil {
		return errors.Wrap(err, "read full")
	}
	return nil
}

// EncodeColumn encodes {{ .Name }} rows to *Buffer.
func (c {{ .Type }}) EncodeColumn(b *Buffer) {
	{{- if .DateTime }}
	v := c.Data
	{{- else }}
	v := c
	{{- end }}
	if len(v) == 0 {
		return
	}
	offset := len(b.Buf)
	{{- if .SingleByte }}
	b.Buf = append(b.Buf, make([]byte, len(v))...)
	{{- else }}
	{{- if .FixedStr }}
	const size = {{ .Bytes }}
	{{- else }}
	const size = {{ .Bits }} / 8
	{{- end }}
	b.Buf = append(b.Buf, make([]byte, size*len(v))...)
	{{- end }}
	s := *(*slice)(unsafe.Pointer(&v))
	{{- if not .SingleByte }}
	s.Len *= size
	s.Cap *= size
	{{- end }}
	src := *(*[]byte)(unsafe.Pointer(&s))
	dst := b.Buf[offset:]
	copy(dst, src)
}

func (c {{ .Type }}) WriteColumn(w *Writer) {
	{{- if .DateTime }}
	v := c.Data
	{{- else }}
	v := c
	{{- end }}
	if len(v) == 0 {
		return
	}
	{{- if .SingleByte }}
		src := *(*[]byte)(unsafe.Pointer(&v))
	{{- else }}
		{{- if .FixedStr }}
			const size = {{ .Bytes }}
		{{- else }}
			const size = {{ .Bits }} / 8
		{{- end }}

		s := *(*slice)(unsafe.Pointer(&v))
		{{- if not .SingleByte }}
			s.Len *= size
			s.Cap *= size
		{{- end }}

		src := *(*[]byte)(unsafe.Pointer(&s))
	{{- end }}
	w.ChainWrite(src)
}
