// $Id: MELXmlParser.cpp,v 1.3 2003/03/19 16:49:24 fukasawa Exp $

//=============================================================================
/**
 *  @file    MELXmlParse.cpp
 *
 *  @author  Fukasawa Mitsuo
 *
 *
 *    Copyright (C) 2001-2002 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 "ace/Mem_Map.h"
#include "ace/Log_Msg.h"
#include "MELXmlParser.h"
#ifdef PLC_MELSEC_SERVER
#include "MELDeviceServer.h"
#else
#include "MELDeviceManager.h"
#endif

static MELXmlParser * _instance = NULL;
static const ACE_TCHAR * _elmConfig = ACE_TEXT("plcConfiguration");
static const ACE_TCHAR * _elmDevices= ACE_TEXT("melDevices");
static const ACE_TCHAR * _elmDevice = ACE_TEXT("melDevice");
static const ACE_TCHAR * _elmCycle  = ACE_TEXT("logCycle");
static const ACE_TCHAR * _elmLogSize= ACE_TEXT("logSize");
static const ACE_TCHAR * _elmReadBlocks = ACE_TEXT("readBlocks");
static const ACE_TCHAR * _elmReadBlock =  ACE_TEXT("readBlock");
static const ACE_TCHAR * _elmReadDevice = ACE_TEXT("readDevice");

//-----------------------------------------------------------------------------
// Instance of own
//-----------------------------------------------------------------------------
MELXmlParser * MELXmlParser::instance()
{
    if (_instance == NULL)
    {
        _instance = new MELXmlParser;
    }
    return _instance;
}

//-----------------------------------------------------------------------------
// Initialize
//-----------------------------------------------------------------------------
int MELXmlParser::init(const char * xmlFile)
{
    m_xmlFile = (xmlFile == NULL) ? "" : xmlFile;

    try
    {
        XMLPlatformUtils::Initialize();
        m_melsecs.clear();
        m_cycle = 10;
    }
    catch (const XMLException& toCatch)
    {
        ACE_ERROR((LM_ERROR, ACE_TEXT("MELXmlParser::init: %s %s.\n"),
                             ACE_TEXT("Xerces-c Initialize exception message: "),
                             StrX(toCatch.getMessage()).localForm()));
        return -1;
    }

    return 0;
}

//-----------------------------------------------------------------------------
// Finish
//-----------------------------------------------------------------------------
int MELXmlParser::fini()
{
    try
    {
        XMLPlatformUtils::Terminate();
    }
    catch (const XMLException& toCatch)
    {
        ACE_ERROR((LM_ERROR, ACE_TEXT("MELXmlParser::fini: %s %s.\n"),
                             ACE_TEXT("Xerces-c Finalize exception message: "),
                             StrX(toCatch.getMessage()).localForm()));
    }
    return 0;
}

//-----------------------------------------------------------------------------
// Parse xml file
//-----------------------------------------------------------------------------
int MELXmlParser::parse(MELDeviceManager * melmngr)
{
    int result;
    DOMParser * parser;

    try
    {
        parser = new DOMParser();
        parser->setValidationScheme(DOMParser::Val_Always);     // optional
        parser->setDoNamespaces(true);                          // optional
        parser->setDoSchema(true);                              // optional
        parser->setValidationSchemaFullChecking(true);          // optional
        parser->parse(m_xmlFile.c_str());
    }
    catch (const XMLException& toCatch)
    {
        ACE_ERROR((LM_ERROR, ACE_TEXT("MELXmlParser::parse: %s %s.\n"),
                             ACE_TEXT("Xerces-c Parsing exception message: "),
                             StrX(toCatch.getMessage()).localForm()));
        return -1;
    }
    catch (...)
    {
        ACE_ERROR((LM_ERROR, ACE_TEXT("MELXmlParser::parse: %s %s.\n"),
                             ACE_TEXT("Xerces-c Parsing exception message: "),
                             ACE_TEXT("Unexpected Exception")));
        return -1;
    }

    // Traverse xml tree
    DOMDocument * doc = parser->getDocument();
    if (doc != NULL)
    {
        result = parseElements(melmngr,
                               (DOMNode *)doc->getDocumentElement());
        if (result < 0)
        {
            return result;
        }
    }
    else
    {
        ACE_ERROR((LM_ERROR, ACE_TEXT("MELXmlParser::parse: %s.\n"),
                             ACE_TEXT("Parsed document is null")));
    }

    return 0;
}

//-----------------------------------------------------------------------------
// Parse element
//-----------------------------------------------------------------------------
int MELXmlParser::parseElements(MELDeviceManager * melmngr, DOMNode * node)
{
    int result = 0;
    DOMNode * child;
    if (node == NULL)
    {
        ACE_ERROR((LM_ERROR,
            ACE_TEXT("MELXmlParser::parseElements: Node is null.\n")));
        return -1;
    }

    string nameStr = StrX(node->getNodeName()).localForm();
    if (nameStr != _elmConfig)
    {
        ACE_ERROR((LM_ERROR,
            ACE_TEXT("MELXmlParser::parseElements: Illegal node name %s.\n"),
            nameStr.c_str()));
        return -1;
    }

    // Attributes: nothing

    int nodeType = node->getNodeType();
    switch (nodeType)
    {
    case DOMNode::ELEMENT_NODE:
        {
            // Parse for the presence of children.
            for (child = node->getFirstChild(); child != NULL;
                 child = child->getNextSibling())
            {
                switch (child->getNodeType())
                {
                case DOMNode::ELEMENT_NODE:
                    {
                        nameStr = StrX(child->getNodeName()).localForm();
                        if (nameStr == _elmDevices)
                        {
                            result = parseDevicesElm(child);
                            if (result < 0)
                            {
                                return result;
                            }
                            //
                            melmngr->initRegisters(this);    // *** Init device table ***
                        }
                        else if (nameStr == _elmCycle)
                        {
                            result = parseCycleElement(child);
                            if (result < 0)
                            {
                                return result;
                            }
                        }
                        else if (nameStr == _elmReadBlocks)
                        {
#ifdef PLC_MELSEC_SERVER
                            result = parseReadBlocksElm(child);
                            if (result < 0)
                            {
                                return result;
                            }
#endif
                        }
                        else
                        {
                            ACE_ERROR((LM_ERROR,
                                ACE_TEXT("MELXmlParser::parseElements: Ignore element name %s.\n"),
                                nameStr.c_str()));
                            // return -1;   // ignore
                        }
                    }
                    break;

                case DOMNode::TEXT_NODE:
                case DOMNode::PROCESSING_INSTRUCTION_NODE:
                case DOMNode::DOCUMENT_NODE:
                case DOMNode::ENTITY_REFERENCE_NODE:
                case DOMNode::CDATA_SECTION_NODE:
                case DOMNode::COMMENT_NODE:
                case DOMNode::DOCUMENT_TYPE_NODE:
                case DOMNode::ENTITY_NODE:
                    break;
                default:
                    break;
                }
            }
        }
        break;

    case DOMNode::TEXT_NODE:
    case DOMNode::PROCESSING_INSTRUCTION_NODE:
    case DOMNode::DOCUMENT_NODE:
    case DOMNode::ENTITY_REFERENCE_NODE:
    case DOMNode::CDATA_SECTION_NODE:
    case DOMNode::COMMENT_NODE:
    case DOMNode::DOCUMENT_TYPE_NODE:
    case DOMNode::ENTITY_NODE:
        break;
    default:
        break;
    }

    return result;
}

//-----------------------------------------------------------------------------
// Parse Devices element
//-----------------------------------------------------------------------------
int MELXmlParser::parseDevicesElm(DOMNode * node)
{
    int result;
    DOMNode * child;

    // Attributes: nothing

    // Parse for the presence of children.
    for (child = node->getFirstChild(); child != NULL;
         child = child->getNextSibling())
    {
        switch (child->getNodeType())
        {
        case DOMNode::ELEMENT_NODE:
            {
                string nameStr = StrX(child->getNodeName()).localForm();
                if (nameStr == _elmDevice)
                {
                    result = parseDeviceElement(child);
                    if (result < 0)
                    {
                        return result;
                    }
                }
                else
                {
                    ACE_ERROR((LM_ERROR,
                        ACE_TEXT("MELXmlParser::parseDevicesElm: Invalid element name %s.\n"),
                        nameStr.c_str()));
                    // return -1;   // ignore
                }
            }
            break;

        case DOMNode::TEXT_NODE:
        case DOMNode::PROCESSING_INSTRUCTION_NODE:
        case DOMNode::DOCUMENT_NODE:
        case DOMNode::ENTITY_REFERENCE_NODE:
        case DOMNode::CDATA_SECTION_NODE:
        case DOMNode::COMMENT_NODE:
        case DOMNode::DOCUMENT_TYPE_NODE:
        case DOMNode::ENTITY_NODE:
            break;
        default:
            break;
        }
    }

    return result;
}

//-----------------------------------------------------------------------------
// Parse Device element
//-----------------------------------------------------------------------------
int MELXmlParser::parseDeviceElement(DOMNode * node)
{
    int result = 0;
    DOMNode * child;
    MelsecMemoryInfo melmem;

    DOMNamedNodeMap * attributes = node->getAttributes();
    int attrCount = attributes->getLength();
    for (int i = 0; i < attrCount; i++)
    {
        DOMNode * attribute = attributes->item(i);
        string nameStr = StrX(attribute->getNodeName()).localForm();
        string valStr  = StrX(attribute->getNodeValue()).localForm();
        if (nameStr == "name")
        {
            strncpy(melmem.m_name, valStr.c_str(), melmem.nameq() - 1);
            melmem.m_name[melmem.nameq() - 1] = '\0';
        }
        else if (nameStr == ACE_TEXT("id"))
        {
            melmem.m_devcode = strtoul(valStr.c_str(), NULL, 10);
            if (melmem.m_devcode == 0)
            {
                ACE_ERROR((LM_ERROR,
                    "Device(%s) is defined invalid id(%s).\n",
                    melmem.m_name, valStr.c_str()));
                return -1;
            }
        }
        else if (nameStr == ACE_TEXT("type"))
        {
            if (valStr == "BIT")
            {
                melmem.m_memtype = MELMEM_BIT;
            }
            else if (valStr == ACE_TEXT("WORD"))
            {
                melmem.m_memtype = MELMEM_WORD;
            }
            else if (valStr == ACE_TEXT("ZR"))
            {
                melmem.m_memtype = MELMEM_ZR;
            }
            else
            {
                ACE_ERROR((LM_ERROR,
                    ACE_TEXT("Device(%s) is defined invalid type(%s).\n"),
                    melmem.m_name, valStr.c_str()));
                return -1;
            }
        }
        else if (nameStr == ACE_TEXT("maxsize"))
        {
            melmem.m_maxsize = strtoul(valStr.c_str(), NULL, 0);
            if (melmem.m_maxsize == 0)
            {
                ACE_ERROR((LM_ERROR,
                    ACE_TEXT("Device(%s) is defined invalid maxsize(%s).\n"),
                    melmem.m_name, valStr.c_str()));
                return -1;
            }
            melmem.m_size = melmem.m_maxsize;
        }
        else
        {
            ACE_ERROR((LM_ERROR,
                ACE_TEXT("Device(%s) is defined invalid attribute name(%s).\n"),
                melmem.m_name, nameStr.c_str()));
            return -1;
        }
    }

    // Parse for the presence of children.
    for (child = node->getFirstChild(); child != NULL;
         child = child->getNextSibling())
    {
        int nodeType = child->getNodeType();
        switch (nodeType)
        {
        case DOMNode::ELEMENT_NODE:
            {
                if (_elmLogSize == StrX(child->getNodeName()))
                {
                    result = parseLogSizeElement(child, melmem);
                    if (result < 0)
                    {
                        return result;
                    }
                }
            }
            break;

        case DOMNode::TEXT_NODE:
        case DOMNode::PROCESSING_INSTRUCTION_NODE:
        case DOMNode::DOCUMENT_NODE:
        case DOMNode::ENTITY_REFERENCE_NODE:
        case DOMNode::CDATA_SECTION_NODE:
        case DOMNode::COMMENT_NODE:
        case DOMNode::DOCUMENT_TYPE_NODE:
        case DOMNode::ENTITY_NODE:
            break;
        default:
            break;
        }
    }

    //ACE_DEBUG((LM_DEBUG,
    //    "Device(%s): type=%d id=%d max=%d size=%d.\n",
    //    melmem.m_name, melmem.m_memtype, melmem.m_devcode,
    //    melmem.m_maxsize, melmem.m_size));

    m_melsecs.push_back(melmem);

    return result;
}

//-----------------------------------------------------------------------------
// Parse LogCycle element
//-----------------------------------------------------------------------------
int MELXmlParser::parseCycleElement(DOMNode * node)
{
    int result = 0;
    DOMNode * child;

    // Parse for the presence of children.
    for (child = node->getFirstChild(); child != NULL;
         child = child->getNextSibling())
    {
        int nodeType = child->getNodeType();
        switch (nodeType)
        {
        case DOMNode::TEXT_NODE:
            {
                string valStr = StrX(child->getNodeValue()).localForm();
                m_cycle = strtoul(valStr.c_str(), NULL, 10);
                if (m_cycle == 0)
                {
                    ACE_ERROR((LM_ERROR,
                        ACE_TEXT("LogCycle is invalid time(%s).\n"), valStr.c_str()));
                    return -1;
                }
            }
            break;

        case DOMNode::ELEMENT_NODE:
        case DOMNode::PROCESSING_INSTRUCTION_NODE:
        case DOMNode::DOCUMENT_NODE:
        case DOMNode::ENTITY_REFERENCE_NODE:
        case DOMNode::CDATA_SECTION_NODE:
        case DOMNode::COMMENT_NODE:
        case DOMNode::DOCUMENT_TYPE_NODE:
        case DOMNode::ENTITY_NODE:
            break;
        default:
            break;
        }
    }

    return result;
}

//-----------------------------------------------------------------------------
// Parse LogSize element
//-----------------------------------------------------------------------------
int MELXmlParser::parseLogSizeElement(DOMNode * node,
                                      MelsecMemoryInfo& melmem)
{
    int result = 0;
    DOMNode * child;

    // Parse for the presence of children.
    for (child = node->getFirstChild(); child != NULL;
         child = child->getNextSibling())
    {
        int nodeType = child->getNodeType();
        switch (nodeType)
        {
        case DOMNode::TEXT_NODE:
            {
                string valStr = StrX(child->getNodeValue()).localForm();
                melmem.m_size = strtoul(valStr.c_str(), NULL, 0);
                if (melmem.m_size == 0)
                {
                    ACE_ERROR((LM_ERROR,
                        ACE_TEXT("LogSize(%s) is defined invalid value(%s).\n"),
                        melmem.m_name, valStr.c_str()));
                    return -1;
                }
            }
            break;

        case DOMNode::ELEMENT_NODE:
        case DOMNode::PROCESSING_INSTRUCTION_NODE:
        case DOMNode::DOCUMENT_NODE:
        case DOMNode::ENTITY_REFERENCE_NODE:
        case DOMNode::CDATA_SECTION_NODE:
        case DOMNode::COMMENT_NODE:
        case DOMNode::DOCUMENT_TYPE_NODE:
        case DOMNode::ENTITY_NODE:
            break;
        default:
            break;
        }
    }

    return result;
}

//-----------------------------------------------------------------------------
// Parse Devices element
//-----------------------------------------------------------------------------
int MELXmlParser::parseReadBlocksElm(DOMNode * node)
{
    ACE_UNUSED_ARG(node);

    int result = 0;
#ifdef PLC_MELSEC_SERVER
    DOMNode * child;
    int maxblock = 0;

    // Attributes: nothing

    // Parse for the presence of children.
    for (child = node->getFirstChild(); child != NULL;
         child = child->getNextSibling())
    {
        switch (child->getNodeType())
        {
        case DOMNode::ELEMENT_NODE:
            {
                string nameStr = StrX(child->getNodeName()).localForm();
                if (nameStr == _elmReadBlock)
                {
                    MelReadBlocks blocks;          // init. parameter area
                    blocks.m_multi = false;
                    blocks.m_words = 0;
                    blocks.m_buftop = NULL;
                    blocks.m_blocks.clear();
                    maxblock = 0;
                    result = parseReadBlockElm(child, blocks, maxblock);
                    if (result < 0)
                    {
                        return result;
                    }

                    // Entry block reader
                    if (! blocks.m_multi)
                    {
                        MelReadBlocks mbr;
                        int actq = (maxblock > 0) ? maxblock : blocks.m_blocks.size();
                        // separate block data
                        for (int j = 0; j < actq; j++)
                        {
                            mbr.m_multi = false;
                            mbr.m_blocks.clear();         // erase before blocks
                            mbr.m_words = blocks.m_blocks[j].m_words;
                            mbr.m_buftop = (u_short *)malloc(mbr.m_words * 2);
                            blocks.m_blocks[j].m_bufp = mbr.m_buftop;
                            mbr.m_blocks.push_back(blocks.m_blocks[j]);
                            m_readers.push_back(mbr);
                            mbr.m_buftop = NULL;          // buffer narrow copied
                        }
                    }
                    else
                    {
                        m_readers.push_back(blocks);
                        blocks.m_buftop = NULL;
                    }
                }
                else
                {
                    ACE_ERROR((LM_ERROR,
                        ACE_TEXT("MELXmlParser::parseReadBlocksElm: Invalid element name %s.\n"),
                        nameStr.c_str()));
                    return -1;
                }
            }
            break;

        case DOMNode::TEXT_NODE:
        case DOMNode::PROCESSING_INSTRUCTION_NODE:
        case DOMNode::DOCUMENT_NODE:
        case DOMNode::ENTITY_REFERENCE_NODE:
        case DOMNode::CDATA_SECTION_NODE:
        case DOMNode::COMMENT_NODE:
        case DOMNode::DOCUMENT_TYPE_NODE:
        case DOMNode::ENTITY_NODE:
            break;
        default:
            break;
        }
    }
#endif
    return result;
}

//-----------------------------------------------------------------------------
// Parse Device element
//-----------------------------------------------------------------------------
int MELXmlParser::parseReadBlockElm(DOMNode * node,
                                    MelReadBlocks& blocks, int& maxblock)
{
    ACE_UNUSED_ARG(node);
    ACE_UNUSED_ARG(blocks);
    ACE_UNUSED_ARG(maxblock);

    int result = 0;
#ifdef PLC_MELSEC_SERVER
    DOMNode *  child;
    PLCDevice * plc;
    MelReadBlock rblock;

    DOMNamedNodeMap * attributes = node->getAttributes();
    int attrCount = attributes->getLength();
    for (int i = 0; i < attrCount; i++)
    {
        DOMNode * attribute = attributes->item(i);
        string nameStr = StrX(attribute->getNodeName()).localForm();
        string valStr  = StrX(attribute->getNodeValue()).localForm();
        if (nameStr == ACE_TEXT("maxblock"))
        {
            maxblock = strtol(valStr.c_str(), NULL, 10);
            if (maxblock < 0)
            {
                ACE_ERROR((LM_ERROR,
                    ACE_TEXT("ReadBlock is defined invalid count(%s).\n"),
                    valStr.c_str()));
                return -1;
            }
        }
        else
        {
            ACE_ERROR((LM_ERROR,
                ACE_TEXT("ReadBlock is defined invalid attribute name(%s).\n"),
                nameStr.c_str()));
            return -1;
        }
    }

    // Parse for the presence of children.
    for (child = node->getFirstChild(); child != NULL;
         child = child->getNextSibling())
    {
        int nodeType = child->getNodeType();
        switch (nodeType)
        {
        case DOMNode::ELEMENT_NODE:
            {
                string nameStr = StrX(child->getNodeName()).localForm();
                if (nameStr == _elmReadDevice)
                {
                    result = parseReadDeviceElm(child, rblock);
                    if (result >= 0)
                    {
                        blocks.m_words += rblock.m_words;
                        blocks.m_blocks.push_back(rblock);   // enter to return area
                    }
                }
            }
            break;

        case DOMNode::TEXT_NODE:
        case DOMNode::PROCESSING_INSTRUCTION_NODE:
        case DOMNode::DOCUMENT_NODE:
        case DOMNode::ENTITY_REFERENCE_NODE:
        case DOMNode::CDATA_SECTION_NODE:
        case DOMNode::COMMENT_NODE:
        case DOMNode::DOCUMENT_TYPE_NODE:
        case DOMNode::ENTITY_NODE:
            break;
        default:
            break;
        }

    }

    if (blocks.m_blocks.size() > 1)
    {
        blocks.m_multi = true;
        blocks.m_buftop = (u_short *)malloc(blocks.m_words * 2);
        unsigned long offset = 0;
        for (u_int i = 0; i < blocks.m_blocks.size(); i++)
        {
            blocks.m_blocks[i].m_bufp = blocks.m_buftop + offset;
            offset += blocks.m_blocks[i].m_words;
        }
    }
    else /* if (blocks.m_blocks.size() == 1) */
    {
        blocks.m_multi = false;

        plc = blocks.m_blocks[0].m_plc;
        size_t unitq = (plc->isBit()) ? 16 : 1;
        rblock.m_plc = plc;
        rblock.m_bufp = NULL;
        size_t restsize = blocks.m_words;
        if (blocks.m_words >= 32768)
        {
            blocks.m_blocks.clear();        // aband first block

            // divition of this memory into three blocks
            long curpos = 0;
            int  curblock = 1;
            while (restsize > 0)
            {
                rblock.m_top = curpos;
                rblock.m_datalen = 0;
                // divide block
                if ((curblock % 3) != 0)
                {   // As block is first or second, block size is 0x3000
                    rblock.m_words = (0x3000 <= restsize) ? 0x3000 : restsize;
                }
                else // if ((curblock % 3) == 0)
                {   // block size is 0x2000
                    rblock.m_words = (0x2000 <= restsize) ? 0x2000 : restsize;
                }
                restsize -= rblock.m_words;
                rblock.m_datalen = (rblock.m_words * unitq);

                blocks.m_blocks.push_back(rblock);

                curpos += rblock.m_datalen;
                curblock++;
            }
        }
        else if (blocks.m_words >= 16384)
        {
            // divide by 2
            blocks.m_blocks[0].m_words = 0x3000;
            blocks.m_blocks[0].m_datalen = (blocks.m_blocks[0].m_words * unitq);
            blocks.m_blocks[0].m_top = 0;
            blocks.m_blocks[0].m_bufp = NULL;

            rblock.m_plc = plc;
            rblock.m_words = blocks.m_words - 0x3000;
            rblock.m_datalen = (rblock.m_words * unitq);
            rblock.m_top = blocks.m_blocks[0].m_datalen;
            rblock.m_bufp = NULL;
            blocks.m_blocks.push_back(rblock);
        }
        else
        {   // only one block
            blocks.m_blocks[0].m_words = blocks.m_words;
            blocks.m_blocks[0].m_datalen = (blocks.m_blocks[0].m_words * unitq);
            blocks.m_blocks[0].m_top = 0;
            blocks.m_blocks[0].m_bufp = NULL;
        }
    }
