1 | /* |
2 | * Copyright (c) 2009-2011, Salvatore Sanfilippo <antirez at gmail dot com> |
3 | * Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com> |
4 | * |
5 | * All rights reserved. |
6 | * |
7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions are met: |
9 | * |
10 | * * Redistributions of source code must retain the above copyright notice, |
11 | * this list of conditions and the following disclaimer. |
12 | * * Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. |
15 | * * Neither the name of Redis nor the names of its contributors may be used |
16 | * to endorse or promote products derived from this software without |
17 | * specific prior written permission. |
18 | * |
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | * POSSIBILITY OF SUCH DAMAGE. |
30 | */ |
31 | |
32 | |
33 | #ifndef __HIREDIS_READ_H |
34 | #define __HIREDIS_READ_H |
35 | #include <stdio.h> /* for size_t */ |
36 | |
37 | #define REDIS_ERR -1 |
38 | #define REDIS_OK 0 |
39 | |
40 | /* When an error occurs, the err flag in a context is set to hold the type of |
41 | * error that occurred. REDIS_ERR_IO means there was an I/O error and you |
42 | * should use the "errno" variable to find out what is wrong. |
43 | * For other values, the "errstr" field will hold a description. */ |
44 | #define REDIS_ERR_IO 1 /* Error in read or write */ |
45 | #define REDIS_ERR_EOF 3 /* End of file */ |
46 | #define REDIS_ERR_PROTOCOL 4 /* Protocol error */ |
47 | #define REDIS_ERR_OOM 5 /* Out of memory */ |
48 | #define REDIS_ERR_TIMEOUT 6 /* Timed out */ |
49 | #define REDIS_ERR_OTHER 2 /* Everything else... */ |
50 | |
51 | #define REDIS_REPLY_STRING 1 |
52 | #define REDIS_REPLY_ARRAY 2 |
53 | #define REDIS_REPLY_INTEGER 3 |
54 | #define REDIS_REPLY_NIL 4 |
55 | #define REDIS_REPLY_STATUS 5 |
56 | #define REDIS_REPLY_ERROR 6 |
57 | #define REDIS_REPLY_DOUBLE 7 |
58 | #define REDIS_REPLY_BOOL 8 |
59 | #define REDIS_REPLY_MAP 9 |
60 | #define REDIS_REPLY_SET 10 |
61 | #define REDIS_REPLY_ATTR 11 |
62 | #define REDIS_REPLY_PUSH 12 |
63 | #define REDIS_REPLY_BIGNUM 13 |
64 | #define REDIS_REPLY_VERB 14 |
65 | |
66 | /* Default max unused reader buffer. */ |
67 | #define REDIS_READER_MAX_BUF (1024*16) |
68 | |
69 | /* Default multi-bulk element limit */ |
70 | #define REDIS_READER_MAX_ARRAY_ELEMENTS ((1LL<<32) - 1) |
71 | |
72 | #ifdef __cplusplus |
73 | extern "C" { |
74 | #endif |
75 | |
76 | typedef struct redisReadTask { |
77 | int type; |
78 | long long elements; /* number of elements in multibulk container */ |
79 | int idx; /* index in parent (array) object */ |
80 | void *obj; /* holds user-generated value for a read task */ |
81 | struct redisReadTask *parent; /* parent task */ |
82 | void *privdata; /* user-settable arbitrary field */ |
83 | } redisReadTask; |
84 | |
85 | typedef struct redisReplyObjectFunctions { |
86 | void *(*createString)(const redisReadTask*, char*, size_t); |
87 | void *(*createArray)(const redisReadTask*, size_t); |
88 | void *(*createInteger)(const redisReadTask*, long long); |
89 | void *(*createDouble)(const redisReadTask*, double, char*, size_t); |
90 | void *(*createNil)(const redisReadTask*); |
91 | void *(*createBool)(const redisReadTask*, int); |
92 | void (*freeObject)(void*); |
93 | } redisReplyObjectFunctions; |
94 | |
95 | typedef struct redisReader { |
96 | int err; /* Error flags, 0 when there is no error */ |
97 | char errstr[128]; /* String representation of error when applicable */ |
98 | |
99 | char *buf; /* Read buffer */ |
100 | size_t pos; /* Buffer cursor */ |
101 | size_t len; /* Buffer length */ |
102 | size_t maxbuf; /* Max length of unused buffer */ |
103 | long long maxelements; /* Max multi-bulk elements */ |
104 | |
105 | redisReadTask **task; |
106 | int tasks; |
107 | |
108 | int ridx; /* Index of current read task */ |
109 | void *reply; /* Temporary reply pointer */ |
110 | |
111 | redisReplyObjectFunctions *fn; |
112 | void *privdata; |
113 | } redisReader; |
114 | |
115 | /* Public API for the protocol parser. */ |
116 | redisReader *redisReaderCreateWithFunctions(redisReplyObjectFunctions *fn); |
117 | void redisReaderFree(redisReader *r); |
118 | int redisReaderFeed(redisReader *r, const char *buf, size_t len); |
119 | int redisReaderGetReply(redisReader *r, void **reply); |
120 | |
121 | #define redisReaderSetPrivdata(_r, _p) (int)(((redisReader*)(_r))->privdata = (_p)) |
122 | #define redisReaderGetObject(_r) (((redisReader*)(_r))->reply) |
123 | #define redisReaderGetError(_r) (((redisReader*)(_r))->errstr) |
124 | |
125 | #ifdef __cplusplus |
126 | } |
127 | #endif |
128 | |
129 | #endif |
130 | |