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