/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <axutil_generic_obj.h>

struct axutil_generic_obj
{
    AXIS2_FREE_VOID_ARG free_func;
    int type;
    void *value;
};

AXIS2_EXTERN axutil_generic_obj_t *AXIS2_CALL
axutil_generic_obj_create(
    const axutil_env_t *env)
{
    axutil_generic_obj_t *generic_obj = NULL;
    AXIS2_ENV_CHECK(env, NULL);

    generic_obj = (axutil_generic_obj_t *) AXIS2_MALLOC(env->allocator,
                      sizeof(axutil_generic_obj_t));

    if (!generic_obj)
    {
        AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory");
        return NULL;
    }
    generic_obj->value = NULL;
    generic_obj->free_func = 0;

    return generic_obj;
}

AXIS2_EXTERN void AXIS2_CALL
axutil_generic_obj_free(
    axutil_generic_obj_t *generic_obj,
    const axutil_env_t *env)
{
    if (generic_obj->value)
    {
        if (generic_obj->free_func)
        {
            generic_obj->free_func(generic_obj->value, env);
        }
        else
        {
            AXIS2_FREE(env->allocator, generic_obj->value);
        }

    }

    if (generic_obj)
    {
        AXIS2_FREE(env->allocator, generic_obj);
    }
    return;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_generic_obj_set_free_func(
    axutil_generic_obj_t *generic_obj,
    const axutil_env_t *env,
    AXIS2_FREE_VOID_ARG free_func)
{
    generic_obj->free_func = free_func;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_generic_obj_set_value(
    axutil_generic_obj_t *generic_obj,
    const axutil_env_t *env,
    void *value)
{
    generic_obj->value = value;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN void *AXIS2_CALL
axutil_generic_obj_get_value(
    axutil_generic_obj_t *generic_obj,
    const axutil_env_t *env)
{
    return generic_obj->value;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_generic_obj_set_type(
    axutil_generic_obj_t *generic_obj,
    const axutil_env_t *env,
    int type)
{
    generic_obj->type = type;
    return AXIS2_SUCCESS;
}

AXIS2_EXTERN int AXIS2_CALL
axutil_generic_obj_get_type(
    axutil_generic_obj_t *generic_obj,
    const axutil_env_t *env)
{
    return generic_obj->type;
}

