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, Listm 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)