diff options
Diffstat (limited to 'librsync/librsync.go')
-rw-r--r-- | librsync/librsync.go | 58 |
1 files changed, 52 insertions, 6 deletions
diff --git a/librsync/librsync.go b/librsync/librsync.go index 641e480..1ffc7ec 100644 --- a/librsync/librsync.go +++ b/librsync/librsync.go @@ -6,6 +6,7 @@ package librsync #include <stdio.h> #include <librsync.h> #include <stdlib.h> +#include <stdbool.h> static inline rs_buffers_t* new_rs_buffers() { return (rs_buffers_t*) malloc(sizeof(rs_buffers_t)); @@ -17,6 +18,27 @@ rs_result patchCallback(void* _patcher, rs_long_t pos, size_t* len, void** _buf) return patchCallbackGo(_patcher, pos, len, _buf); } +#ifndef RS_DEFAULT_STRONG_LEN +// librsync >= 1.0.0, 0 is the full size (32 bytes) +#define DEFAULT_STRONG_LEN 0 +#else +// librsync < 1.0.0, using md4 (8 bytes) +#define DEFAULT_STRONG_LEN RS_DEFAULT_STRONG_LEN +#endif + +static inline rs_job_t* sig_begin(size_t new_block_len, size_t strong_sum_len, bool compat) { +#ifndef RS_DEFAULT_STRONG_LEN + // librsync >= 1.0.0, supporting the newer hash function (blake2b) + if (compat) { + return rs_sig_begin(new_block_len, strong_sum_len, RS_MD4_SIG_MAGIC); + } + return rs_sig_begin(new_block_len, strong_sum_len, RS_BLAKE2_SIG_MAGIC); +#else + // not supporting the newer hash function, fall back to the md4 hash + return rs_sig_begin(new_block_len, strong_sum_len); +#endif +} + */ import "C" @@ -32,6 +54,11 @@ const ( outbufSize = 16 * 1024 ) +const ( + DefaultBlockLen = C.RS_DEFAULT_BLOCK_LEN + DefaultStrongLen = C.DEFAULT_STRONG_LEN +) + var ( ErrInputEnded = errors.New("Input ended (possibly unexpected)") ErrBadMagic = errors.New("Bad magic number. Probably not an librsync file.") @@ -74,24 +101,43 @@ func newJob(input io.Reader) (job *Job, err error) { return } -// NewDefaultSignatureGen is like NewSignatureGen, but uses default values for blocklen and stronglen. +// Config sets parameters for NewSignatureGen. May be the zero value for default +// values. +type Config struct { + BlockLen uint // length of a block, e.g. 2048 + StrongLen uint // length of a strong hash, e.g. 32 or 0 + CompatMD4 bool // enable for compatibility with librsync < 1.0.0 +} + +func (c *Config) setup() { + if c.BlockLen == 0 { + c.BlockLen = DefaultBlockLen + } + if c.StrongLen == 0 { + c.StrongLen = DefaultStrongLen + } +} + +// NewDefaultSignatureGen is like NewSignatureGen, but uses the default +// configuration. func NewDefaultSignatureGen(basis io.Reader) (job *Job, err error) { - job, err = NewSignatureGen(C.RS_DEFAULT_BLOCK_LEN, C.RS_DEFAULT_STRONG_LEN, basis) + job, err = NewSignatureGen(Config{}, basis) return } // NewSignatureGen creates a signature generation job. // -// blocklen is the length of a block. -// stronglen is the length of the stong hash. +// config is a Config object for more options. // basis is an io.Reader that provides data of the basis file. -func NewSignatureGen(blocklen, stronglen uint, basis io.Reader) (job *Job, err error) { +func NewSignatureGen(config Config, basis io.Reader) (job *Job, err error) { job, err = newJob(basis) if err != nil { return } - job.job = C.rs_sig_begin(C.size_t(blocklen), C.size_t(stronglen)) + config.setup() + + job.job = C.sig_begin(C.size_t(config.BlockLen), C.size_t(config.StrongLen), C.bool(config.CompatMD4)) if job.job == nil { job.Close() return nil, errors.New("rs_sig_begin failed") |