001// Copyright (c) FIRST and other WPILib contributors.
002// Open Source Software; you can modify and/or share it under the terms of
003// the WPILib BSD license file in the root directory of this project.
004
005package edu.wpi.first.util.struct;
006
007import java.nio.ByteBuffer;
008
009/**
010 * Interface for raw struct serialization.
011 *
012 * <p>This is designed for serializing small fixed-size data structures in the fastest and most
013 * compact means possible. Serialization consists of making relative put() calls to a ByteBuffer and
014 * deserialization consists of making relative get() calls from a ByteBuffer.
015 *
016 * <p>Idiomatically, classes that support raw struct serialization should provide a static final
017 * member named "struct" that provides an instance of an implementation of this interface.
018 *
019 * @param <T> object type
020 */
021public interface Struct<T> {
022  /** Serialized size of a "bool" value. */
023  int kSizeBool = 1;
024
025  /** Serialized size of an "int8" or "uint8" value. */
026  int kSizeInt8 = 1;
027
028  /** Serialized size of an "int16" or "uint16" value. */
029  int kSizeInt16 = 2;
030
031  /** Serialized size of an "int32" or "uint32" value. */
032  int kSizeInt32 = 4;
033
034  /** Serialized size of an "int64" or "uint64" value. */
035  int kSizeInt64 = 8;
036
037  /** Serialized size of an "float" or "float32" value. */
038  int kSizeFloat = 4;
039
040  /** Serialized size of an "double" or "float64" value. */
041  int kSizeDouble = 8;
042
043  /**
044   * Gets the Class object for the stored value.
045   *
046   * @return Class
047   */
048  Class<T> getTypeClass();
049
050  /**
051   * Gets the type string (e.g. for NetworkTables). This should be globally unique and start with
052   * "struct:".
053   *
054   * @return type string
055   */
056  String getTypeString();
057
058  /**
059   * Gets the serialized size (in bytes). This should always be a constant.
060   *
061   * @return serialized size
062   */
063  int getSize();
064
065  /**
066   * Gets the schema.
067   *
068   * @return schema
069   */
070  String getSchema();
071
072  /**
073   * Gets the list of struct types referenced by this struct.
074   *
075   * @return list of struct types
076   */
077  default Struct<?>[] getNested() {
078    return new Struct<?>[] {};
079  }
080
081  /**
082   * Deserializes an object from a raw struct serialized ByteBuffer starting at the current
083   * position. Will increment the ByteBuffer position by getStructSize() bytes. Will not otherwise
084   * modify the ByteBuffer (e.g. byte order will not be changed).
085   *
086   * @param bb ByteBuffer
087   * @return New object
088   */
089  T unpack(ByteBuffer bb);
090
091  /**
092   * Puts object contents to a ByteBuffer starting at the current position. Will increment the
093   * ByteBuffer position by getStructSize() bytes. Will not otherwise modify the ByteBuffer (e.g.
094   * byte order will not be changed).
095   *
096   * @param bb ByteBuffer
097   * @param value object to serialize
098   */
099  void pack(ByteBuffer bb, T value);
100
101  /**
102   * Updates object contents from a raw struct serialized ByteBuffer starting at the current
103   * position. Will increment the ByteBuffer position by getStructSize() bytes. Will not otherwise
104   * modify the ByteBuffer (e.g. byte order will not be changed).
105   *
106   * <p>Immutable classes cannot and should not implement this function. The default implementation
107   * throws UnsupportedOperationException.
108   *
109   * @param out object to update
110   * @param bb ByteBuffer
111   * @throws UnsupportedOperationException if the object is immutable
112   */
113  default void unpackInto(T out, ByteBuffer bb) {
114    throw new UnsupportedOperationException("object does not support unpackInto");
115  }
116}