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