// $Id: JGDevAttribute.cpp,v 1.3 2003/02/02 15:56:01 fukasawa Exp $

//=============================================================================
/**
 *  @file    JGDevAttribute.cpp
 *
 *  @author  Fukasawa Mitsuo
 *
 *
 *    Copyright (C) 2001-2003 BEE Co.,Ltd. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
//=============================================================================

#define BEE_BUILD_DLL

#include "JGDevAttribute.h"
#include "JGDevType.h"
#include "JGDevObject.h"

#define  VM_PLC    1

#ifdef VM_PLC
#define GET_PLC(o,a)         (o)->vmget(a)
#define PUT_PLC(o,a,x)       (o)->put((a),(x))
#define READ_PLC(o,a,s,b)    (o)->vmread((a),(s),(b))
#define WRITE_PLC(o,a,s,b)   (o)->write((a),(s),(b))
#else
#define GET_PLC(o,a)         (o)->get(a)
#define PUT_PLC(o,a,x)       (o)->put((a),(x))
#define READ_PLC(o,a,s,b)    (o)->read((a),(s),(b))
#define WRITE_PLC(o,a,s,b)   (o)->write((a),(s),(b))
#endif

//-----------------------------------------------------------------------------
// Constructor/Destructor
//-----------------------------------------------------------------------------
JGDevAttribute::JGDevAttribute(JGDevType& clazz, const BCHAR * name, int type,
                         size_t size, const PLCAccess& paddr, bool comp)
        : b_attribute(clazz, name, type, size) {
    TRACE_FUNCTION(TRL_CONSTRUCT, "JGDevAttribute::JGDevAttribute");
    m_addr = paddr;
    m_comp = comp;
}

//-----------------------------------------------------------------------------
// Get current value
//-----------------------------------------------------------------------------
int JGDevAttribute::getValue(JGvalue& value) const
{
    TRACE_FUNCTION(TRL_LOW, "JGDevAttribute::getValue");
    int     result = 0;
    u_short datum;
    u_long  offset = m_addr.addr();
    PLCDevice * plc = const_cast<PLCAccess&>(m_addr).memory();
    size_t  words;

    if (m_type == ATOM_INT2)
    {
        short ss = GET_PLC(plc, offset);
        value = ss;
    }
    else if (m_type == ATOM_ASCII)
    {
        words = (m_size + 1) / 2;
        BCHAR * readbuf = new BCHAR[(words + 1) * 2];
        result = READ_PLC(plc, offset, words, (USHORT *)readbuf);
        if (result == 0)
        {
            *(readbuf + m_size - 1) = '\0';
        }
        else
        {
            *readbuf = '\0';
        }
        value = readbuf;
        delete[] readbuf;
    }
    else if (m_type == ATOM_BINARY)
    {
        words = (m_size + 1) / 2;
        BYTE * binbuf = new BYTE[(words + 1) * 2];
        result = READ_PLC(plc, offset, words, (USHORT *)binbuf);
        value.set(binbuf, words * 2);
        delete[] binbuf;
    }
    else if (m_type == ATOM_INT4 || m_type == ATOM_UINT4)
    {
        UINT v;
        datum = GET_PLC(plc, offset);
        v = datum << 16;
        datum = GET_PLC(plc, offset + 1);
        v += datum;
        value = v;
    }
    else if (m_type == ATOM_BOOLEAN)
    {
        bool bit = (GET_PLC(plc, offset) != 0) ? true : false;
        value = bit;
    }
    else // if (m_type == ATOM_UINT2)
    {
        datum = GET_PLC(plc, offset);
        value = datum;
    }

    return result;
}


//-----------------------------------------------------------------------------
// Dump
//-----------------------------------------------------------------------------
void JGDevAttribute::dump() const
{
    ACE_DEBUG((LM_DEBUG, ACE_TEXT("  %d:name = %s, "), m_position,
                                                       m_name.c_str()));
    ACE_DEBUG((LM_DEBUG, ACE_TEXT("type = 0x%x, "), m_type));
    ACE_DEBUG((LM_DEBUG, ACE_TEXT("size = %d, "), m_size));
    ACE_DEBUG((LM_DEBUG, ACE_TEXT("addr = %d:%u.\n"), m_addr.type(),
                                                      m_addr.addr()));
}

