107 lines
3.8 KiB
Kotlin
107 lines
3.8 KiB
Kotlin
package net.sergeych.bipack
|
|
|
|
import kotlinx.serialization.SerialInfo
|
|
|
|
/**
|
|
* To be used with [kotlinx.serialization.Serializable]. Allows serialized classes to be
|
|
* extended by _adding members with default initializers_ __to the end of the constructor list__.
|
|
*
|
|
* This annotation makes Bipack to insert fields count before the
|
|
* serialized data. It then checks it on deserializing to fill not serialized fields will
|
|
* default values.
|
|
*
|
|
* Note that since 0.0.7 the same behavior could be achieved by serializing each instance in the
|
|
* array as Bipack correctly processes end-of-data by filling missing fields with default values,
|
|
* using `Extendable` is more convenient and save some space, most of the time.
|
|
*
|
|
* _Please note that without this annotation it could be impossible to deserialize old versions of
|
|
* the class, in particular, in array, inner fields, etc._
|
|
*/
|
|
@Target(AnnotationTarget.CLASS)
|
|
@SerialInfo
|
|
annotation class Extendable
|
|
|
|
|
|
/**
|
|
* Serializable classes annotated as Framed will have leading checked mark as CRC32
|
|
* of its name (uses `@SerialName` internally). On deserializing, if frame will not
|
|
* match the expected name, the [InvalidFrameException] will be thrown.
|
|
*/
|
|
@SerialInfo
|
|
annotation class Framed
|
|
|
|
/**
|
|
* Allow to CRC-protect structures (we suppose to use it with classes only). After the
|
|
* data block its CRC32 will be written and checked. It is memory-wise: it calculates CRC
|
|
* on the fly without buffering the data. If used with [Framed] and [Extendable] the extra
|
|
* data is protected too.
|
|
*
|
|
* __Common pitfalls__. When unpacking corrupted data protected this way, the not only [InvalidFrameCRCException]
|
|
* can be thrown. Actually, most often you will see [DataSource.EndOfData] exception
|
|
*/
|
|
@SerialInfo
|
|
annotation class CrcProtected
|
|
|
|
/**
|
|
* Allow marking data fields as being serialized as unsigned (applicable also to signed fields lite Int, Long and
|
|
* Short, if you are sure they will not be negative). As unsigned types are not cully supported by `kotlinx.serialization`
|
|
* it is the only way to tell the serialized to use more compact unsigned variable length encoding.
|
|
*/
|
|
@SerialInfo
|
|
@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY)
|
|
annotation class Unsigned
|
|
|
|
/**
|
|
* Fixed size collection of a given size. __Use it only with collections!__
|
|
*
|
|
* Use it with collection of fixed size, to read/write exact number of items (for example, bytes),
|
|
* like hash digest, key bits and so on. Does not store/load the collection
|
|
* size what reduces packed size to at least one byte. depending on the actual
|
|
* collection size. As for nowonly collection types (e.g. ByteArray, List<T>m etc) are supported.
|
|
* Note that if the actual collection size differs from [size], [BipackEncoder] will throw
|
|
* [WrongCollectionSize] while encoding it. For example:
|
|
*
|
|
* ~~~
|
|
* @Serializable
|
|
* class Foo(
|
|
* @FixedSize(32)
|
|
* thirtyTwoBytes: ByteArray
|
|
* )
|
|
*/
|
|
@SerialInfo
|
|
@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY)
|
|
annotation class FixedSize(val size: Int)
|
|
|
|
/**
|
|
* Fixed-size number, big-endian. Could be used only with field of following types:
|
|
*
|
|
* - Int, UInt: 4 bytes
|
|
* - Short, UShort: 2 bytes
|
|
* - Long, ULong: 8 bytes.
|
|
*
|
|
* It should not be used with Byte or UByte as their size is always 1 byte ;)
|
|
*
|
|
* Example:
|
|
* ~~~
|
|
* @Serializable
|
|
* class Foo(
|
|
* @Fixed
|
|
* val eightBytesLongInt: Long
|
|
* )
|
|
*
|
|
* // so:
|
|
* assertEquals("00 00 00 01 00 00 00 02", BipackEncoder.encode(Foo(0x100000002)).encodeToHex())
|
|
* ~~~
|
|
*/
|
|
@SerialInfo
|
|
@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY)
|
|
annotation class Fixed
|
|
|
|
open class InvalidFrameException(reason: String) : Exception(reason)
|
|
class InvalidFrameHeaderException(reason: String = "Frame header does not match") : InvalidFrameException(reason)
|
|
class InvalidFrameCRCException : InvalidFrameException("Checksum CRC32 failed")
|
|
|
|
class WrongCollectionSize(reason: String) : Exception(reason)
|
|
|
|
|