Skip to content

Commit

Permalink
Rename Write and Read methods, introduce ReadBytes to enable readin…
Browse files Browse the repository at this point in the history
…g a byte slice by length and `ReadObjectFromReader` to enable reading objects without prepending the size
  • Loading branch information
jonastheis committed Oct 31, 2023
1 parent ba12012 commit a5ebefe
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 31 deletions.
51 changes: 31 additions & 20 deletions serializer/stream/read.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,38 +14,38 @@ func Read[T allowedGenericTypes](reader io.Reader) (result T, err error) {
return result, binary.Read(reader, binary.LittleEndian, &result)
}

// ReadByteSlice reads a byte slice from the reader where lenType specifies the serialization length prefix type.
func ReadByteSlice(reader io.Reader, lenType serializer.SeriLengthPrefixType) ([]byte, error) {
size, err := readFixedSize(reader, lenType)
if err != nil {
return nil, ierrors.Wrap(err, "failed to read blob size")
}

readBytes := make([]byte, size)
func ReadBytes(reader io.Reader, len int) ([]byte, error) {
readBytes := make([]byte, len)

nBytes, err := reader.Read(readBytes)
if err != nil {
return nil, ierrors.Wrap(err, "failed to read serialized bytes")
}
if nBytes != size {
return nil, ierrors.Errorf("failed to read serialized bytes: read bytes (%d) != size (%d)", nBytes, size)
if nBytes != len {
return nil, ierrors.Errorf("failed to read serialized bytes: read bytes (%d) != size (%d)", nBytes, len)
}

return readBytes, nil
}

// ReadFixedSizeObject reads a type from the reader as specified by objectFromBytesFunc. A fixed length for the deserialized type must be specified.
func ReadFixedSizeObject[T any](reader io.Reader, fixedLen int, objectFromBytesFunc func(bytes []byte) (T, int, error)) (T, error) {
// ReadBytesWithSize reads a byte slice from the reader where lenType specifies the serialization length prefix type.
func ReadBytesWithSize(reader io.Reader, lenType serializer.SeriLengthPrefixType) ([]byte, error) {
size, err := readFixedSize(reader, lenType)
if err != nil {
return nil, ierrors.Wrap(err, "failed to read blob size")
}

return ReadBytes(reader, size)
}

// ReadObject reads a type from the reader as specified by objectFromBytesFunc. A fixed length for the deserialized type must be specified.
func ReadObject[T any](reader io.Reader, fixedLen int, objectFromBytesFunc func(bytes []byte) (T, int, error)) (T, error) {
var result T
readBytes := make([]byte, fixedLen)

nBytes, err := reader.Read(readBytes)
readBytes, err := ReadBytes(reader, fixedLen)
if err != nil {
return result, ierrors.Wrap(err, "failed to read serialized bytes")
}
if nBytes != fixedLen {
return result, ierrors.Errorf("failed to read serialized bytes: read bytes (%d) != fixed size (%d)", nBytes, fixedLen)
}

result, consumedBytes, err := objectFromBytesFunc(readBytes)
if err != nil {
Expand All @@ -58,11 +58,11 @@ func ReadFixedSizeObject[T any](reader io.Reader, fixedLen int, objectFromBytesF
return result, nil
}

// ReadObject reads a type from the reader as specified by fromBytesFunc. The serialization length prefix type must be specified.
func ReadObject[T any](reader io.Reader, lenType serializer.SeriLengthPrefixType, objectFromBytesFunc func(bytes []byte) (T, int, error)) (T, error) {
// ReadObjectWithSize reads a type from the reader as specified by fromBytesFunc. The serialization length prefix type must be specified.
func ReadObjectWithSize[T any](reader io.Reader, lenType serializer.SeriLengthPrefixType, objectFromBytesFunc func(bytes []byte) (T, int, error)) (T, error) {
var result T

readBytes, err := ReadByteSlice(reader, lenType)
readBytes, err := ReadBytesWithSize(reader, lenType)
if err != nil {
return result, ierrors.Wrap(err, "failed to read serialized bytes")
}
Expand All @@ -78,6 +78,17 @@ func ReadObject[T any](reader io.Reader, lenType serializer.SeriLengthPrefixType
return result, nil
}

func ReadObjectFromReader[T any](reader io.Reader, objectFromReaderFunc func(reader io.Reader) (T, error)) (T, error) {
var result T

result, err := objectFromReaderFunc(reader)
if err != nil {
return result, ierrors.Wrap(err, "failed to read object from reader")
}

return result, nil
}

func PeekCollectionSize(reader io.ReadSeeker, lenType serializer.SeriLengthPrefixType) (int, error) {
startOffset, err := Offset(reader)
if err != nil {
Expand Down
18 changes: 7 additions & 11 deletions serializer/stream/write.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ func WriteBytes(writer io.Writer, bytes []byte) error {
return lo.Return2(writer.Write(bytes))
}

// WriteByteSlice writes bytes to the writer where lenType specifies the serialization length prefix type.
func WriteByteSlice(writer io.Writer, bytes []byte, lenType serializer.SeriLengthPrefixType) error {
// WriteBytesWithSize writes bytes to the writer where lenType specifies the serialization length prefix type.
func WriteBytesWithSize(writer io.Writer, bytes []byte, lenType serializer.SeriLengthPrefixType) error {
if err := writeFixedSize(writer, len(bytes), lenType); err != nil {
return ierrors.Wrap(err, "failed to write bytes length")
}
Expand All @@ -33,32 +33,28 @@ func WriteByteSlice(writer io.Writer, bytes []byte, lenType serializer.SeriLengt
return nil
}

// WriteFixedSizeObject writes a type to the writer as specified by the objectToBytesFunc. A fixed length for the serialized type must be specified.
func WriteFixedSizeObject[T any](writer io.Writer, target T, fixedLen int, objectToBytesFunc func(T) ([]byte, error)) error {
// WriteObject writes a type to the writer as specified by the objectToBytesFunc.
func WriteObject[T any](writer io.Writer, target T, objectToBytesFunc func(T) ([]byte, error)) error {
serializedBytes, err := objectToBytesFunc(target)
if err != nil {
return ierrors.Wrap(err, "failed to serialize target")
}

if fixedLen != len(serializedBytes) {
return ierrors.Errorf("serialized bytes length (%d) != fixed size (%d)", len(serializedBytes), fixedLen)
}

if _, err = writer.Write(serializedBytes); err != nil {
return ierrors.Wrap(err, "failed to write target")
}

return nil
}

// WriteObject writes an object to the writer as specified by the objectToBytesFunc. The serialization length prefix type must be specified.
func WriteObject[T any](writer io.Writer, target T, lenType serializer.SeriLengthPrefixType, objectToBytesFunc func(T) ([]byte, error)) error {
// WriteObjectWithSize writes an object to the writer as specified by the objectToBytesFunc. The serialization length prefix type must be specified.
func WriteObjectWithSize[T any](writer io.Writer, target T, lenType serializer.SeriLengthPrefixType, objectToBytesFunc func(T) ([]byte, error)) error {
serializedBytes, err := objectToBytesFunc(target)
if err != nil {
return ierrors.Wrap(err, "failed to serialize object")
}

if err = WriteByteSlice(writer, serializedBytes, lenType); err != nil {
if err = WriteBytesWithSize(writer, serializedBytes, lenType); err != nil {
return ierrors.Wrap(err, "failed to write serialized bytes")
}

Expand Down

0 comments on commit a5ebefe

Please sign in to comment.