github.com/consensys/gnark@v0.11.0/internal/backend/ioutils/intcomp.go (about) 1 package ioutils 2 3 import ( 4 "encoding/binary" 5 "io" 6 7 "github.com/ronanh/intcomp" 8 ) 9 10 // CompressAndWriteUints32 compresses a slice of uint32 and writes it to w. 11 // It returns the input buffer (possibly extended) for future use. 12 func CompressAndWriteUints32(w io.Writer, input []uint32, buffer []uint32) ([]uint32, error) { 13 buffer = buffer[:0] 14 buffer = intcomp.CompressUint32(input, buffer) 15 if err := binary.Write(w, binary.LittleEndian, uint64(len(buffer))); err != nil { 16 return nil, err 17 } 18 if err := binary.Write(w, binary.LittleEndian, buffer); err != nil { 19 return nil, err 20 } 21 return buffer, nil 22 } 23 24 // CompressAndWriteUints64 compresses a slice of uint64 and writes it to w. 25 // It returns the input buffer (possibly extended) for future use. 26 func CompressAndWriteUints64(w io.Writer, input []uint64) error { 27 buffer := intcomp.CompressUint64(input, nil) 28 if err := binary.Write(w, binary.LittleEndian, uint64(len(buffer))); err != nil { 29 return err 30 } 31 return binary.Write(w, binary.LittleEndian, buffer) 32 } 33 34 // ReadAndDecompressUints32 reads a compressed slice of uint32 from r and decompresses it. 35 // It returns the number of bytes read, the decompressed slice and an error. 36 func ReadAndDecompressUints32(in []byte, buf32 []uint32) (outbuf32 []uint32, read int, out []uint32, err error) { 37 if len(in) < 8 { 38 return buf32, 0, nil, io.ErrUnexpectedEOF 39 } 40 length := binary.LittleEndian.Uint64(in[:8]) 41 if uint64(len(in)) < 8+4*length { 42 return buf32, 0, nil, io.ErrUnexpectedEOF 43 } 44 in = in[8 : 8+4*length] 45 if cap(buf32) < int(length) { 46 buf32 = make([]uint32, length) 47 } else { 48 buf32 = buf32[:length] 49 } 50 51 for i := 0; i < int(length); i++ { 52 buf32[i] = binary.LittleEndian.Uint32(in[4*i : 4*(i+1)]) 53 } 54 55 return buf32, 8 + 4*int(length), intcomp.UncompressUint32(buf32, nil), nil 56 } 57 58 // ReadAndDecompressUints64 reads a compressed slice of uint64 from r and decompresses it. 59 // It returns the number of bytes read, the decompressed slice and an error. 60 func ReadAndDecompressUints64(in []byte) (int, []uint64, error) { 61 if len(in) < 8 { 62 return 0, nil, io.ErrUnexpectedEOF 63 } 64 length := binary.LittleEndian.Uint64(in[:8]) 65 if uint64(len(in)) < 8+8*length { 66 return 0, nil, io.ErrUnexpectedEOF 67 } 68 in = in[8 : 8+8*length] 69 buffer := make([]uint64, length) 70 for i := 0; i < int(length); i++ { 71 buffer[i] = binary.LittleEndian.Uint64(in[8*i : 8*(i+1)]) 72 } 73 return 8 + 8*int(length), intcomp.UncompressUint64(buffer, nil), nil 74 }