]>
git.saurik.com Git - redis.git/blob - src/rio.c
bb977c740cc7a22272a02f4347e783402a4449d4
   1 /* rio.c is a simple stream-oriented I/O abstraction that provides an interface 
   2  * to write code that can consume/produce data using different concrete input 
   3  * and output devices. For instance the same rdb.c code using the rio abstraction 
   4  * can be used to read and write the RDB format using in-memory buffers or files. 
   6  * A rio object provides the following methods: 
   7  *  read: read from stream. 
   8  *  write: write to stream. 
   9  *  tell: get the current offset. 
  11  * It is also possible to set a 'checksum' method that is used by rio.c in order 
  12  * to compute a checksum of the data written or read, or to query the rio object 
  13  * for the current checksum. */ 
  21 /* Returns 1 or 0 for success/failure. */ 
  22 static size_t rioBufferWrite(rio 
*r
, const void *buf
, size_t len
) { 
  23     r
->io
.buffer
.ptr 
= sdscatlen(r
->io
.buffer
.ptr
,(char*)buf
,len
); 
  24     r
->io
.buffer
.pos 
+= len
; 
  28 /* Returns 1 or 0 for success/failure. */ 
  29 static size_t rioBufferRead(rio 
*r
, void *buf
, size_t len
) { 
  30     if (sdslen(r
->io
.buffer
.ptr
)-r
->io
.buffer
.pos 
< len
) 
  31         return 0; /* not enough buffer to return len bytes. */ 
  32     memcpy(buf
,r
->io
.buffer
.ptr
+r
->io
.buffer
.pos
,len
); 
  33     r
->io
.buffer
.pos 
+= len
; 
  37 /* Returns read/write position in buffer. */ 
  38 static off_t 
rioBufferTell(rio 
*r
) { 
  39     return r
->io
.buffer
.pos
; 
  42 /* Returns 1 or 0 for success/failure. */ 
  43 static size_t rioFileWrite(rio 
*r
, const void *buf
, size_t len
) { 
  44     return fwrite(buf
,len
,1,r
->io
.file
.fp
); 
  47 /* Returns 1 or 0 for success/failure. */ 
  48 static size_t rioFileRead(rio 
*r
, void *buf
, size_t len
) { 
  49     return fread(buf
,len
,1,r
->io
.file
.fp
); 
  52 /* Returns read/write position in file. */ 
  53 static off_t 
rioFileTell(rio 
*r
) { 
  54     return ftello(r
->io
.file
.fp
); 
  57 static const rio rioBufferIO 
= { 
  61     NULL
,           /* update_checksum */ 
  62     0,              /* current checksum */ 
  63     { { NULL
, 0 } } /* union for io-specific vars */ 
  66 static const rio rioFileIO 
= { 
  70     NULL
,           /* update_checksum */ 
  71     0,              /* current checksum */ 
  72     { { NULL
, 0 } } /* union for io-specific vars */ 
  75 void rioInitWithFile(rio 
*r
, FILE *fp
) { 
  80 void rioInitWithBuffer(rio 
*r
, sds s
) { 
  86 /* This function can be installed both in memory and file streams when checksum 
  87  * computation is needed. */ 
  88 void rioGenericUpdateChecksum(rio 
*r
, const void *buf
, size_t len
) { 
  89     r
->checksum 
= crc64(r
->checksum
,buf
,len
); 
  92 /* ------------------------------ Higher level interface --------------------------- 
  93  * The following higher level functions use lower level rio.c functions to help 
  94  * generating the Redis protocol for the Append Only File. */ 
  96 /* Write multi bulk count in the format: "*<count>\r\n". */ 
  97 size_t rioWriteBulkCount(rio 
*r
, char prefix
, int count
) { 
 102     clen 
= 1+ll2string(cbuf
+1,sizeof(cbuf
)-1,count
); 
 105     if (rioWrite(r
,cbuf
,clen
) == 0) return 0; 
 109 /* Write binary-safe string in the format: "$<count>\r\n<payload>\r\n". */ 
 110 size_t rioWriteBulkString(rio 
*r
, const char *buf
, size_t len
) { 
 113     if ((nwritten 
= rioWriteBulkCount(r
,'$',len
)) == 0) return 0; 
 114     if (len 
> 0 && rioWrite(r
,buf
,len
) == 0) return 0; 
 115     if (rioWrite(r
,"\r\n",2) == 0) return 0; 
 116     return nwritten
+len
+2; 
 119 /* Write a long long value in format: "$<count>\r\n<payload>\r\n". */ 
 120 size_t rioWriteBulkLongLong(rio 
*r
, long long l
) { 
 124     llen 
= ll2string(lbuf
,sizeof(lbuf
),l
); 
 125     return rioWriteBulkString(r
,lbuf
,llen
); 
 128 /* Write a double value in the format: "$<count>\r\n<payload>\r\n" */ 
 129 size_t rioWriteBulkDouble(rio 
*r
, double d
) { 
 133     dlen 
= snprintf(dbuf
,sizeof(dbuf
),"%.17g",d
); 
 134     return rioWriteBulkString(r
,dbuf
,dlen
);