X-Git-Url: https://git.saurik.com/redis.git/blobdiff_plain/69cecb511fef03795e94ba819308262ea44b2a18..7c5d96d98e6cc2a0e7ea5ea30e3ca4772a84b3cb:/src/rio.c?ds=sidebyside diff --git a/src/rio.c b/src/rio.c index ebe24a3d..44165d71 100644 --- a/src/rio.c +++ b/src/rio.c @@ -1,7 +1,25 @@ +/* rio.c is a simple stream-oriented I/O abstraction that provides an interface + * to write code that can consume/produce data using different concrete input + * and output devices. For instance the same rdb.c code using the rio abstraction + * can be used to read and write the RDB format using in-memory buffers or files. + * + * A rio object provides the following methods: + * read: read from stream. + * write: write to stream. + * tell: get the current offset. + * + * It is also possible to set a 'checksum' method that is used by rio.c in order + * to compute a checksum of the data written or read, or to query the rio object + * for the current checksum. */ + +#include "fmacros.h" #include +#include #include "rio.h" #include "util.h" +uint64_t crc64(uint64_t crc, const unsigned char *s, uint64_t l); + /* Returns 1 or 0 for success/failure. */ static size_t rioBufferWrite(rio *r, const void *buf, size_t len) { r->io.buffer.ptr = sdscatlen(r->io.buffer.ptr,(char*)buf,len); @@ -42,6 +60,8 @@ static const rio rioBufferIO = { rioBufferRead, rioBufferWrite, rioBufferTell, + NULL, /* update_checksum */ + 0, /* current checksum */ { { NULL, 0 } } /* union for io-specific vars */ }; @@ -49,21 +69,32 @@ static const rio rioFileIO = { rioFileRead, rioFileWrite, rioFileTell, + NULL, /* update_checksum */ + 0, /* current checksum */ { { NULL, 0 } } /* union for io-specific vars */ }; -rio rioInitWithFile(FILE *fp) { - rio r = rioFileIO; - r.io.file.fp = fp; - return r; +void rioInitWithFile(rio *r, FILE *fp) { + *r = rioFileIO; + r->io.file.fp = fp; } -rio rioInitWithBuffer(sds s) { - rio r = rioBufferIO; - r.io.buffer.ptr = s; - r.io.buffer.pos = 0; - return r; + +void rioInitWithBuffer(rio *r, sds s) { + *r = rioBufferIO; + r->io.buffer.ptr = s; + r->io.buffer.pos = 0; } +/* This function can be installed both in memory and file streams when checksum + * computation is needed. */ +void rioGenericUpdateChecksum(rio *r, const void *buf, size_t len) { + r->cksum = crc64(r->cksum,buf,len); +} + +/* ------------------------------ Higher level interface --------------------------- + * The following higher level functions use lower level rio.c functions to help + * generating the Redis protocol for the Append Only File. */ + /* Write multi bulk count in the format: "*\r\n". */ size_t rioWriteBulkCount(rio *r, char prefix, int count) { char cbuf[128];