#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "uuid.h"
#include "php.h"
#include "ext/standard/info.h"
typedef struct {
uuid_t *uuid;
} ctx_t;
static void ctx_destructor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
{
ctx_t *ctx = (ctx_t *)rsrc->ptr;
if (ctx != NULL) {
if (ctx->uuid != NULL) {
uuid_destroy(ctx->uuid);
ctx->uuid = NULL;
}
free(ctx);
}
return;
}
static int ctx_id;
#define ctx_name "UUID context"
PHP_MINIT_FUNCTION(uuid)
{
ctx_id = zend_register_list_destructors_ex(
ctx_destructor, NULL, ctx_name, module_number);
REGISTER_LONG_CONSTANT("UUID_VERSION", UUID_VERSION, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("UUID_LEN_BIN", UUID_LEN_BIN, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("UUID_LEN_STR", UUID_LEN_STR, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("UUID_LEN_SIV", UUID_LEN_SIV, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("UUID_RC_OK", UUID_RC_OK, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("UUID_RC_ARG", UUID_RC_ARG, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("UUID_RC_MEM", UUID_RC_MEM, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("UUID_RC_SYS", UUID_RC_SYS, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("UUID_RC_INT", UUID_RC_INT, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("UUID_RC_IMP", UUID_RC_IMP, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("UUID_MAKE_V1", UUID_MAKE_V1, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("UUID_MAKE_V3", UUID_MAKE_V3, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("UUID_MAKE_V4", UUID_MAKE_V4, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("UUID_MAKE_V5", UUID_MAKE_V5, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("UUID_MAKE_MC", UUID_MAKE_MC, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("UUID_FMT_BIN", UUID_FMT_BIN, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("UUID_FMT_STR", UUID_FMT_STR, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("UUID_FMT_SIV", UUID_FMT_SIV, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("UUID_FMT_TXT", UUID_FMT_TXT, CONST_CS|CONST_PERSISTENT);
return SUCCESS;
}
PHP_MSHUTDOWN_FUNCTION(uuid)
{
return SUCCESS;
}
PHP_MINFO_FUNCTION(uuid)
{
char version[32];
sprintf(version, "%lx", uuid_version());
php_info_print_table_start();
php_info_print_table_row(2, "UUID (Universally Unique Identifier) Support", "enabled");
php_info_print_table_row(2, "UUID Library Version", version);
php_info_print_table_end();
return;
}
PHP_FUNCTION(uuid_create)
{
zval *z_ctx;
ctx_t *ctx;
uuid_rc_t rc;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &z_ctx) == FAILURE)
RETURN_LONG((long)UUID_RC_ARG);
if (!PZVAL_IS_REF(z_ctx)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uuid_create: parameter wasn't passed by reference");
RETURN_LONG((long)UUID_RC_ARG);
}
if ((ctx = (ctx_t *)malloc(sizeof(ctx_t))) == NULL)
RETURN_LONG((long)UUID_RC_MEM);
if ((rc = uuid_create(&ctx->uuid)) != UUID_RC_OK) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uuid_create: %s", uuid_error(rc));
RETURN_LONG((long)rc);
}
ZEND_REGISTER_RESOURCE(z_ctx, ctx, ctx_id);
RETURN_LONG((long)rc);
}
PHP_FUNCTION(uuid_destroy)
{
zval *z_ctx;
ctx_t *ctx;
uuid_rc_t rc;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_ctx) == FAILURE)
RETURN_LONG((long)UUID_RC_ARG);
ZEND_FETCH_RESOURCE(ctx, ctx_t *, &z_ctx, -1, ctx_name, ctx_id);
if (ctx == NULL || ctx->uuid == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uuid_destroy: invalid context");
RETURN_LONG((long)UUID_RC_ARG);
}
if ((rc = uuid_destroy(ctx->uuid)) != UUID_RC_OK) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uuid_destroy: %s", uuid_error(rc));
RETURN_LONG((long)rc);
}
ctx->uuid = NULL;
RETURN_LONG((long)rc);
}
PHP_FUNCTION(uuid_clone)
{
zval *z_ctx;
ctx_t *ctx;
zval *z_clone;
ctx_t *clone;
uuid_rc_t rc;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz", &z_ctx, &z_clone) == FAILURE)
RETURN_LONG((long)UUID_RC_ARG);
ZEND_FETCH_RESOURCE(ctx, ctx_t *, &z_ctx, -1, ctx_name, ctx_id);
if (ctx == NULL || ctx->uuid == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uuid_clone: invalid context");
RETURN_LONG((long)UUID_RC_ARG);
}
if (!PZVAL_IS_REF(z_clone)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uuid_clone: clone parameter wasn't passed by reference");
RETURN_LONG((long)UUID_RC_ARG);
}
if ((clone = (ctx_t *)malloc(sizeof(ctx_t))) == NULL)
RETURN_LONG((long)UUID_RC_MEM);
if ((rc = uuid_clone(ctx->uuid, &clone->uuid)) != UUID_RC_OK) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uuid_clone: %s", uuid_error(rc));
RETURN_LONG((long)rc);
}
ZEND_REGISTER_RESOURCE(z_clone, clone, ctx_id);
RETURN_LONG((long)rc);
}
PHP_FUNCTION(uuid_load)
{
zval *z_ctx;
ctx_t *ctx;
char *name;
size_t name_len;
uuid_rc_t rc;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &z_ctx, &name, &name_len) == FAILURE)
RETURN_LONG((long)UUID_RC_ARG);
ZEND_FETCH_RESOURCE(ctx, ctx_t *, &z_ctx, -1, ctx_name, ctx_id);
if (ctx == NULL || ctx->uuid == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uuid_load: invalid context");
RETURN_LONG((long)UUID_RC_ARG);
}
if ((rc = uuid_load(ctx->uuid, name)) != UUID_RC_OK) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uuid_load: %s", uuid_error(rc));
RETURN_LONG((long)rc);
}
RETURN_LONG((long)rc);
}
PHP_FUNCTION(uuid_make)
{
zval *z_ctx;
ctx_t *ctx;
uuid_rc_t rc;
long z_mode;
unsigned long mode;
zval *z_ctx_ns;
ctx_t *ctx_ns;
char *url;
size_t url_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|rs", &z_ctx, &z_mode, &z_ctx_ns, &url, &url_len) == FAILURE)
RETURN_LONG((long)UUID_RC_ARG);
ZEND_FETCH_RESOURCE(ctx, ctx_t *, &z_ctx, -1, ctx_name, ctx_id);
if (ctx == NULL || ctx->uuid == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uuid_make: invalid context");
RETURN_LONG((long)UUID_RC_ARG);
}
mode = (unsigned long)z_mode;
if (ZEND_NUM_ARGS() == 2 && ((mode & UUID_MAKE_V1) || (mode & UUID_MAKE_V4))) {
if ((rc = uuid_make(ctx->uuid, mode)) != UUID_RC_OK) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uuid_make: %s", uuid_error(rc));
RETURN_LONG((long)rc);
}
}
else if (ZEND_NUM_ARGS() == 4 && ((mode & UUID_MAKE_V3) || (mode & UUID_MAKE_V5))) {
ZEND_FETCH_RESOURCE(ctx_ns, ctx_t *, &z_ctx_ns, -1, ctx_name, ctx_id);
if (ctx_ns == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uuid_make: invalid namespace context");
RETURN_LONG((long)UUID_RC_ARG);
}
if (url == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uuid_make: invalid URL");
RETURN_LONG((long)UUID_RC_ARG);
}
if ((rc = uuid_make(ctx->uuid, mode, ctx_ns->uuid, url)) != UUID_RC_OK) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uuid_make: %s", uuid_error(rc));
RETURN_LONG((long)rc);
}
}
else {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uuid_make: invalid mode");
RETURN_LONG((long)UUID_RC_ARG);
}
RETURN_LONG((long)rc);
}
PHP_FUNCTION(uuid_isnil)
{
zval *z_ctx;
ctx_t *ctx;
uuid_rc_t rc;
zval *z_result;
int result;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rz", &z_ctx, &z_result) == FAILURE)
RETURN_LONG((long)UUID_RC_ARG);
ZEND_FETCH_RESOURCE(ctx, ctx_t *, &z_ctx, -1, ctx_name, ctx_id);
if (ctx == NULL || ctx->uuid == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uuid_isnil: invalid context");
RETURN_LONG((long)UUID_RC_ARG);
}
if (!PZVAL_IS_REF(z_result)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uuid_isnil: result parameter wasn't passed by reference");
RETURN_LONG((long)UUID_RC_ARG);
}
if ((rc = uuid_isnil(ctx->uuid, &result)) != UUID_RC_OK) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uuid_isnil: %s", uuid_error(rc));
RETURN_LONG((long)rc);
}
ZVAL_LONG(z_result, (long)result);
RETURN_LONG((long)rc);
}
PHP_FUNCTION(uuid_compare)
{
zval *z_ctx;
ctx_t *ctx;
zval *z_ctx2;
ctx_t *ctx2;
uuid_rc_t rc;
zval *z_result;
int result;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrz", &z_ctx, &z_ctx2, &z_result) == FAILURE)
RETURN_LONG((long)UUID_RC_ARG);
ZEND_FETCH_RESOURCE(ctx, ctx_t *, &z_ctx, -1, ctx_name, ctx_id);
if (ctx == NULL || ctx->uuid == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uuid_compare: invalid context");
RETURN_LONG((long)UUID_RC_ARG);
}
ZEND_FETCH_RESOURCE(ctx2, ctx_t *, &z_ctx2, -1, ctx_name, ctx_id);
if (ctx2 == NULL || ctx2->uuid) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uuid_compare: invalid context");
RETURN_LONG((long)UUID_RC_ARG);
}
if (!PZVAL_IS_REF(z_result)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uuid_compare: result parameter wasn't passed by reference");
RETURN_LONG((long)UUID_RC_ARG);
}
if ((rc = uuid_compare(ctx->uuid, ctx2->uuid, &result)) != UUID_RC_OK) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uuid_compare: %s", uuid_error(rc));
RETURN_LONG((long)rc);
}
ZVAL_LONG(z_result, (long)result);
RETURN_LONG((long)rc);
}
PHP_FUNCTION(uuid_import)
{
zval *z_ctx;
ctx_t *ctx;
long z_fmt;
unsigned long fmt;
zval *z_data;
uuid_rc_t rc;
void *data_ptr;
size_t data_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rls", &z_ctx, &z_fmt, &data_ptr, &data_len) == FAILURE)
RETURN_LONG((long)UUID_RC_ARG);
ZEND_FETCH_RESOURCE(ctx, ctx_t *, &z_ctx, -1, ctx_name, ctx_id);
if (ctx == NULL || ctx->uuid == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uuid_import: invalid context");
RETURN_LONG((long)UUID_RC_ARG);
}
fmt = (unsigned long)z_fmt;
if ((rc = uuid_import(ctx->uuid, fmt, data_ptr, data_len)) != UUID_RC_OK) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uuid_import: %s", uuid_error(rc));
RETURN_LONG((long)rc);
}
RETURN_LONG((long)rc);
}
PHP_FUNCTION(uuid_export)
{
zval *z_ctx;
ctx_t *ctx;
long z_fmt;
unsigned long fmt;
zval *z_data;
uuid_rc_t rc;
void *data_ptr;
size_t data_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlz", &z_ctx, &z_fmt, &z_data) == FAILURE)
RETURN_LONG((long)UUID_RC_ARG);
ZEND_FETCH_RESOURCE(ctx, ctx_t *, &z_ctx, -1, ctx_name, ctx_id);
if (ctx == NULL || ctx->uuid == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uuid_export: invalid context");
RETURN_LONG((long)UUID_RC_ARG);
}
fmt = (unsigned long)z_fmt;
if (!PZVAL_IS_REF(z_data)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uuid_export: data parameter wasn't passed by reference");
RETURN_LONG((long)UUID_RC_ARG);
}
data_ptr = NULL;
data_len = 0;
if ((rc = uuid_export(ctx->uuid, fmt, &data_ptr, &data_len)) != UUID_RC_OK) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "uuid_export: %s", uuid_error(rc));
RETURN_LONG((long)rc);
}
ZVAL_STRINGL(z_data, data_ptr, data_len, 1);
free(data_ptr);
RETURN_LONG((long)rc);
}
PHP_FUNCTION(uuid_error)
{
int z_rc;
uuid_rc_t rc;
char *error;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &z_rc) == FAILURE)
RETURN_NULL();
rc = (uuid_rc_t)z_rc;
if ((error = uuid_error(rc)) == NULL)
RETURN_NULL();
RETURN_STRING(error, 1);
}
PHP_FUNCTION(uuid_version)
{
RETURN_LONG((long)uuid_version());
}
static function_entry uuid_functions[] = {
PHP_FE(uuid_create, NULL)
PHP_FE(uuid_destroy, NULL)
PHP_FE(uuid_clone, NULL)
PHP_FE(uuid_load, NULL)
PHP_FE(uuid_make, NULL)
PHP_FE(uuid_isnil, NULL)
PHP_FE(uuid_compare, NULL)
PHP_FE(uuid_import, NULL)
PHP_FE(uuid_export, NULL)
PHP_FE(uuid_error, NULL)
PHP_FE(uuid_version, NULL)
{ NULL, NULL, NULL }
};
zend_module_entry uuid_module_entry = {
STANDARD_MODULE_HEADER,
"uuid",
uuid_functions,
PHP_MINIT(uuid),
PHP_MSHUTDOWN(uuid),
NULL,
NULL,
PHP_MINFO(uuid),
NO_VERSION_YET,
STANDARD_MODULE_PROPERTIES
};
#ifdef COMPILE_DL_UUID
ZEND_GET_MODULE(uuid)
#endif