fbbf68d7231461094080e71ac2e67d35b41028f8
[m6w6/libmemcached] / src / libmemcached / callback.cc
1 /*
2 +--------------------------------------------------------------------+
3 | libmemcached - C/C++ Client Library for memcached |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted under the terms of the BSD license. |
7 | You should have received a copy of the license in a bundled file |
8 | named LICENSE; in case you did not receive a copy you can review |
9 | the terms online at: https://opensource.org/licenses/BSD-3-Clause |
10 +--------------------------------------------------------------------+
11 | Copyright (c) 2006-2014 Brian Aker https://datadifferential.com/ |
12 | Copyright (c) 2020 Michael Wallner <mike@php.net> |
13 +--------------------------------------------------------------------+
14 */
15
16 #include "libmemcached/common.h"
17 #include <sys/types.h>
18
19 #ifndef __INTEL_COMPILER
20 # pragma GCC diagnostic ignored "-Wstrict-aliasing"
21 #endif
22
23 /*
24 These functions provide data and function callback support
25 */
26
27 memcached_return_t memcached_callback_set(memcached_st *shell, const memcached_callback_t flag,
28 const void *data) {
29 Memcached *ptr = memcached2Memcached(shell);
30 if (ptr) {
31 switch (flag) {
32 case MEMCACHED_CALLBACK_PREFIX_KEY: {
33 return memcached_set_namespace(*ptr, (char *) data, data ? strlen((char *) data) : 0);
34 }
35
36 case MEMCACHED_CALLBACK_USER_DATA: {
37 ptr->user_data = const_cast<void *>(data);
38 break;
39 }
40
41 case MEMCACHED_CALLBACK_CLEANUP_FUNCTION: {
42 memcached_cleanup_fn func = *(memcached_cleanup_fn *) &data;
43 ptr->on_cleanup = func;
44 break;
45 }
46
47 case MEMCACHED_CALLBACK_CLONE_FUNCTION: {
48 memcached_clone_fn func = *(memcached_clone_fn *) &data;
49 ptr->on_clone = func;
50 break;
51 }
52
53 case MEMCACHED_CALLBACK_GET_FAILURE: {
54 memcached_trigger_key_fn func = *(memcached_trigger_key_fn *) &data;
55 ptr->get_key_failure = func;
56 break;
57 }
58
59 case MEMCACHED_CALLBACK_DELETE_TRIGGER: {
60 if (data) // NULL would mean we are disabling.
61 {
62 if (memcached_behavior_get(ptr, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS)) {
63 return memcached_set_error(
64 *ptr, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT,
65 memcached_literal_param("Delete triggers cannot be used if buffering is enabled"));
66 }
67
68 if (memcached_behavior_get(ptr, MEMCACHED_BEHAVIOR_NOREPLY)) {
69 return memcached_set_error(
70 *ptr, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT,
71 memcached_literal_param(
72 "Delete triggers cannot be used if MEMCACHED_BEHAVIOR_NOREPLY is set"));
73 }
74 }
75
76 memcached_trigger_delete_key_fn func = *(memcached_trigger_delete_key_fn *) &data;
77 ptr->delete_trigger = func;
78 break;
79 }
80
81 case MEMCACHED_CALLBACK_MAX:
82 return memcached_set_error(*ptr, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT,
83 memcached_literal_param("Invalid callback supplied"));
84 }
85
86 return MEMCACHED_SUCCESS;
87 }
88
89 return MEMCACHED_INVALID_ARGUMENTS;
90 }
91
92 void *memcached_callback_get(memcached_st *shell, const memcached_callback_t flag,
93 memcached_return_t *error) {
94 Memcached *ptr = memcached2Memcached(shell);
95 memcached_return_t local_error;
96 if (error == NULL) {
97 error = &local_error;
98 }
99
100 if (ptr == NULL) {
101 *error = MEMCACHED_INVALID_ARGUMENTS;
102 return NULL;
103 }
104
105 switch (flag) {
106 case MEMCACHED_CALLBACK_PREFIX_KEY: {
107 *error = MEMCACHED_SUCCESS;
108 if (ptr->_namespace) {
109 return (void *) memcached_array_string(ptr->_namespace);
110 }
111 return NULL;
112 }
113
114 case MEMCACHED_CALLBACK_USER_DATA: {
115 *error = ptr->user_data ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE;
116 return (void *) ptr->user_data;
117 }
118
119 case MEMCACHED_CALLBACK_CLEANUP_FUNCTION: {
120 *error = ptr->on_cleanup ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE;
121 return *(void **) &ptr->on_cleanup;
122 }
123
124 case MEMCACHED_CALLBACK_CLONE_FUNCTION: {
125 *error = ptr->on_clone ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE;
126 return *(void **) &ptr->on_clone;
127 }
128
129 case MEMCACHED_CALLBACK_GET_FAILURE: {
130 *error = ptr->get_key_failure ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE;
131 return *(void **) &ptr->get_key_failure;
132 }
133
134 case MEMCACHED_CALLBACK_DELETE_TRIGGER: {
135 *error = ptr->delete_trigger ? MEMCACHED_SUCCESS : MEMCACHED_FAILURE;
136 return *(void **) &ptr->delete_trigger;
137 }
138
139 case MEMCACHED_CALLBACK_MAX:
140 break;
141 }
142
143 assert_msg(0, "Invalid callback passed to memcached_callback_get()");
144 *error = MEMCACHED_FAILURE;
145 return NULL;
146 }