/*
 * Copyright (c) Likewise Software.  All rights Reserved.
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the license, or (at
 * your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
 * General Public License for more details.  You should have received a copy
 * of the GNU Lesser General Public License along with this program.  If
 * not, see <http://www.gnu.org/licenses/>.
 *
 * LIKEWISE SOFTWARE MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING
 * TERMS AS WELL.  IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT
 * WITH LIKEWISE SOFTWARE, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE
 * TERMS OF THAT SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE GNU
 * LESSER GENERAL PUBLIC LICENSE, NOTWITHSTANDING THE ABOVE NOTICE.  IF YOU
 * HAVE QUESTIONS, OR WISH TO REQUEST A COPY OF THE ALTERNATE LICENSING
 * TERMS OFFERED BY LIKEWISE SOFTWARE, PLEASE CONTACT LIKEWISE SOFTWARE AT
 * license@likewisesoftware.com
 */

/*
 * Module Name:
 *
 *        type.c
 *
 * Abstract:
 *
 *        Type specification API
 *        Primary entry points
 *
 * Authors: Brian Koropoff (bkoropoff@likewisesoftware.com)
 *
 */
#include "type-private.h"
#include "util-private.h"

LWMsgKind
lwmsg_type_get_kind(
    LWMsgType* type
    )
{
    return type->kind;
}

size_t
lwmsg_type_get_size(
    LWMsgType* type
    )
{
    return type->size;
}

unsigned int
lwmsg_type_get_width(
    LWMsgType* type
    )
{
    return type->info.kind_integer.width;
}

LWMsgSignage
lwmsg_type_get_signage(
    LWMsgType* type
    )
{
    return type->info.kind_integer.sign;
}

uint64_t
lwmsg_type_get_tag(
    LWMsgType* type
    )
{
    return type->tag;
}

const char*
lwmsg_type_get_encoding(
    LWMsgType* type
    )
{
    return type->info.kind_indirect.encoding;
}

LWMsgLengthStrategy
lwmsg_type_get_length_strategy(
    LWMsgType* type
    )
{
    return type->info.kind_indirect.term;
}

size_t
lwmsg_type_get_static_length(
    LWMsgType* type
    )
{
    return type->info.kind_indirect.term_info.static_length;
}

const char*
lwmsg_type_get_name(
    LWMsgType* type
    )
{
    return type->meta.type_name;
}

const char*
lwmsg_type_get_member_name(
    LWMsgType* type
    )
{
    return type->meta.member_name;
}

LWMsgTypeFlags
lwmsg_type_get_flags(
    LWMsgType* type
    )
{
    return type->attrs.flags;
}

size_t
lwmsg_type_get_custom_flags(
    LWMsgType* type
    )
{
    return type->attrs.custom;
}

void
lwmsg_type_get_range(
    LWMsgType* type,
    size_t* low,
    size_t* high
    )
{
    LWMSG_ASSERT(type->attrs.flags & LWMSG_TYPE_FLAG_RANGE);
    *low = type->attrs.range_low;
    *high = type->attrs.range_high;
}

LWMsgBool
lwmsg_type_has_enum_value(
    LWMsgType* type
    )
{
    LWMsgTypeIter iter;

    for (lwmsg_type_enter(type, &iter);
         lwmsg_type_valid(&iter);
         lwmsg_type_next(&iter))
    {
        if (iter.kind == LWMSG_KIND_ENUM_VALUE)
        {
            return LWMSG_TRUE;
        }
    }

    return LWMSG_FALSE;
}

LWMsgBool
lwmsg_type_has_enum_mask(
    LWMsgType* type
    )
{
    LWMsgTypeIter iter;

    for (lwmsg_type_enter(type, &iter);
         lwmsg_type_valid(&iter);
         lwmsg_type_next(&iter))
    {
        if (iter.kind == LWMSG_KIND_ENUM_MASK)
        {
            return LWMSG_TRUE;
        }
    }

    return LWMSG_FALSE;
}
