view pkg/auth/encode.go @ 4169:91f4b3f56ce2

Moved binary session encoding/decoding into auth package as it is only used there.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 05 Aug 2019 16:24:40 +0200
parents pkg/misc/encode.go@5b9b8eabcd01
children 6270951dda28
line wrap: on
line source

// This is Free Software under GNU Affero General Public License v >= 3.0
// without warranty, see README.md and license for details.
//
// SPDX-License-Identifier: AGPL-3.0-or-later
// License-Filename: LICENSES/AGPL-3.0.txt
//
// Copyright (C) 2018 by via donau
//   – Österreichische Wasserstraßen-Gesellschaft mbH
// Software engineering by Intevation GmbH
//
// Author(s):
//  * Sascha L. Teichmann <sascha.teichmann@intevation.de>

package auth

import (
	"encoding/binary"
	"io"
)

// BinReader is a io.Reader to support an error tolerant way
// to read big endian encoded binary data.
type BinReader struct {
	io.Reader
	// Err is the first encountered error.
	Err error
}

// Read implements io.Reader without any endian awareness.
func (r *BinReader) Read(buf []byte) (int, error) {
	if r.Err != nil {
		return 0, r.Err
	}
	var n int
	n, r.Err = r.Read(buf)
	return n, r.Err
}

// ReadBin reads big endian encodes binary data into x.
// If an error was encountered before no data is read.
func (r *BinReader) ReadBin(x interface{}) {
	if r.Err == nil {
		r.Err = binary.Read(r.Reader, binary.BigEndian, x)
	}
}

// ReadString reads a big endian encoded string from
// the underlying io.Reader into *s.
// If an error was encountered before no data is read
// and *s is unmodified.
func (r *BinReader) ReadString(s *string) {
	if r.Err != nil {
		return
	}
	var l uint32
	if r.Err = binary.Read(r.Reader, binary.BigEndian, &l); r.Err != nil {
		return
	}
	b := make([]byte, l)
	if r.Err = binary.Read(r.Reader, binary.BigEndian, b); r.Err != nil {
		return
	}
	*s = string(b)
}

// BinWriter is a io.Writer to support an error tolerant way
// to write big endian encoded binary data.
type BinWriter struct {
	io.Writer
	// Err is the first encountered error.
	Err error
}

// Write implements io.Writer without any endian awareness.
func (w *BinWriter) Write(buf []byte) (int, error) {
	if w.Err != nil {
		return 0, w.Err
	}
	var n int
	n, w.Err = w.Writer.Write(buf)
	return n, w.Err
}

// WriteBin writes x big endian encoded to the underlying io.Writer.
// If an error was encountered before no data is written.
func (w *BinWriter) WriteBin(x interface{}) {
	if w.Err == nil {
		w.Err = binary.Write(w.Writer, binary.BigEndian, x)
	}
}

// WriteString writes a big endian encoded string to
// the underlying io.Writer.
// If an error was encountered before no data is written.
func (w *BinWriter) WriteString(s string) {
	if w.Err == nil {
		w.Err = binary.Write(w.Writer, binary.BigEndian, uint32(len(s)))
	}
	if w.Err == nil {
		w.Err = binary.Write(w.Writer, binary.BigEndian, []byte(s))
	}
}