view pkg/mesh/meshserialize.go @ 5679:03dfbe675842 sr-v2

Simplified version handling.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Sun, 11 Feb 2024 12:37:09 +0100
parents 4abbb62d2bed
children a87900c0fd11
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 mesh

import (
	"bufio"
	"bytes"
	"compress/gzip"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
)

const Version = 1

const magicHeader = "SR3D"

func coalesceVersion(version int) int {
	if version > 0 {
		return version
	}
	return Version
}

func (s *STRTree) OptimizeForSerialization(version int) {
	version = coalesceVersion(version)
	// TODO: Implement me!
	_ = version
}

// Bytes serializes this tree to a byte slice.
func (s *STRTree) Bytes(version int) ([]byte, int, error) {

	var buf bytes.Buffer
	w, err := gzip.NewWriterLevel(&buf, gzip.BestSpeed)
	if err != nil {
		return nil, 0, err
	}

	version = coalesceVersion(version)

	if err := s.serializeVn(w, version); err != nil {
		return nil, 0, err
	}

	if err := w.Close(); err != nil {
		return nil, 0, err
	}

	return buf.Bytes(), version, nil
}

func (s *STRTree) serializeVn(w io.Writer, version int) error {

	if version > Version {
		return fmt.Errorf(
			"cannot serialize mesh version %d. Highest supported version %d",
			version, Version)
	}

	return s.serializeV1(w)
}

// FromBytes restores a STRTree from a binary representation.
func (s *STRTree) FromBytes(data []byte, version int) error {

	version = coalesceVersion(version)

	if version > Version {
		return fmt.Errorf(
			"cannot deserialize mesh version %d. Highest supported version %d",
			version, Version)
	}

	r, err := gzip.NewReader(bytes.NewReader(data))
	if err != nil {
		return err
	}
	return s.deserialize(bufio.NewReader(r), version)
}

func (s *STRTree) deserialize(r *bufio.Reader, version int) error {

	header, err := r.Peek(8)
	if err != nil {
		return err
	}

	if bytes.HasPrefix(header, []byte(magicHeader)) {
		realVersion := int(binary.LittleEndian.Uint32(header[4:]))
		if realVersion != version {
			return fmt.Errorf("sounding result version mismatch: Have %d expect %d",
				realVersion, version)
		}
		return s.deserializeVn(r, realVersion)
	}

	return s.deserializeV1(r)
}

func (s *STRTree) deserializeVn(r *bufio.Reader, version int) error {
	if version == 1 {
		return s.deserializeV1(r)
	}
	// TODO: Implement me!
	return errors.New("not implemented, yet")
}