#endif
    return result;
}

//-----------------------------------------------------------------------------
// Parse Device element
//-----------------------------------------------------------------------------
int MELXmlParser::parseReadDeviceElm(DOMNode * node, MelReadBlock& rblock)
{
    ACE_UNUSED_ARG(node);
    ACE_UNUSED_ARG(rblock);

    int result = 0;
#ifdef PLC_MELSEC_SERVER
    DOMNode *  child;
    PLCDevice * plc;

    // Parse for the presence of children.
    for (child = node->getFirstChild(); child != NULL;
         child = child->getNextSibling())
    {
        int nodeType = child->getNodeType();
        switch (nodeType)
        {
        case DOMNode::TEXT_NODE:
            {
                rblock.m_plc = NULL;
                rblock.m_top = 0;
                rblock.m_words = 0;
                rblock.m_bufp = NULL;
                rblock.m_datalen = 0;
                string valStr = StrX(child->getNodeValue()).localForm();
                plc = MELDeviceServer::instance()->get(valStr.c_str());
                if (plc == NULL)
                {   // Undefined
                    ACE_ERROR((LM_ERROR,
                        ACE_TEXT("ReadBlock is not defined device(%s).\n"),
                        valStr.c_str()));
                }
                else
                {
                    rblock.m_plc = plc;
                    rblock.m_datalen = plc->size();
                    rblock.m_words = plc->words();
                }
            }
            break;

        case DOMNode::ELEMENT_NODE:
        case DOMNode::PROCESSING_INSTRUCTION_NODE:
        case DOMNode::DOCUMENT_NODE:
        case DOMNode::ENTITY_REFERENCE_NODE:
        case DOMNode::CDATA_SECTION_NODE:
        case DOMNode::COMMENT_NODE:
        case DOMNode::DOCUMENT_TYPE_NODE:
        case DOMNode::ENTITY_NODE:
            break;
        default:
            break;
        }

    }

#endif
    return result;
}


