Update protocol due to review comments:
[m6w6/libmemcached] / libmemcached / protocol / common.h
1 /* -*- Mode: C; tab-width: 2; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2 #ifndef LIBMEMCACHED_PROTOCOL_COMMON_H
3 #define LIBMEMCACHED_PROTOCOL_COMMON_H
4
5 #include "config.h"
6 #include <stdbool.h>
7 #include <assert.h>
8 #include <netinet/in.h>
9
10 /* Define this here, which will turn on the visibilty controls while we're
11 * building libmemcached.
12 */
13 #define BUILDING_LIBMEMCACHED 1
14
15 #include <libmemcached/byteorder.h>
16 #include <libmemcached/protocol_handler.h>
17 #include <libmemcached/protocol/cache.h>
18
19 /*
20 * I don't really need the following two functions as function pointers
21 * in the instance handle, but I don't want to put them in the global
22 * namespace for those linking statically (personally I don't like that,
23 * but some people still do). If it ever shows up as a performance thing
24 * I'll look into optimizing this ;-)
25 */
26 typedef bool (*drain_func)(memcached_protocol_client_st *client);
27 typedef protocol_binary_response_status (*spool_func)(memcached_protocol_client_st *client,
28 const void *data,
29 size_t length);
30
31 /**
32 * Definition of the per instance structure.
33 */
34 struct memcached_protocol_st {
35 memcached_binary_protocol_callback_st *callback;
36 memcached_protocol_recv_func recv;
37 memcached_protocol_send_func send;
38
39 /*
40 * I really don't need these as funciton pointers, but I don't want
41 * to clutter the namespace if someone links statically.
42 */
43 drain_func drain;
44 spool_func spool;
45
46 /*
47 * To avoid keeping a buffer in each client all the time I have a
48 * bigger buffer in the instance that I read to initially, and then
49 * I try to parse and execute as much from the buffer. If I wasn't able
50 * to process all data I'll keep that in a per-connection buffer until
51 * the next time I can read from the socket.
52 */
53 uint8_t *input_buffer;
54 size_t input_buffer_size;
55
56 bool pedantic;
57 /* @todo use multiple sized buffers */
58 cache_t *buffer_cache;
59 };
60
61 struct chunk_st {
62 /* Pointer to the data */
63 char *data;
64 /* The offset to the first byte into the buffer that is used */
65 size_t offset;
66 /* The offset into the buffer for the first free byte */
67 size_t nbytes;
68 /* The number of bytes in the buffer */
69 size_t size;
70 /* Pointer to the next buffer in the chain */
71 struct chunk_st *next;
72 };
73
74 #define CHUNK_BUFFERSIZE 2048
75
76 typedef memcached_protocol_event_t (*process_data)(struct memcached_protocol_client_st *client, ssize_t *length, void **endptr);
77
78 enum ascii_cmd {
79 GET_CMD,
80 GETS_CMD,
81 SET_CMD,
82 ADD_CMD,
83 REPLACE_CMD,
84 CAS_CMD,
85 APPEND_CMD,
86 PREPEND_CMD,
87 DELETE_CMD,
88 INCR_CMD,
89 DECR_CMD,
90 STATS_CMD,
91 FLUSH_ALL_CMD,
92 VERSION_CMD,
93 QUIT_CMD,
94 VERBOSITY_CMD,
95 UNKNOWN_CMD,
96 };
97
98 struct memcached_protocol_client_st {
99 memcached_protocol_st *root;
100 int sock;
101 int error;
102
103 /* Linked list of data to send */
104 struct chunk_st *output;
105 struct chunk_st *output_tail;
106
107 /*
108 * While we process input data, this is where we spool incomplete commands
109 * if we need to receive more data....
110 * @todo use the buffercace
111 */
112 uint8_t *input_buffer;
113 size_t input_buffer_size;
114 size_t input_buffer_offset;
115
116 /* The callback to the protocol handler to use (ascii or binary) */
117 process_data work;
118
119 /*
120 * Should the spool data discard the data to send or not? (aka noreply in
121 * the ascii protocol..
122 */
123 bool mute;
124
125 /* Members used by the binary protocol */
126 protocol_binary_request_header *current_command;
127
128 /* Members used by the ascii protocol */
129 enum ascii_cmd ascii_command;
130 };
131
132 #include "ascii_handler.h"
133 #include "binary_handler.h"
134
135 #endif