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