]> git.saurik.com Git - redis.git/blame - src/rio.c
changed license to gpl BSD. LOL
[redis.git] / src / rio.c
CommitLineData
2e4b0e77
PN
1#include <string.h>
2#include "rio.h"
3#include "util.h"
4
5/* Returns 1 or 0 for success/failure. */
6static size_t rioBufferWrite(rio *r, const void *buf, size_t len) {
7 r->io.buffer.ptr = sdscatlen(r->io.buffer.ptr,(char*)buf,len);
8 r->io.buffer.pos += len;
69cecb51 9 return 1;
2e4b0e77
PN
10}
11
12/* Returns 1 or 0 for success/failure. */
13static size_t rioBufferRead(rio *r, void *buf, size_t len) {
14 if (sdslen(r->io.buffer.ptr)-r->io.buffer.pos < len)
69cecb51 15 return 0; /* not enough buffer to return len bytes. */
2e4b0e77
PN
16 memcpy(buf,r->io.buffer.ptr+r->io.buffer.pos,len);
17 r->io.buffer.pos += len;
18 return 1;
19}
20
21/* Returns read/write position in buffer. */
22static off_t rioBufferTell(rio *r) {
23 return r->io.buffer.pos;
24}
25
26/* Returns 1 or 0 for success/failure. */
27static size_t rioFileWrite(rio *r, const void *buf, size_t len) {
28 return fwrite(buf,len,1,r->io.file.fp);
29}
30
31/* Returns 1 or 0 for success/failure. */
32static size_t rioFileRead(rio *r, void *buf, size_t len) {
33 return fread(buf,len,1,r->io.file.fp);
34}
35
36/* Returns read/write position in file. */
37static off_t rioFileTell(rio *r) {
38 return ftello(r->io.file.fp);
39}
40
41static const rio rioBufferIO = {
42 rioBufferRead,
43 rioBufferWrite,
44 rioBufferTell,
45 { { NULL, 0 } } /* union for io-specific vars */
46};
47
48static const rio rioFileIO = {
49 rioFileRead,
50 rioFileWrite,
51 rioFileTell,
52 { { NULL, 0 } } /* union for io-specific vars */
53};
54
f96a8a80 55void rioInitWithFile(rio *r, FILE *fp) {
56 *r = rioFileIO;
57 r->io.file.fp = fp;
2e4b0e77 58}
f96a8a80 59
60void rioInitWithBuffer(rio *r, sds s) {
61 *r = rioBufferIO;
62 r->io.buffer.ptr = s;
63 r->io.buffer.pos = 0;
2e4b0e77
PN
64}
65
66/* Write multi bulk count in the format: "*<count>\r\n". */
67size_t rioWriteBulkCount(rio *r, char prefix, int count) {
68 char cbuf[128];
69 int clen;
70
71 cbuf[0] = prefix;
72 clen = 1+ll2string(cbuf+1,sizeof(cbuf)-1,count);
73 cbuf[clen++] = '\r';
74 cbuf[clen++] = '\n';
75 if (rioWrite(r,cbuf,clen) == 0) return 0;
76 return clen;
77}
78
79/* Write binary-safe string in the format: "$<count>\r\n<payload>\r\n". */
80size_t rioWriteBulkString(rio *r, const char *buf, size_t len) {
81 size_t nwritten;
82
83 if ((nwritten = rioWriteBulkCount(r,'$',len)) == 0) return 0;
84 if (len > 0 && rioWrite(r,buf,len) == 0) return 0;
85 if (rioWrite(r,"\r\n",2) == 0) return 0;
86 return nwritten+len+2;
87}
88
89/* Write a long long value in format: "$<count>\r\n<payload>\r\n". */
90size_t rioWriteBulkLongLong(rio *r, long long l) {
91 char lbuf[32];
92 unsigned int llen;
93
94 llen = ll2string(lbuf,sizeof(lbuf),l);
95 return rioWriteBulkString(r,lbuf,llen);
96}
97
98/* Write a double value in the format: "$<count>\r\n<payload>\r\n" */
99size_t rioWriteBulkDouble(rio *r, double d) {
100 char dbuf[128];
101 unsigned int dlen;
102
103 dlen = snprintf(dbuf,sizeof(dbuf),"%.17g",d);
104 return rioWriteBulkString(r,dbuf,dlen);
105}