bool user_callback_wrapper(const as_val *val, void *udata) { zval retval; ZVAL_NULL(&retval); if (!val) { return false; } as_record* record = as_record_fromval(val); user_callback_function* callback_info = (user_callback_function*)udata; pthread_mutex_lock(callback_info->cb_mutex); callback_info->callback.retval = &retval; if (execute_user_callback(record, callback_info) != AEROSPIKE_OK) { as_error_update(callback_info->err, AEROSPIKE_ERR_PARAM, "Callback raised an error"); pthread_mutex_unlock(callback_info->cb_mutex); return false; } if (callback_info->callback.retval && Z_TYPE_P(callback_info->callback.retval) == IS_FALSE) { pthread_mutex_unlock(callback_info->cb_mutex); return false; } zval_dtor(&retval); pthread_mutex_unlock(callback_info->cb_mutex); return true; }
/* ******************************************************************************************************* * Checks as_bytes->type. * Deserializes as_bytes into Py_Object (retval) using deserialization logic * based on as_bytes->type. * * @param bytes The as_bytes to be deserialized. * @param retval The return zval to be populated with the * deserialized value of the input as_bytes. * @param error_p The as_error to be populated by the function * with encountered error if any. ******************************************************************************************************* */ extern PyObject * deserialize_based_on_as_bytes_type(AerospikeClient * self, as_bytes *bytes, PyObject **retval, as_error *error_p) { switch(as_bytes_get_type(bytes)) { case AS_BYTES_PYTHON: { PyObject* sysmodules = PyImport_GetModuleDict(); PyObject* cpickle_module = NULL; if(PyMapping_HasKeyString(sysmodules, "cPickle")) { cpickle_module = PyMapping_GetItemString(sysmodules, "cPickle"); } else { cpickle_module = PyImport_ImportModule("cPickle"); } PyObject* initresult = NULL; if(!cpickle_module) { /* insert error handling here! and exit this function */ as_error_update(error_p, AEROSPIKE_ERR_CLIENT, "Unable to load cpickle module"); goto CLEANUP; } else { char* bytes_val_p = (char*)bytes->value; PyObject *py_value = PyStr_FromStringAndSize(bytes_val_p, as_bytes_size(bytes)); PyObject *py_funcname = PyStr_FromString("loads"); Py_INCREF(cpickle_module); initresult = PyObject_CallMethodObjArgs(cpickle_module, py_funcname, py_value, NULL); Py_DECREF(cpickle_module); Py_DECREF(py_funcname); Py_DECREF(py_value); if(!initresult) { /* more error handling &c */ as_error_update(error_p, AEROSPIKE_ERR_CLIENT, "Unable to call loads function"); goto CLEANUP; } else { *retval = initresult; } } Py_XDECREF(cpickle_module); } break; case AS_BYTES_BLOB: { if (self->user_deserializer_call_info.callback) { execute_user_callback(&self->user_deserializer_call_info, &bytes, retval, false, error_p); if(AEROSPIKE_OK != (error_p->code)) { uint32_t bval_size = as_bytes_size(bytes); PyObject *py_val = PyByteArray_FromStringAndSize((char *) as_bytes_get(bytes), bval_size); if (!py_val) { as_error_update(error_p, AEROSPIKE_ERR_CLIENT, "Unable to deserialize bytes"); goto CLEANUP; } *retval = py_val; as_error_update(error_p, AEROSPIKE_OK, NULL); } } else { if (is_user_deserializer_registered) { execute_user_callback(&user_deserializer_call_info, &bytes, retval, false, error_p); if(AEROSPIKE_OK != (error_p->code)) { uint32_t bval_size = as_bytes_size(bytes); PyObject *py_val = PyByteArray_FromStringAndSize((char *) as_bytes_get(bytes), bval_size); if (!py_val) { as_error_update(error_p, AEROSPIKE_ERR_CLIENT, "Unable to deserialize bytes"); goto CLEANUP; } as_error_update(error_p, AEROSPIKE_OK, NULL); *retval = py_val; } } else { uint32_t bval_size = as_bytes_size(bytes); PyObject *py_val = PyByteArray_FromStringAndSize((char *) as_bytes_get(bytes), bval_size); if (!py_val) { as_error_update(error_p, AEROSPIKE_ERR_CLIENT, "Unable to deserialize bytes"); goto CLEANUP; } *retval = py_val; } } } break; case AS_BYTES_LDT: { Py_INCREF(Py_None); *retval = Py_None; } break; default: as_error_update(error_p, AEROSPIKE_ERR, "Unable to deserialize bytes"); goto CLEANUP; } CLEANUP: if ( error_p->code != AEROSPIKE_OK ) { PyObject * py_err = NULL; error_to_pyobject(error_p, &py_err); PyObject *exception_type = raise_exception(error_p); PyErr_SetObject(exception_type, py_err); Py_DECREF(py_err); return NULL; } return PyLong_FromLong(0); }
/* ******************************************************************************************************* * Checks serializer_policy. * Serializes Py_Object (value) into as_bytes using serialization logic * based on serializer_policy. * * @param serializer_policy The serializer_policy to be used to handle * the serialization. * @param bytes The as_bytes to be set. * @param value The value to be serialized. * @param error_p The as_error to be populated by the function * with encountered error if any. ******************************************************************************************************* */ extern PyObject * serialize_based_on_serializer_policy(AerospikeClient * self, int32_t serializer_policy, as_bytes **bytes, PyObject *value, as_error *error_p) { uint8_t use_client_serializer = true; PyObject* initresult = NULL; if (self->is_client_put_serializer) { if (serializer_policy == SERIALIZER_USER) { if (!self->user_serializer_call_info.callback) { use_client_serializer = false; } } } else if (self->user_serializer_call_info.callback) { serializer_policy = SERIALIZER_USER; } switch(serializer_policy) { case SERIALIZER_NONE: as_error_update(error_p, AEROSPIKE_ERR_PARAM, "Cannot serialize: SERIALIZER_NONE selected"); goto CLEANUP; case SERIALIZER_PYTHON: { /* * Serialize bytearray as is and store them into database with * type AS_BYTES_BLOB, unlike other values in case of * SERIALIZER_PYTHON. * This is a special case. * Refer: AER-3589 for more details. */ if (PyByteArray_Check(value)) { uint8_t *bytes_array = (uint8_t *) PyByteArray_AsString(value); uint32_t bytes_array_len = (uint32_t) PyByteArray_Size(value); set_as_bytes(bytes, bytes_array, bytes_array_len, AS_BYTES_BLOB, error_p); } else { /* get the sys.modules dictionary */ PyObject* sysmodules = PyImport_GetModuleDict(); PyObject* cpickle_module = NULL; if(PyMapping_HasKeyString(sysmodules, "cPickle")) { cpickle_module = PyMapping_GetItemString(sysmodules, "cPickle"); } else { cpickle_module = PyImport_ImportModule("cPickle"); } if(!cpickle_module) { /* insert error handling here! and exit this function */ as_error_update(error_p, AEROSPIKE_ERR_CLIENT, "Unable to load cpickle module"); goto CLEANUP; } else { PyObject * py_funcname = PyStr_FromString("dumps"); Py_INCREF(cpickle_module); initresult = PyObject_CallMethodObjArgs(cpickle_module, py_funcname, value, NULL); Py_DECREF(cpickle_module); Py_DECREF(py_funcname); if(!initresult) { /* more error handling &c */ as_error_update(error_p, AEROSPIKE_ERR_CLIENT, "Unable to call dumps function"); goto CLEANUP; } else { Py_INCREF(initresult); char *return_value = PyStr_AsString(initresult); Py_ssize_t len = PyBytes_GET_SIZE(initresult); set_as_bytes(bytes, (uint8_t *) return_value, len, AS_BYTES_PYTHON, error_p); Py_DECREF(initresult); } } Py_XDECREF(cpickle_module); } } break; case SERIALIZER_JSON: /* * TODO: * Handle JSON serialization after support for AS_BYTES_JSON * is added in aerospike-client-c */ as_error_update(error_p, AEROSPIKE_ERR, "Unable to serialize using standard json serializer"); goto CLEANUP; case SERIALIZER_USER: if (use_client_serializer) { execute_user_callback(&self->user_serializer_call_info, bytes, &value, true, error_p); if (AEROSPIKE_OK != (error_p->code)) { goto CLEANUP; } } else { if (is_user_serializer_registered) { execute_user_callback(&user_serializer_call_info, bytes, &value, true, error_p); if (AEROSPIKE_OK != (error_p->code)) { goto CLEANUP; } } else if (self->user_serializer_call_info.callback) { execute_user_callback(&self->user_serializer_call_info, bytes, &value, true, error_p); if (AEROSPIKE_OK != (error_p->code)) { goto CLEANUP; } } else { as_error_update(error_p, AEROSPIKE_ERR, "No serializer callback registered"); goto CLEANUP; } } break; default: as_error_update(error_p, AEROSPIKE_ERR, "Unsupported serializer"); goto CLEANUP; } CLEANUP: Py_XDECREF(initresult); if ( error_p->code != AEROSPIKE_OK ) { PyObject * py_err = NULL; error_to_pyobject(error_p, &py_err); PyObject *exception_type = raise_exception(error_p); PyErr_SetObject(exception_type, py_err); Py_DECREF(py_err); return NULL; } return PyLong_FromLong(0); }