<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: attr.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: ihi $ $Date: 2008-02-04 13:55:45 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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 library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include "attr.hxx"
#include "element.hxx"
#include <com/sun/star/xml/dom/DOMException.hdl>
#include <string.h>

namespace DOM
{
    CAttr::CAttr(const xmlAttrPtr pAttr)
    {
        m_aAttrPtr = pAttr;
        m_aNodeType = NodeType_ATTRIBUTE_NODE;
        init_node((xmlNodePtr)pAttr);
    }

    OUString SAL_CALL CAttr::getNodeName()
        throw (RuntimeException)
    {
        return getName();
    }
    OUString SAL_CALL CAttr::getNodeValue()
        throw (RuntimeException)
    {
        return getValue();
    }

    /**
    Returns the name of this attribute.
    */
    OUString SAL_CALL CAttr::getName() throw (RuntimeException)
    {
        OUString aName;
        if (m_aAttrPtr != NULL)
        {
            aName = OUString((char*)m_aAttrPtr->name, strlen((char*)m_aAttrPtr->name), RTL_TEXTENCODING_UTF8);
        }
        return aName;
    }

    /**
    The Element node this attribute is attached to or null if this
    attribute is not in use.
    */
    Reference< XElement > SAL_CALL CAttr::getOwnerElement()
        throw (RuntimeException)
    {
        Reference< XElement > aElement;
        if (m_aAttrPtr != NULL && m_aAttrPtr->parent != NULL)
        {
            aElement = Reference< XElement >(static_cast< CElement* >(CNode::get(m_aAttrPtr->parent)));
        }
        return aElement;
    }

    /**
    If this attribute was explicitly given a value in the original
    document, this is true; otherwise, it is false.
    */
    sal_Bool SAL_CALL CAttr::getSpecified()
        throw (RuntimeException)
    {
        // XXX what is this supposed do exactly?
        return sal_False;
    }

    /**
    On retrieval, the value of the attribute is returned as a string.
    */
    OUString SAL_CALL CAttr::getValue()
        throw (RuntimeException)
    {
        OUString aName;
        if (m_aAttrPtr != NULL && m_aAttrPtr->children != NULL)
        {
            aName = OUString((char*)m_aAttrPtr->children->content, strlen((char*)m_aAttrPtr->children->content),
                RTL_TEXTENCODING_UTF8);
        }
        return aName;
    }

    /**
    Sets the value of the attribute from a string.
    */
    void SAL_CALL CAttr::setValue(const OUString& value)
        throw (RuntimeException, DOMException)
    {
        // remember old value (for mutation event)
        OUString sOldValue = getValue();

        OString o1 = OUStringToOString(value, RTL_TEXTENCODING_UTF8);
        xmlChar* xValue = (xmlChar*)o1.getStr();
        // xmlChar* xName = OUStringToOString(m_aAttrPtr->name, RTL_TEXTENCODING_UTF8).getStr();
        // this does not work if the attribute was created anew
        // xmlNodePtr pNode = m_aAttrPtr->parent;
        // xmlSetProp(pNode, m_aAttrPtr->name, xValue);
        xmlChar *buffer = xmlEncodeEntitiesReentrant(m_aAttrPtr->doc, xValue);
        m_aAttrPtr->children = xmlStringGetNodeList(m_aAttrPtr->doc, buffer);
        xmlNodePtr tmp = m_aAttrPtr->children;
        while (tmp != NULL) {
            tmp->parent = (xmlNodePtr) m_aNodePtr;
            tmp->doc = m_aAttrPtr->doc;
            if (tmp->next == NULL)
                m_aNodePtr->last = tmp;
            tmp = tmp->next;
        }

        // dispatch DOM events to signal change in attribute value
        // dispatch DomAttrModified + DOMSubtreeModified
        OUString sEventName( RTL_CONSTASCII_USTRINGPARAM("DOMAttrModified") );
        Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
        Reference< XMutationEvent > event(docevent->createEvent(sEventName),UNO_QUERY);
        event->initMutationEvent(
                sEventName, sal_True, sal_False,
                Reference<XNode>( static_cast<XAttr*>( this ) ),
                sOldValue, value, getName(), AttrChangeType_MODIFICATION );
        dispatchEvent(Reference< XEvent >(event, UNO_QUERY));
        dispatchSubtreeModified();
        xmlFree(buffer);
    }

}
<commit_msg>INTEGRATION: CWS custommeta (1.6.58); FILE MERGED 2008/02/26 10:40:38 mst 1.6.58.3: RESYNC: (1.7-1.8); FILE MERGED 2008/02/01 10:36:04 mst 1.6.58.2: RESYNC: (1.6-1.7); FILE MERGED 2007/12/07 14:05:56 mst 1.6.58.1: - unoxml/source/dom/document.{hxx,cxx}:   implement interface css::xml::sax::XSAXSerializable - unoxml/source/dom/*.{hxx,cxx}:   add virtual method saxify() on all subclasses of CNode   add missing implementations of getLocalName()<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: attr.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: obo $ $Date: 2008-02-26 14:46:45 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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 library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include "attr.hxx"
#include "element.hxx"
#include <com/sun/star/xml/dom/DOMException.hdl>
#include <string.h>

namespace DOM
{
    CAttr::CAttr(const xmlAttrPtr pAttr)
    {
        m_aAttrPtr = pAttr;
        m_aNodeType = NodeType_ATTRIBUTE_NODE;
        init_node((xmlNodePtr)pAttr);
    }

    OUString SAL_CALL CAttr::getNodeName()
        throw (RuntimeException)
    {
        return getName();
    }
    OUString SAL_CALL CAttr::getNodeValue()
        throw (RuntimeException)
    {
        return getValue();
    }
    OUString SAL_CALL CAttr::getLocalName()
        throw (RuntimeException)
    {
        return getName();
    }

    /**
    Returns the name of this attribute.
    */
    OUString SAL_CALL CAttr::getName() throw (RuntimeException)
    {
        OUString aName;
        if (m_aAttrPtr != NULL)
        {
            aName = OUString((char*)m_aAttrPtr->name, strlen((char*)m_aAttrPtr->name), RTL_TEXTENCODING_UTF8);
        }
        return aName;
    }

    /**
    The Element node this attribute is attached to or null if this
    attribute is not in use.
    */
    Reference< XElement > SAL_CALL CAttr::getOwnerElement()
        throw (RuntimeException)
    {
        Reference< XElement > aElement;
        if (m_aAttrPtr != NULL && m_aAttrPtr->parent != NULL)
        {
            aElement = Reference< XElement >(static_cast< CElement* >(CNode::get(m_aAttrPtr->parent)));
        }
        return aElement;
    }

    /**
    If this attribute was explicitly given a value in the original
    document, this is true; otherwise, it is false.
    */
    sal_Bool SAL_CALL CAttr::getSpecified()
        throw (RuntimeException)
    {
        // XXX what is this supposed do exactly?
        return sal_False;
    }

    /**
    On retrieval, the value of the attribute is returned as a string.
    */
    OUString SAL_CALL CAttr::getValue()
        throw (RuntimeException)
    {
        OUString aName;
        if (m_aAttrPtr != NULL && m_aAttrPtr->children != NULL)
        {
            aName = OUString((char*)m_aAttrPtr->children->content, strlen((char*)m_aAttrPtr->children->content),
                RTL_TEXTENCODING_UTF8);
        }
        return aName;
    }

    /**
    Sets the value of the attribute from a string.
    */
    void SAL_CALL CAttr::setValue(const OUString& value)
        throw (RuntimeException, DOMException)
    {
        // remember old value (for mutation event)
        OUString sOldValue = getValue();

        OString o1 = OUStringToOString(value, RTL_TEXTENCODING_UTF8);
        xmlChar* xValue = (xmlChar*)o1.getStr();
        // xmlChar* xName = OUStringToOString(m_aAttrPtr->name, RTL_TEXTENCODING_UTF8).getStr();
        // this does not work if the attribute was created anew
        // xmlNodePtr pNode = m_aAttrPtr->parent;
        // xmlSetProp(pNode, m_aAttrPtr->name, xValue);
        xmlChar *buffer = xmlEncodeEntitiesReentrant(m_aAttrPtr->doc, xValue);
        m_aAttrPtr->children = xmlStringGetNodeList(m_aAttrPtr->doc, buffer);
        xmlNodePtr tmp = m_aAttrPtr->children;
        while (tmp != NULL) {
            tmp->parent = (xmlNodePtr) m_aNodePtr;
            tmp->doc = m_aAttrPtr->doc;
            if (tmp->next == NULL)
                m_aNodePtr->last = tmp;
            tmp = tmp->next;
        }

        // dispatch DOM events to signal change in attribute value
        // dispatch DomAttrModified + DOMSubtreeModified
        OUString sEventName( RTL_CONSTASCII_USTRINGPARAM("DOMAttrModified") );
        Reference< XDocumentEvent > docevent(getOwnerDocument(), UNO_QUERY);
        Reference< XMutationEvent > event(docevent->createEvent(sEventName),UNO_QUERY);
        event->initMutationEvent(
                sEventName, sal_True, sal_False,
                Reference<XNode>( static_cast<XAttr*>( this ) ),
                sOldValue, value, getName(), AttrChangeType_MODIFICATION );
        dispatchEvent(Reference< XEvent >(event, UNO_QUERY));
        dispatchSubtreeModified();
        xmlFree(buffer);
    }

}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Log$
 * Revision 1.10  2001/08/01 19:11:01  tng
 * Add full schema constraint checking flag to the samples and the parser.
 *
 * Revision 1.9  2001/05/11 13:24:55  tng
 * Copyright update.
 *
 * Revision 1.8  2001/05/03 15:59:40  tng
 * Schema: samples update with schema
 *
 * Revision 1.7  2000/09/11 18:43:48  aruna1
 * OS390 related updates
 *
 * Revision 1.6  2000/03/02 19:53:42  roddey
 * This checkin includes many changes done while waiting for the
 * 1.1.0 code to be finished. I can't list them all here, but a list is
 * available elsewhere.
 *
 * Revision 1.5  2000/02/11 02:37:01  abagchi
 * Removed StrX::transcode
 *
 * Revision 1.4  2000/02/06 07:47:19  rahulj
 * Year 2K copyright swat.
 *
 * Revision 1.3  2000/01/12 00:27:00  roddey
 * Updates to work with the new URL and input source scheme.
 *
 * Revision 1.2  1999/11/20 01:09:55  rahulj
 * Fixed usage message.
 *
 * Revision 1.1.1.1  1999/11/09 01:09:49  twl
 * Initial checkin
 *
 * Revision 1.7  1999/11/08 20:43:36  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

/**
 * This sample program illustrates how one can use a memory buffer as the
 * input to parser. The memory buffer contains raw bytes representing XML
 * statements.
 *
 * Look at the API documentation for 'MemBufInputSource' for more information
 * on parameters to the constructor.
 *
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <parsers/SAXParser.hpp>
#include <framework/MemBufInputSource.hpp>
#include "MemParse.hpp"

// ---------------------------------------------------------------------------
//  Local const data
//
//  gXMLInMemBuf
//      Defines the memory buffer contents here which parsed by the XML
//      parser. This is the cheap way to do it, instead of reading it from
//      somewhere. For this demo, its fine.
//
//      NOTE: This will NOT work if your compiler's default char type is not
//      ASCII, since we indicate in the encoding that its ascii.
//
//  gMemBufId
//      A simple name to give as the system id for the memory buffer. This
//      just for indentification purposes in case of errors. Its not a real
//      system id (and the parser knows that.)
// ---------------------------------------------------------------------------

#ifdef OS390
static const char*  gXMLInMemBuf =
"\
<?xml version='1.0' encoding='ibm-1047-s390'?>\n\
<!DOCTYPE company [\n\
<!ELEMENT company     (product,category,developedAt)>\n\
<!ELEMENT product     (#PCDATA)>\n\
<!ELEMENT category    (#PCDATA)>\n\
<!ATTLIST category idea CDATA #IMPLIED>\n\
<!ELEMENT developedAt (#PCDATA)>\n\
]>\n\n\
<company>\n\
    <product>XML4C</product>\n\
    <category idea='great'>XML Parsing Tools</category>\n\
    <developedAt>\n\
      IBM Center for Java Technology, Silicon Valley, Cupertino, CA\n\
    </developedAt>\n\
</company>\
";
#else
static const char*  gXMLInMemBuf =
"\
<?xml version='1.0' encoding='ascii'?>\n\
<!DOCTYPE company [\n\
<!ELEMENT company     (product,category,developedAt)>\n\
<!ELEMENT product     (#PCDATA)>\n\
<!ELEMENT category    (#PCDATA)>\n\
<!ATTLIST category idea CDATA #IMPLIED>\n\
<!ELEMENT developedAt (#PCDATA)>\n\
]>\n\n\
<company>\n\
    <product>XML4C</product>\n\
    <category idea='great'>XML Parsing Tools</category>\n\
    <developedAt>\n\
      IBM Center for Java Technology, Silicon Valley, Cupertino, CA\n\
    </developedAt>\n\
</company>\
";
#endif

static const char*  gMemBufId = "prodInfo";

// ---------------------------------------------------------------------------
//  Local helper methods
// ---------------------------------------------------------------------------
void usage()
{
    cout << "\nUsage:\n"
         << "    MemParse [-v]\n"
         << "This program uses the SAX Parser to parse a memory buffer\n"
         << "containing XML statements, and reports the number of\n"
         << "elements and attributes found.\n"
         << "\nOptions:\n"
         << "    -v=xxx      Validation scheme [always | never | auto*]\n"
         << "    -n          Enable namespace processing. Defaults to off.\n"
         << "    -s          Enable schema processing. Defaults to off.\n"
         << "    -f          Enable full schema constraint checking. Defaults to off.\n\n"
         << "  * = Default if not provided explicitly\n"
         << endl;
}

// ---------------------------------------------------------------------------
//  Program entry point
// ---------------------------------------------------------------------------
int main(int argC, char* argV[])
{
    // Initialize the XML4C2 system
    try
    {
         XMLPlatformUtils::Initialize();
    }
    catch (const XMLException& toCatch)
    {
         cerr << "Error during initialization! Message:\n"
              << StrX(toCatch.getMessage()) << endl;
         return 1;
    }

    SAXParser::ValSchemes    valScheme = SAXParser::Val_Auto;
    bool doNamespaces       = false;
    bool doSchema           = false;
    bool schemaFullChecking = false;
    if (argC > 1)
    {
        // See if non validating dom parser configuration is requested.
        if ((argC == 2) && !strcmp(argV[1], "-?"))
        {
            usage();
            return 2;
        }

        int argInd;
        for (argInd = 1; argInd < argC; argInd++)
        {
            if (!strncmp(argV[argInd], "-v=", 3)
            ||  !strncmp(argV[argInd], "-V=", 3))
            {
                const char* const parm = &argV[argInd][3];

                if (!strcmp(parm, "never"))
                    valScheme = SAXParser::Val_Never;
                else if (!strcmp(parm, "auto"))
                    valScheme = SAXParser::Val_Auto;
                else if (!strcmp(parm, "always"))
                    valScheme = SAXParser::Val_Always;
                else
                {
                    cerr << "Unknown -v= value: " << parm << endl;
                    return 2;
                }
            }
             else if (!strcmp(argV[argInd], "-n")
                  ||  !strcmp(argV[argInd], "-N"))
            {
                doNamespaces = true;
            }
             else if (!strcmp(argV[argInd], "-s")
                  ||  !strcmp(argV[argInd], "-S"))
            {
                doSchema = true;
            }
             else if (!strcmp(argV[argInd], "-f")
                  ||  !strcmp(argV[argInd], "-F"))
            {
                schemaFullChecking = true;
            }
             else
            {
                cerr << "Unknown option '" << argV[argInd]
                     << "', ignoring it\n" << endl;
            }
        }
    }

    //
    //  Create a SAX parser object. Then, according to what we were told on
    //  the command line, set it to validate or not.
    //
    SAXParser parser;
    parser.setValidationScheme(valScheme);
    parser.setDoNamespaces(doNamespaces);
    parser.setDoSchema(doSchema);
    parser.setValidationSchemaFullChecking(schemaFullChecking);

    //
    //  Create our SAX handler object and install it on the parser, as the
    //  document and error handlers.
    //
    MemParseHandlers handler;
    parser.setDocumentHandler(&handler);
    parser.setErrorHandler(&handler);

    //
    //  Create MemBufferInputSource from the buffer containing the XML
    //  statements.
    //
    //  NOTE: We are using strlen() here, since we know that the chars in
    //  our hard coded buffer are single byte chars!!! The parameter wants
    //  the number of BYTES, not chars, so when you create a memory buffer
    //  give it the byte size (which just happens to be the same here.)
    //
    MemBufInputSource* memBufIS = new MemBufInputSource
    (
        (const XMLByte*)gXMLInMemBuf
        , strlen(gXMLInMemBuf)
        , gMemBufId
        , false
    );

    //
    //  Get the starting time and kick off the parse of the indicated
    //  file. Catch any exceptions that might propogate out of it.
    //
    unsigned long duration;
    try
    {
        const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
        parser.parse(*memBufIS);
        const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
        duration = endMillis - startMillis;
    }

    catch (const XMLException& e)
    {
        cerr << "\nError during parsing memory stream:\n"
             << "Exception message is:  \n"
             << StrX(e.getMessage()) << "\n" << endl;
        return -1;
    }

    // Print out the stats that we collected and time taken.
    cout << "\nFinished parsing the memory buffer containing the following "
         << "XML statements:\n\n"
         << gXMLInMemBuf
         << "\n\n\n"
         << "Parsing took " << duration << " ms ("
         << handler.getElementCount() << " elements, "
         << handler.getAttrCount() << " attributes, "
         << handler.getSpaceCount() << " spaces, "
         << handler.getCharacterCount() << " characters).\n" << endl;

    // And call the termination method
    XMLPlatformUtils::Terminate();

    return 0;
}

<commit_msg>Pulled the hardcoded "encoding" out of the document itself and made it a #define to make it easier to support other encodings.  Patch from David McCreedy. And other modification for consistent help display and return code across samples.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Log$
 * Revision 1.11  2001/10/19 18:56:08  tng
 * Pulled the hardcoded "encoding" out of the document itself and made it a #define
 * to make it easier to support other encodings.  Patch from David McCreedy.
 * And other modification for consistent help display and return code across samples.
 *
 * Revision 1.10  2001/08/01 19:11:01  tng
 * Add full schema constraint checking flag to the samples and the parser.
 *
 * Revision 1.9  2001/05/11 13:24:55  tng
 * Copyright update.
 *
 * Revision 1.8  2001/05/03 15:59:40  tng
 * Schema: samples update with schema
 *
 * Revision 1.7  2000/09/11 18:43:48  aruna1
 * OS390 related updates
 *
 * Revision 1.6  2000/03/02 19:53:42  roddey
 * This checkin includes many changes done while waiting for the
 * 1.1.0 code to be finished. I can't list them all here, but a list is
 * available elsewhere.
 *
 * Revision 1.5  2000/02/11 02:37:01  abagchi
 * Removed StrX::transcode
 *
 * Revision 1.4  2000/02/06 07:47:19  rahulj
 * Year 2K copyright swat.
 *
 * Revision 1.3  2000/01/12 00:27:00  roddey
 * Updates to work with the new URL and input source scheme.
 *
 * Revision 1.2  1999/11/20 01:09:55  rahulj
 * Fixed usage message.
 *
 * Revision 1.1.1.1  1999/11/09 01:09:49  twl
 * Initial checkin
 *
 * Revision 1.7  1999/11/08 20:43:36  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

/**
 * This sample program illustrates how one can use a memory buffer as the
 * input to parser. The memory buffer contains raw bytes representing XML
 * statements.
 *
 * Look at the API documentation for 'MemBufInputSource' for more information
 * on parameters to the constructor.
 *
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <parsers/SAXParser.hpp>
#include <framework/MemBufInputSource.hpp>
#include "MemParse.hpp"

// ---------------------------------------------------------------------------
//  Local const data
//
//  gXMLInMemBuf
//      Defines the memory buffer contents here which parsed by the XML
//      parser. This is the cheap way to do it, instead of reading it from
//      somewhere. For this demo, its fine.
//
//      NOTE: If your encoding is not ascii you will need to change
//            the MEMPARSE_ENCODING #define
//
//  gMemBufId
//      A simple name to give as the system id for the memory buffer. This
//      just for indentification purposes in case of errors. Its not a real
//      system id (and the parser knows that.)
// ---------------------------------------------------------------------------

#ifndef MEMPARSE_ENCODING
   #if defined(OS390)
      #define MEMPARSE_ENCODING "ibm-1047-s390"
   #else
      #define MEMPARSE_ENCODING "ascii"
   #endif
#endif /* ifndef MEMPARSE_ENCODING */

static const char*  gXMLInMemBuf =
"\
<?xml version='1.0' encoding='" MEMPARSE_ENCODING "'?>\n\
<!DOCTYPE company [\n\
<!ELEMENT company     (product,category,developedAt)>\n\
<!ELEMENT product     (#PCDATA)>\n\
<!ELEMENT category    (#PCDATA)>\n\
<!ATTLIST category idea CDATA #IMPLIED>\n\
<!ELEMENT developedAt (#PCDATA)>\n\
]>\n\n\
<company>\n\
    <product>XML4C</product>\n\
    <category idea='great'>XML Parsing Tools</category>\n\
    <developedAt>\n\
      IBM Center for Java Technology, Silicon Valley, Cupertino, CA\n\
    </developedAt>\n\
</company>\
";

static const char*  gMemBufId = "prodInfo";

// ---------------------------------------------------------------------------
//  Local helper methods
// ---------------------------------------------------------------------------
void usage()
{
    cout << "\nUsage:\n"
            "    MemParse [options]\n\n"
            "This program uses the SAX Parser to parse a memory buffer\n"
            "containing XML statements, and reports the number of\n"
            "elements and attributes found.\n\n"
            "Options:\n"
            "    -v=xxx      Validation scheme [always | never | auto*].\n"
            "    -n          Enable namespace processing. Defaults to off.\n"
            "    -s          Enable schema processing. Defaults to off.\n"
            "    -f          Enable full schema constraint checking. Defaults to off.\n"
		      "    -?          Show this help.\n\n"
            "  * = Default if not provided explicitly.\n"
         << endl;
}

// ---------------------------------------------------------------------------
//  Program entry point
// ---------------------------------------------------------------------------
int main(int argC, char* argV[])
{
    // Initialize the XML4C2 system
    try
    {
         XMLPlatformUtils::Initialize();
    }
    catch (const XMLException& toCatch)
    {
         cerr << "Error during initialization! Message:\n"
              << StrX(toCatch.getMessage()) << endl;
         return 1;
    }

    SAXParser::ValSchemes    valScheme = SAXParser::Val_Auto;
    bool doNamespaces       = false;
    bool doSchema           = false;
    bool schemaFullChecking = false;

    int argInd;
    for (argInd = 1; argInd < argC; argInd++)
    {
        // Break out on first parm not starting with a dash
        if (argV[argInd][0] != '-')
        {
            usage();
            XMLPlatformUtils::Terminate();
            return 1;
        }

        // Watch for special case help request
        if (!strcmp(argV[argInd], "-?"))
        {
            usage();
            XMLPlatformUtils::Terminate();
            return 1;
        }
         else if (!strncmp(argV[argInd], "-v=", 3)
              ||  !strncmp(argV[argInd], "-V=", 3))
        {
            const char* const parm = &argV[argInd][3];

            if (!strcmp(parm, "never"))
                valScheme = SAXParser::Val_Never;
            else if (!strcmp(parm, "auto"))
                valScheme = SAXParser::Val_Auto;
            else if (!strcmp(parm, "always"))
                valScheme = SAXParser::Val_Always;
            else
            {
                cerr << "Unknown -v= value: " << parm << endl;
                return 2;
            }
        }
         else if (!strcmp(argV[argInd], "-n")
              ||  !strcmp(argV[argInd], "-N"))
        {
            doNamespaces = true;
        }
         else if (!strcmp(argV[argInd], "-s")
              ||  !strcmp(argV[argInd], "-S"))
        {
            doSchema = true;
        }
         else if (!strcmp(argV[argInd], "-f")
              ||  !strcmp(argV[argInd], "-F"))
        {
            schemaFullChecking = true;
        }
         else
        {
            cerr << "Unknown option '" << argV[argInd]
                 << "', ignoring it\n" << endl;
        }
    }

    //
    //  Create a SAX parser object. Then, according to what we were told on
    //  the command line, set it to validate or not.
    //
    SAXParser parser;
    parser.setValidationScheme(valScheme);
    parser.setDoNamespaces(doNamespaces);
    parser.setDoSchema(doSchema);
    parser.setValidationSchemaFullChecking(schemaFullChecking);

    //
    //  Create our SAX handler object and install it on the parser, as the
    //  document and error handlers.
    //
    MemParseHandlers handler;
    parser.setDocumentHandler(&handler);
    parser.setErrorHandler(&handler);

    //
    //  Create MemBufferInputSource from the buffer containing the XML
    //  statements.
    //
    //  NOTE: We are using strlen() here, since we know that the chars in
    //  our hard coded buffer are single byte chars!!! The parameter wants
    //  the number of BYTES, not chars, so when you create a memory buffer
    //  give it the byte size (which just happens to be the same here.)
    //
    MemBufInputSource* memBufIS = new MemBufInputSource
    (
        (const XMLByte*)gXMLInMemBuf
        , strlen(gXMLInMemBuf)
        , gMemBufId
        , false
    );

    //
    //  Get the starting time and kick off the parse of the indicated
    //  file. Catch any exceptions that might propogate out of it.
    //
    unsigned long duration;
    int errorCount = 0;
    try
    {
        const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
        parser.parse(*memBufIS);
        const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
        duration = endMillis - startMillis;
        errorCount = parser.getErrorCount();
    }

    catch (const XMLException& e)
    {
        cerr << "\nError during parsing memory stream:\n"
             << "Exception message is:  \n"
             << StrX(e.getMessage()) << "\n" << endl;
        return 4;
    }

    // Print out the stats that we collected and time taken.
    if (!errorCount) {
        cout << "\nFinished parsing the memory buffer containing the following "
             << "XML statements:\n\n"
             << gXMLInMemBuf
             << "\n\n\n"
             << "Parsing took " << duration << " ms ("
             << handler.getElementCount() << " elements, "
             << handler.getAttrCount() << " attributes, "
             << handler.getSpaceCount() << " spaces, "
             << handler.getCharacterCount() << " characters).\n" << endl;
    }

    // And call the termination method
    XMLPlatformUtils::Terminate();

    if (errorCount > 0)
        return 4;
    else
        return 0;
}

<|endoftext|>


<commit_before>/*************************************************************************
 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT7_RAttrAxis
#define ROOT7_RAttrAxis

#include <ROOT/RAttrBase.hxx>
#include <ROOT/RAttrLine.hxx>
#include <ROOT/RAttrText.hxx>
#include <ROOT/RAttrValue.hxx>
#include <ROOT/RPadLength.hxx>
#include <cmath>

namespace ROOT {
namespace Experimental {

/** \class RAttrAxis
\ingroup GpadROOT7
\author Sergey Linev <s.linev@gsi.de>
\date 2020-02-20
\brief All supported axes attributes for: line, ticks, labels, title, min/max, log, reverse, ...
\warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback is welcome!
*/

class RAttrAxis : public RAttrBase {

   RAttrValue<double> fMin{this, "min", 0.};                             ///<! axis min
   RAttrValue<double> fMax{this, "max", 0.};                             ///<! axis max
   RAttrValue<double> fZoomMin{this, "zoommin", 0.};                     ///<! axis zoom min
   RAttrValue<double> fZoomMax{this, "zoommax", 0.};                     ///<! axis zoom max
   RAttrValue<double> fLog{this, "log", 0};                              ///<! log scale, <1 off, 1 - base10, 2 - base 2, 2.71 - exp, 3, 4, ...
   RAttrValue<bool> fReverse{this, "reverse", false};                    ///<! reverse scale
   RAttrValue<bool> fTimeDisplay{this, "time", false};                   ///<! time display
   RAttrValue<double> fTimeOffset{this, "time_offset", 0};               ///<! time offset to display
   RAttrValue<std::string> fTimeFormat{this, "time_format", ""};         ///<! time format
   RAttrLine fAttrLine{this, "line"};                                    ///<! line attributes
   RAttrValue<std::string> fEndingStyle{this, "ending_style", ""};       ///<! axis ending style - none, arrow, circle
   RAttrValue<RPadLength> fEndingSize{this, "ending_size", 0.02_normal}; ///<! axis ending size
   RAttrValue<std::string> fTicksSide{this, "ticks_side", "normal"};     ///<! ticks position - normal, invert, both
   RAttrValue<RPadLength> fTicksSize{this, "ticks_size", 0.02_normal};   ///<! ticks size
   RAttrValue<RColor> fTicksColor{this, "ticks_color", RColor::kBlack};  ///<! ticks color
   RAttrValue<int> fTicksWidth{this, "ticks_width", 1};                  ///<! ticks width
   RAttrText fLabelsAttr{this, "labels"};                                ///<! text attributes for labels
   RAttrValue<RPadLength> fLabelsOffset{this, "labels_offset", {}};      ///<! axis labels offset - relative
   RAttrValue<bool> fLabelsCenter{this, "labels_center", false};         ///<! center labels
   RAttrText fTitleAttr{this, "title"};                                  ///<! axis title text attributes
   RAttrValue<std::string> fTitle{this, "title", ""};                    ///<! axis title
   RAttrValue<std::string> fTitlePos{this, "title_position", "right"};   ///<! axis title position - left, right, center
   RAttrValue<RPadLength> fTitleOffset{this, "title_offset", {}};        ///<! axis title offset - relative

   R__ATTR_CLASS(RAttrAxis, "axis");

   RAttrAxis &SetMin(double min) { fMin = min; return *this; }
   RAttrAxis &SetMax(double max) { fMax = max; return *this; }
   double GetMin() const { return fMin; }
   double GetMax() const { return fMax; }
   bool HasMin() const { return fMin.Has(); }
   bool HasMax() const { return fMax.Has(); }

   RAttrAxis &SetMinMax(double min, double max) { SetMin(min); SetMax(max); return *this; }
   void ClearMinMax() { fMin.Clear(); fMax.Clear(); }

   RAttrAxis &SetZoomMin(double min) { fZoomMin = min; return *this; }
   RAttrAxis &SetZoomMax(double max) { fZoomMax = max; return *this; }
   double GetZoomMin() const { return fZoomMin; }
   double GetZoomMax() const { return fZoomMax; }
   bool HasZoomMin() const { return fZoomMin.Has(); }
   bool HasZoomMax() const { return fZoomMax.Has(); }

   RAttrAxis &SetZoom(double min, double max) { SetZoomMin(min); SetZoomMax(max); return *this; }
   void ClearZoom() { fZoomMin.Clear(); fZoomMax.Clear(); }

   RAttrAxis &SetLog(double base = 10) { fLog = (base < 1) ? 0 : base; return *this; }
   double GetLog() const { return fLog; }
   bool IsLogScale() const { return GetLog() > 0.999999; }
   bool IsLog10() const { auto l = GetLog(); return (std::fabs(l-1.) < 1e-6) || (std::fabs(l-10.) < 1e-6); }
   bool IsLog2() const { return std::fabs(GetLog() - 2.) < 1e-6; }
   bool IsLn() const { return std::fabs(GetLog() - 2.71828) < 0.1; }

   RAttrAxis &SetReverse(bool on = true) { fReverse = on; return *this; }
   bool GetReverse() const { return fReverse; }

   RAttrAxis &SetTimeDisplay(const std::string &fmt = "", double offset = -1)
   {
      fTimeDisplay = true;
      if (!fmt.empty()) fTimeFormat = fmt;
      if (offset >= 0) fTimeOffset = offset;
      return *this;
   }
   bool GetTimeDisplay() const { return fTimeDisplay; }
   void ClearTimeDisplay()
   {
      fTimeDisplay.Clear();
      fTimeOffset.Clear();
      fTimeFormat.Clear();
   }

   const RAttrLine &GetAttrLine() const { return fAttrLine; }
   RAttrAxis &SetAttrLine(const RAttrLine &line) { fAttrLine = line; return *this; }
   RAttrLine &AttrLine() { return fAttrLine; }

   RAttrAxis &SetEndingSize(const RPadLength &sz) { fEndingSize = sz; return *this; }
   RPadLength GetEndingSize() const { return fEndingSize; }

   RAttrAxis &SetEndingStyle(const std::string &st) { fEndingStyle = st; return *this; }
   RAttrAxis &SetEndingArrow() { return SetEndingStyle("arrow"); }
   RAttrAxis &SetEndingCircle() { return SetEndingStyle("cicrle"); }
   std::string GetEndingStyle() const { return fEndingStyle; }

   RAttrAxis &SetTicksSize(const RPadLength &sz) { fTicksSize = sz; return *this; }
   RPadLength GetTicksSize() const { return fTicksSize; }

   RAttrAxis &SetTicksSide(const std::string &side) { fTicksSide = side; return *this; }
   RAttrAxis &SetTicksNormal() { return SetTicksSide("normal"); }
   RAttrAxis &SetTicksInvert() { return SetTicksSide("invert"); }
   RAttrAxis &SetTicksBoth() { return SetTicksSide("both"); }
   std::string GetTicksSide() const { return fTicksSide; }

   RAttrAxis &SetTicksColor(const RColor &color) { fTicksColor = color; return *this; }
   RColor GetTicksColor() const { return fTicksColor; }

   RAttrAxis &SetTicksWidth(int width) { fTicksWidth = width; return *this; }
   int GetTicksWidth() const { return fTicksWidth; }

   RAttrAxis &SetLabelsOffset(const RPadLength &len) { fLabelsOffset = len; return *this; }
   RPadLength GetLabelsOffset() const { return fLabelsOffset; }

   const RAttrText &GetLabelsAttr() const { return fLabelsAttr; }
   RAttrAxis &SetLabelsAttr(const RAttrText &attr) { fLabelsAttr = attr; return *this; }
   RAttrText &LabelsAttr() { return fLabelsAttr; }

   RAttrAxis &SetLabelsCenter(bool on = true) { fLabelsCenter = on; return *this; }
   bool GetLabelsCenter() const { return fLabelsCenter; }

   const RAttrText &GetTitleAttr() const { return fTitleAttr; }
   RAttrAxis &SetTitleAttr(const RAttrText &attr) { fTitleAttr = attr; return *this; }
   RAttrText &TitleAttr() { return fTitleAttr; }

   RAttrAxis &SetTitle(const std::string &title) { fTitle = title; return *this; }
   std::string GetTitle() const { return fTitle; }

   RAttrAxis &SetTitlePos(const std::string &pos) { fTitlePos = pos; return *this; }
   RAttrAxis &SetTitleLeft() { return SetTitlePos("left"); }
   RAttrAxis &SetTitleCenter() { return SetTitlePos("center"); }
   RAttrAxis &SetTitleRight() { return SetTitlePos("right"); }
   std::string GetTitlePos() const { return fTitlePos; }

   RAttrAxis &SetTitleOffset(const RPadLength &len) { fTitleOffset = len; return *this; }
   RPadLength GetTitleOffset() const { return fTitleOffset; }
};

} // namespace Experimental
} // namespace ROOT

#endif
<commit_msg>[raxis] add symlog attribute for RAxis<commit_after>/*************************************************************************
 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT7_RAttrAxis
#define ROOT7_RAttrAxis

#include <ROOT/RAttrBase.hxx>
#include <ROOT/RAttrLine.hxx>
#include <ROOT/RAttrText.hxx>
#include <ROOT/RAttrValue.hxx>
#include <ROOT/RPadLength.hxx>
#include <cmath>

namespace ROOT {
namespace Experimental {

/** \class RAttrAxis
\ingroup GpadROOT7
\author Sergey Linev <s.linev@gsi.de>
\date 2020-02-20
\brief All supported axes attributes for: line, ticks, labels, title, min/max, log, reverse, ...
\warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback is welcome!
*/

class RAttrAxis : public RAttrBase {

   RAttrValue<double> fMin{this, "min", 0.};                             ///<! axis min
   RAttrValue<double> fMax{this, "max", 0.};                             ///<! axis max
   RAttrValue<double> fZoomMin{this, "zoommin", 0.};                     ///<! axis zoom min
   RAttrValue<double> fZoomMax{this, "zoommax", 0.};                     ///<! axis zoom max
   RAttrValue<double> fLog{this, "log", 0};                              ///<! log scale, <1 off, 1 - base10, 2 - base 2, 2.71 - exp, 3, 4, ...
   RAttrValue<double> fSymlog{this, "symlog", 0};                        ///<! symlog scale constant, 0 - off
   RAttrValue<bool> fReverse{this, "reverse", false};                    ///<! reverse scale
   RAttrValue<bool> fTimeDisplay{this, "time", false};                   ///<! time display
   RAttrValue<double> fTimeOffset{this, "time_offset", 0};               ///<! time offset to display
   RAttrValue<std::string> fTimeFormat{this, "time_format", ""};         ///<! time format
   RAttrLine fAttrLine{this, "line"};                                    ///<! line attributes
   RAttrValue<std::string> fEndingStyle{this, "ending_style", ""};       ///<! axis ending style - none, arrow, circle
   RAttrValue<RPadLength> fEndingSize{this, "ending_size", 0.02_normal}; ///<! axis ending size
   RAttrValue<std::string> fTicksSide{this, "ticks_side", "normal"};     ///<! ticks position - normal, invert, both
   RAttrValue<RPadLength> fTicksSize{this, "ticks_size", 0.02_normal};   ///<! ticks size
   RAttrValue<RColor> fTicksColor{this, "ticks_color", RColor::kBlack};  ///<! ticks color
   RAttrValue<int> fTicksWidth{this, "ticks_width", 1};                  ///<! ticks width
   RAttrText fLabelsAttr{this, "labels"};                                ///<! text attributes for labels
   RAttrValue<RPadLength> fLabelsOffset{this, "labels_offset", {}};      ///<! axis labels offset - relative
   RAttrValue<bool> fLabelsCenter{this, "labels_center", false};         ///<! center labels
   RAttrText fTitleAttr{this, "title"};                                  ///<! axis title text attributes
   RAttrValue<std::string> fTitle{this, "title", ""};                    ///<! axis title
   RAttrValue<std::string> fTitlePos{this, "title_position", "right"};   ///<! axis title position - left, right, center
   RAttrValue<RPadLength> fTitleOffset{this, "title_offset", {}};        ///<! axis title offset - relative

   R__ATTR_CLASS(RAttrAxis, "axis");

   RAttrAxis &SetMin(double min) { fMin = min; return *this; }
   RAttrAxis &SetMax(double max) { fMax = max; return *this; }
   double GetMin() const { return fMin; }
   double GetMax() const { return fMax; }
   bool HasMin() const { return fMin.Has(); }
   bool HasMax() const { return fMax.Has(); }

   RAttrAxis &SetMinMax(double min, double max) { SetMin(min); SetMax(max); return *this; }
   void ClearMinMax() { fMin.Clear(); fMax.Clear(); }

   RAttrAxis &SetZoomMin(double min) { fZoomMin = min; return *this; }
   RAttrAxis &SetZoomMax(double max) { fZoomMax = max; return *this; }
   double GetZoomMin() const { return fZoomMin; }
   double GetZoomMax() const { return fZoomMax; }
   bool HasZoomMin() const { return fZoomMin.Has(); }
   bool HasZoomMax() const { return fZoomMax.Has(); }

   RAttrAxis &SetZoom(double min, double max) { SetZoomMin(min); SetZoomMax(max); return *this; }
   void ClearZoom() { fZoomMin.Clear(); fZoomMax.Clear(); }

   RAttrAxis &SetLog(double base = 10) { fLog = (base < 1) ? 0 : base; return *this; }
   double GetLog() const { return fLog; }
   bool IsLogScale() const { return GetLog() > 0.999999; }
   bool IsLog10() const { auto l = GetLog(); return (std::fabs(l-1.) < 1e-6) || (std::fabs(l-10.) < 1e-6); }
   bool IsLog2() const { return std::fabs(GetLog() - 2.) < 1e-6; }
   bool IsLn() const { return std::fabs(GetLog() - 2.71828) < 0.1; }

   RAttrAxis &SetSymlog(double const_value = 0.01)
   {
      if (const_value <= 0.)
         fSymlog.Clear();
      else
         fSymlog = const_value;
      return *this;
   }
   double GetSymlog() const { return fSymlog; }
   bool HasSymlog() const { return fSymlog.Has(); }
   void ClearSymlog() { fSymlog.Clear(); }

   RAttrAxis &SetReverse(bool on = true) { fReverse = on; return *this; }
   bool GetReverse() const { return fReverse; }

   RAttrAxis &SetTimeDisplay(const std::string &fmt = "", double offset = -1)
   {
      fTimeDisplay = true;
      if (!fmt.empty()) fTimeFormat = fmt;
      if (offset >= 0) fTimeOffset = offset;
      return *this;
   }
   bool GetTimeDisplay() const { return fTimeDisplay; }
   void ClearTimeDisplay()
   {
      fTimeDisplay.Clear();
      fTimeOffset.Clear();
      fTimeFormat.Clear();
   }

   const RAttrLine &GetAttrLine() const { return fAttrLine; }
   RAttrAxis &SetAttrLine(const RAttrLine &line) { fAttrLine = line; return *this; }
   RAttrLine &AttrLine() { return fAttrLine; }

   RAttrAxis &SetEndingSize(const RPadLength &sz) { fEndingSize = sz; return *this; }
   RPadLength GetEndingSize() const { return fEndingSize; }

   RAttrAxis &SetEndingStyle(const std::string &st) { fEndingStyle = st; return *this; }
   RAttrAxis &SetEndingArrow() { return SetEndingStyle("arrow"); }
   RAttrAxis &SetEndingCircle() { return SetEndingStyle("cicrle"); }
   std::string GetEndingStyle() const { return fEndingStyle; }

   RAttrAxis &SetTicksSize(const RPadLength &sz) { fTicksSize = sz; return *this; }
   RPadLength GetTicksSize() const { return fTicksSize; }

   RAttrAxis &SetTicksSide(const std::string &side) { fTicksSide = side; return *this; }
   RAttrAxis &SetTicksNormal() { return SetTicksSide("normal"); }
   RAttrAxis &SetTicksInvert() { return SetTicksSide("invert"); }
   RAttrAxis &SetTicksBoth() { return SetTicksSide("both"); }
   std::string GetTicksSide() const { return fTicksSide; }

   RAttrAxis &SetTicksColor(const RColor &color) { fTicksColor = color; return *this; }
   RColor GetTicksColor() const { return fTicksColor; }

   RAttrAxis &SetTicksWidth(int width) { fTicksWidth = width; return *this; }
   int GetTicksWidth() const { return fTicksWidth; }

   RAttrAxis &SetLabelsOffset(const RPadLength &len) { fLabelsOffset = len; return *this; }
   RPadLength GetLabelsOffset() const { return fLabelsOffset; }

   const RAttrText &GetLabelsAttr() const { return fLabelsAttr; }
   RAttrAxis &SetLabelsAttr(const RAttrText &attr) { fLabelsAttr = attr; return *this; }
   RAttrText &LabelsAttr() { return fLabelsAttr; }

   RAttrAxis &SetLabelsCenter(bool on = true) { fLabelsCenter = on; return *this; }
   bool GetLabelsCenter() const { return fLabelsCenter; }

   const RAttrText &GetTitleAttr() const { return fTitleAttr; }
   RAttrAxis &SetTitleAttr(const RAttrText &attr) { fTitleAttr = attr; return *this; }
   RAttrText &TitleAttr() { return fTitleAttr; }

   RAttrAxis &SetTitle(const std::string &title) { fTitle = title; return *this; }
   std::string GetTitle() const { return fTitle; }

   RAttrAxis &SetTitlePos(const std::string &pos) { fTitlePos = pos; return *this; }
   RAttrAxis &SetTitleLeft() { return SetTitlePos("left"); }
   RAttrAxis &SetTitleCenter() { return SetTitlePos("center"); }
   RAttrAxis &SetTitleRight() { return SetTitlePos("right"); }
   std::string GetTitlePos() const { return fTitlePos; }

   RAttrAxis &SetTitleOffset(const RPadLength &len) { fTitleOffset = len; return *this; }
   RPadLength GetTitleOffset() const { return fTitleOffset; }
};

} // namespace Experimental
} // namespace ROOT

#endif
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include "consoleui.h"
#include "scientist.h"
#include <iomanip>

using namespace std;

ConsoleUI::ConsoleUI()
{
    _service.getScientists();  // gets information from file so it's used from the beginning.
}

// Should not contain logic for individual commands, that should be in separate functions!
void ConsoleUI::run()
{

    string command;
    while(true)
    {
        cout << "Select one of the following options: " << endl;
        cout << "=====================================" << endl;
        cout << "Add - add a programmer/computer scientist" << endl;
        cout << "Remove - remove a programmer/computer scientist" << endl;
        cout << "List - show a list of all programmer's/computer scientist's" << endl;
        cout << "Search - search the list of programmer's/computer scientist's" << endl;
        cout << "Sort - sort list by name, gender, age or year of death" << endl;
        cout << "Quit - end program" << endl;

        cin >> command;
        for(unsigned int i = 0; i < command.length(); i++) // to make all lowercase, taken from c++ site
        {
            command[i] = tolower(command[i]);
        }

        if(command == "add")
        {
           userMenuAdd();
        }
        else if(command == "remove")
        {
           userMenuRemove();
        }
        else if(command == "list")
        {
           userMenuList();
        }
        else if(command == "search")
        {
           userMenuSearch();
        }
        else if(command == "sort")
        {
            userMenuSort();
        }
        else if(command == "quit")
        {
            break;
        }
        else
        {
            cout << "Invalid input" << endl;
        }
    }

}
void ConsoleUI::userMenuAdd()
{
    string name;
    char gender;
    int birthYear;
    int deathYear = 0;
    int age = 0;
    int a;

    while(true)
    {
        cout << "Enter the programmer's/computer scientist's name: ";
        cin.ignore();
        getline(cin, name);

        // Check for gender
        while(true)
        {
            cout << "Enter the programmer's/computer scientist's gender (m/f): ";
            cin >> gender;

            if((gender != 'm') && (gender != 'f'))
            {
                cout << "Invalid input" << endl;
            }
            else
            {
                break;
            }

        }

        // Check year of birth
        while(true)
        {
            cout << "Enter the programmer's/computer scientist's year of birth: ";
            cin >> birthYear;
            if(birthYear < 2016) // Just in case we find a programmer of the univers
            {
                break;
            }
            else
            {
                cout << "Invalid input" << endl;
            }
        }

        // Check when year of death (if dead)
        while(true)
        {
            cout << "Enter the programmer's/computer scientist's year of death (type 0 if not applicable): ";
            cin >> deathYear;
            if (deathYear == 0)
            {
                break;
            }
            else if(deathYear >= birthYear)
            {
                break;
            }
            else
            {
                cout << "Invalid input" << endl;
            }
        }

        // Check if input is correct
        cout << "Name: " << name << endl << "Gender: " << gender << endl << "Born: " << birthYear << endl;

        if(deathYear != 0)
        {
            cout << "Died: " << deathYear << endl;
        }
        else
        {
            cout << endl;
        }

        a = userCheckInput();
        if (a == 0)
        {
            _service.addScientist(name, gender, birthYear, deathYear, age);
            break;
        }
        else if (a == 2)
        {
            break;
        }

    }
    cout << endl;

}
void ConsoleUI::userMenuList()
{
    vector<Scientist> scientist = _service.getScientists();
    userMenuPrint(scientist);
}
void ConsoleUI::userMenuSearch()
{
    string command;
    cout << "Select a search option: " << endl;
    cout << "Name - Search by name" << endl;
    cout << "Gender - Search by gender" << endl;
    cout << "Age - Search by age" << endl;
    cout << "Birth - search by year of birth" << endl;
    cout << "Death - search by year of death" << endl;
    cin >> command;
    cout << endl;

    for(unsigned int i = 0; i < command.length(); i++) // to make all lowercase, taken from c++ site
    {
        command[i] = tolower(command[i]);
    }

    if(command == "name")
    {
        string userInputName;
        cout << "Search by name: ";
        cin.ignore();
        getline(cin, userInputName);

        vector<Scientist> scientist = _service.findScientistByName(userInputName);
        userMenuPrint(scientist);

    }
    else if(command == "gender") // findScientistByGender
    {
        char userInputGender;
        cout << "Search by gender: ";
        cin >> userInputGender;

        vector<Scientist> scientist = _service.findScientistByGender(userInputGender);
        userMenuPrint(scientist);
    }
    else if(command == "age") // findScientistByGender
    {
        int userInputAge;
        cout << "Search by age: ";
        cin >> userInputAge;

        vector<Scientist> scientist = _service.findScientistByAge(userInputAge);
        userMenuPrint(scientist);
    }
    else if(command == "birth")
    {
        int userInputBirth;
        cout << "Search by year of birth: ";
        cin >> userInputBirth;

        vector<Scientist> scientist = _service.findScientistByBirth(userInputBirth);
        userMenuPrint(scientist);
    }
    else if(command == "death")
    {
        int userInputDeath;
        cout << "Search by year of death (0 for still alive): ";
        cin >> userInputDeath;

        vector<Scientist> scientist = _service.findScientistByDeath(userInputDeath);
        userMenuPrint(scientist);
    }
    cout << endl;

}
void ConsoleUI::userMenuSort()
{
    int userInput;
    cout << "Sort list by Name A-Z(1), Name Z-A(2), Gender(3), Year of Birth(4), Year of Death(5) or Age (6)" << endl;
    cin >> userInput;
     _service.scientistSort(userInput);
     userMenuList();
}
void ConsoleUI::userMenuPrint(vector<Scientist>scientist)
{
<<<<<<< HEAD
    cout << endl;
    cout << "Scientist name:        gender:     born:   died:    age: " << endl;
    cout << "========================================================" << endl;
    for (size_t i = 0; i< scientist.size(); ++i)
    {
        cout << left << setw(25) << scientist[i].getName()
             << setw(5) << right << scientist[i].getGender()
             << setw(10) << scientist[i].getBirth();
=======
    cout << string( 100, '\n' );
    cout << "Scientist name:    gender:     born:   died:   age: " << endl;
    cout << "====================================================" << endl;
    for (size_t i = 0; i< scientist.size(); ++i)
    {
        cout << scientist[i].getName()   << "\t"
             << scientist[i].getGender() << "\t"
             << scientist[i].getBirth()  << "\t";
>>>>>>> 63b34c887dc6041917c649b2ebf30425f00c9d25

             if(scientist[i].getDeath() == 0)
             {
                 cout << setw(8) << "-";
             }
             else
             {
                 cout << setw(8) << scientist[i].getDeath();
             }
             cout << setw(8) << scientist[i].getAge() << endl;

    }
    cout << endl;
}
int  ConsoleUI::userCheckInput()
{
    // Check if all data is correct
    while(true)
    {
        char answear;
        cout << "Is this data correct? (input y/n) or press q to quit" << endl;
        cin >> answear;

        if(answear == 'y')
        {
            return 0;
        }
        else if (answear == 'n')
        {
            return 1;
        }
        else if (answear == 'q')
        {
            return 2;
        }
        else
        {
            cout << "Invalid input!";
        }

    }
}
void ConsoleUI::userMenuRemove()
{
    string userInputName;
    cout << "Remove a programmer/computer scientist: ";
    cin.ignore();
    getline(cin, userInputName);

    _service.removeScientist(userInputName);
}
<commit_msg>fixed merge<commit_after>#include <iostream>
#include <string>
#include "consoleui.h"
#include "scientist.h"
#include <iomanip>

using namespace std;

ConsoleUI::ConsoleUI()
{
    _service.getScientists();  // gets information from file so it's used from the beginning.
}

// Should not contain logic for individual commands, that should be in separate functions!
void ConsoleUI::run()
{

    string command;
    while(true)
    {
        cout << "Select one of the following options: " << endl;
        cout << "=====================================" << endl;
        cout << "Add - add a programmer/computer scientist" << endl;
        cout << "Remove - remove a programmer/computer scientist" << endl;
        cout << "List - show a list of all programmer's/computer scientist's" << endl;
        cout << "Search - search the list of programmer's/computer scientist's" << endl;
        cout << "Sort - sort list by name, gender, age or year of death" << endl;
        cout << "Quit - end program" << endl;

        cin >> command;
        for(unsigned int i = 0; i < command.length(); i++) // to make all lowercase, taken from c++ site
        {
            command[i] = tolower(command[i]);
        }

        if(command == "add")
        {
           userMenuAdd();
        }
        else if(command == "remove")
        {
           userMenuRemove();
        }
        else if(command == "list")
        {
           userMenuList();
        }
        else if(command == "search")
        {
           userMenuSearch();
        }
        else if(command == "sort")
        {
            userMenuSort();
        }
        else if(command == "quit")
        {
            break;
        }
        else
        {
            cout << "Invalid input" << endl;
        }
    }

}
void ConsoleUI::userMenuAdd()
{
    string name;
    char gender;
    int birthYear;
    int deathYear = 0;
    int age = 0;
    int a;

    while(true)
    {
        cout << "Enter the programmer's/computer scientist's name: ";
        cin.ignore();
        getline(cin, name);

        // Check for gender
        while(true)
        {
            cout << "Enter the programmer's/computer scientist's gender (m/f): ";
            cin >> gender;

            if((gender != 'm') && (gender != 'f'))
            {
                cout << "Invalid input" << endl;
            }
            else
            {
                break;
            }

        }

        // Check year of birth
        while(true)
        {
            cout << "Enter the programmer's/computer scientist's year of birth: ";
            cin >> birthYear;
            if(birthYear < 2016) // Just in case we find a programmer of the univers
            {
                break;
            }
            else
            {
                cout << "Invalid input" << endl;
            }
        }

        // Check when year of death (if dead)
        while(true)
        {
            cout << "Enter the programmer's/computer scientist's year of death (type 0 if not applicable): ";
            cin >> deathYear;
            if (deathYear == 0)
            {
                break;
            }
            else if(deathYear >= birthYear)
            {
                break;
            }
            else
            {
                cout << "Invalid input" << endl;
            }
        }

        // Check if input is correct
        cout << "Name: " << name << endl << "Gender: " << gender << endl << "Born: " << birthYear << endl;

        if(deathYear != 0)
        {
            cout << "Died: " << deathYear << endl;
        }
        else
        {
            cout << endl;
        }

        a = userCheckInput();
        if (a == 0)
        {
            _service.addScientist(name, gender, birthYear, deathYear, age);
            break;
        }
        else if (a == 2)
        {
            break;
        }

    }
    cout << endl;

}
void ConsoleUI::userMenuList()
{
    vector<Scientist> scientist = _service.getScientists();
    userMenuPrint(scientist);
}
void ConsoleUI::userMenuSearch()
{
    string command;
    cout << "Select a search option: " << endl;
    cout << "Name - Search by name" << endl;
    cout << "Gender - Search by gender" << endl;
    cout << "Age - Search by age" << endl;
    cout << "Birth - search by year of birth" << endl;
    cout << "Death - search by year of death" << endl;
    cin >> command;
    cout << endl;

    for(unsigned int i = 0; i < command.length(); i++) // to make all lowercase, taken from c++ site
    {
        command[i] = tolower(command[i]);
    }

    if(command == "name")
    {
        string userInputName;
        cout << "Search by name: ";
        cin.ignore();
        getline(cin, userInputName);

        vector<Scientist> scientist = _service.findScientistByName(userInputName);
        userMenuPrint(scientist);

    }
    else if(command == "gender") // findScientistByGender
    {
        char userInputGender;
        cout << "Search by gender: ";
        cin >> userInputGender;

        vector<Scientist> scientist = _service.findScientistByGender(userInputGender);
        userMenuPrint(scientist);
    }
    else if(command == "age") // findScientistByGender
    {
        int userInputAge;
        cout << "Search by age: ";
        cin >> userInputAge;

        vector<Scientist> scientist = _service.findScientistByAge(userInputAge);
        userMenuPrint(scientist);
    }
    else if(command == "birth")
    {
        int userInputBirth;
        cout << "Search by year of birth: ";
        cin >> userInputBirth;

        vector<Scientist> scientist = _service.findScientistByBirth(userInputBirth);
        userMenuPrint(scientist);
    }
    else if(command == "death")
    {
        int userInputDeath;
        cout << "Search by year of death (0 for still alive): ";
        cin >> userInputDeath;

        vector<Scientist> scientist = _service.findScientistByDeath(userInputDeath);
        userMenuPrint(scientist);
    }
    cout << endl;

}
void ConsoleUI::userMenuSort()
{
    int userInput;
    cout << "Sort list by Name A-Z(1), Name Z-A(2), Gender(3), Year of Birth(4), Year of Death(5) or Age (6)" << endl;
    cin >> userInput;
     _service.scientistSort(userInput);
     userMenuList();
}
void ConsoleUI::userMenuPrint(vector<Scientist>scientist)
{
    cout << string( 100, '\n' );
    cout << "Scientist name:        gender:     born:   died:    age: " << endl;
    cout << "========================================================" << endl;
    for (size_t i = 0; i< scientist.size(); ++i)
    {
        cout << left << setw(25) << scientist[i].getName()
             << setw(5) << right << scientist[i].getGender()
             << setw(10) << scientist[i].getBirth();

             if(scientist[i].getDeath() == 0)
             {
                 cout << setw(8) << "-";
             }
             else
             {
                 cout << setw(8) << scientist[i].getDeath();
             }
             cout << setw(8) << scientist[i].getAge() << endl;

    }
    cout << endl;
}
int  ConsoleUI::userCheckInput()
{
    // Check if all data is correct
    while(true)
    {
        char answear;
        cout << "Is this data correct? (input y/n) or press q to quit" << endl;
        cin >> answear;

        if(answear == 'y')
        {
            return 0;
        }
        else if (answear == 'n')
        {
            return 1;
        }
        else if (answear == 'q')
        {
            return 2;
        }
        else
        {
            cout << "Invalid input!";
        }

    }
}
void ConsoleUI::userMenuRemove()
{
    string userInputName;
    cout << "Remove a programmer/computer scientist: ";
    cin.ignore();
    getline(cin, userInputName);

    _service.removeScientist(userInputName);
}
<|endoftext|>


<commit_before>
// Copyright (c) 2012, 2013 Pierre MOULON.

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef OPENMVG_FEATURES_DESCRIPTOR_HPP
#define OPENMVG_FEATURES_DESCRIPTOR_HPP

#include "openMVG/numeric/numeric.h"
#include <iostream>
#include <iterator>
#include <fstream>
#include <string>
#include <vector>
#include <exception>

namespace openMVG {
namespace features {

/**
 * Class that handle descriptor (a data container of N values of type T).
 * SiftDescriptor => <uchar,128> or <float,128>

 * Surf 64 => <float,64>
 */
template <typename T, std::size_t N>
class Descriptor
{
public:
  typedef Descriptor<T, N> This;
  typedef T value_type;
  typedef T bin_type;
  typedef std::size_t size_type;

  /// Compile-time length of the descriptor
  static const size_type static_size = N;

  /// Constructor
  inline Descriptor() {}

  inline Descriptor(T defaultValue)
  {
    for(size_type i = 0; i < N; ++i)
      data[i] = defaultValue;
  }

  /// capacity
  inline size_type size() const { return N; }

  /// Mutable and non-mutable bin getters
  inline bin_type& operator[](std::size_t i) { return data[i]; }
  inline bin_type operator[](std::size_t i) const { return data[i]; }

  // Atomic addition between two descriptors
  inline This& operator+=(const This other)
  {
    for(size_type i = 0; i < size(); ++i)
      data[i] += other[i];
    return *this;
  }

  // Division between two descriptors
  inline This operator/(const This other) const
  {
    This res;
    for(size_type i = 0; i < size(); ++i)
      res[i] = data[i] / other[i];
    return res;
  }

  inline bin_type* getData() const {return (bin_type* ) (&data[0]);}

  /// Ostream interface
  std::ostream& print(std::ostream& os) const;
  /// Istream interface
  std::istream& read(std::istream& in);

  template<class Archive>
  void save(Archive & archive) const
  {
    std::vector<T> array(data,data+N);
    archive( array );
  }

  template<class Archive>
  void load(Archive & archive)
  {
    std::vector<T> array(N);
    archive( array );
    std::memcpy(data, array.data(), sizeof(T)*N);
  }

private:
  bin_type data[N];
};

// Output stream definition
template <typename T, std::size_t N>
inline std::ostream& operator<<(std::ostream& out, const Descriptor<T, N>& obj)
{
  return obj.print(out); //simply call the print method.
}

// Input stream definition
template <typename T, std::size_t N>
inline std::istream& operator>>(std::istream& in, Descriptor<T, N>& obj)
{
  return obj.read(in); //simply call the read method.
}

//-- Use specialization to handle unsigned char case.
//-- We do not want confuse unsigned char value with the spaces written in the file

template<typename T>
inline std::ostream& printT(std::ostream& os, T *tab, size_t N)
{
  std::copy( tab, &tab[N], std::ostream_iterator<T>(os," "));
  return os;
}

template<>
inline std::ostream& printT<unsigned char>(std::ostream& os, unsigned char *tab, size_t N)
{
  for(size_t i=0; i < N; ++i)
    os << (int)tab[i] << " ";
  return os;
}

template<typename T>
inline std::istream& readT(std::istream& is, T *tab, size_t N)
{
  for(size_t i=0; i<N; ++i) is >> tab[i];
  return is;
}

template<>
inline std::istream& readT<unsigned char>(std::istream& is, unsigned char *tab, size_t N)
{
  int temp = -1;
  for(size_t i=0; i < N; ++i){
    is >> temp; tab[i] = (unsigned char)temp;
  }
  return is;
}

template<typename T, std::size_t N>
std::ostream& Descriptor<T,N>::print(std::ostream& os) const
{
  return printT<T>(os, (T*) &data[0], N);
}

template<typename T, std::size_t N>
std::istream& Descriptor<T,N>::read(std::istream& in)
{
  return readT<T>(in, (T*) &data[0], N);
}

/// Read descriptors from file
template<typename DescriptorsT >
static bool loadDescsFromFile(
  const std::string & sfileNameDescs,
  DescriptorsT & vec_desc)
{
  vec_desc.clear();

  std::ifstream fileIn(sfileNameDescs.c_str());
  std::copy(
    std::istream_iterator<typename DescriptorsT::value_type >(fileIn),
    std::istream_iterator<typename DescriptorsT::value_type >(),
    std::back_inserter(vec_desc));
  bool bOk = !fileIn.bad();
  fileIn.close();
  return bOk;
}

/// Write descriptors to file
template<typename DescriptorsT >
static bool saveDescsToFile(
  const std::string & sfileNameDescs,
  DescriptorsT & vec_desc)
{
  std::ofstream file(sfileNameDescs.c_str());
  std::copy(vec_desc.begin(), vec_desc.end(),
            std::ostream_iterator<typename DescriptorsT::value_type >(file,"\n"));
  bool bOk = file.good();
  file.close();
  return bOk;
}

/// Read descriptors from file (in binary mode)
template<typename DescriptorsT >
static bool loadDescsFromBinFile(
  const std::string & sfileNameDescs,
  DescriptorsT & vec_desc,
  bool append = false)
{
  typedef typename DescriptorsT::value_type VALUE;

  if( !append ) // for compatibility
    vec_desc.clear();

  std::ifstream fileIn(sfileNameDescs.c_str(), std::ios::in | std::ios::binary);

  if(!fileIn.is_open())
  {
    std::cerr << "Unable to open file " << sfileNameDescs << std::endl;
    throw std::invalid_argument("Unable to open file " + sfileNameDescs);
  }

  //Read the number of descriptor in the file
  std::size_t cardDesc = 0;
  fileIn.read((char*) &cardDesc,  sizeof(std::size_t));
  // Reserve is necessary to avoid iterator problems in case of cleared vector
  vec_desc.reserve(vec_desc.size() + cardDesc);
  typename DescriptorsT::const_iterator begin = vec_desc.end();
  vec_desc.resize(vec_desc.size() + cardDesc);
  for (typename DescriptorsT::const_iterator iter = begin;
    iter != vec_desc.end(); ++iter)
  {
    fileIn.read((char*) (*iter).getData(),
      VALUE::static_size*sizeof(typename VALUE::bin_type));
  }
  bool bOk = !fileIn.bad();
  fileIn.close();
  return bOk;
}

/// Write descriptors to file (in binary mode)
template<typename DescriptorsT >
static bool saveDescsToBinFile(
  const std::string & sfileNameDescs,
  DescriptorsT & vec_desc)
{
  typedef typename DescriptorsT::value_type VALUE;

  std::ofstream file(sfileNameDescs.c_str(), std::ios::out | std::ios::binary);
  //Write the number of descriptor
  const std::size_t cardDesc = vec_desc.size();
  file.write((const char*) &cardDesc,  sizeof(std::size_t));
  for (typename DescriptorsT::const_iterator iter = vec_desc.begin();
    iter != vec_desc.end(); ++iter) {
    file.write((const char*) (*iter).getData(),
      VALUE::static_size*sizeof(typename VALUE::bin_type));
  }
  bool bOk = file.good();
  file.close();
  return bOk;
}

} // namespace features
} // namespace openMVG

#endif  // OPENMVG_FEATURES_DESCRIPTOR_HPP
<commit_msg>[features] add scaling operator to descriptor<commit_after>
// Copyright (c) 2012, 2013 Pierre MOULON.

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef OPENMVG_FEATURES_DESCRIPTOR_HPP
#define OPENMVG_FEATURES_DESCRIPTOR_HPP

#include "openMVG/numeric/numeric.h"
#include <iostream>
#include <iterator>
#include <fstream>
#include <string>
#include <vector>
#include <exception>

namespace openMVG {
namespace features {

/**
 * Class that handle descriptor (a data container of N values of type T).
 * SiftDescriptor => <uchar,128> or <float,128>

 * Surf 64 => <float,64>
 */
template <typename T, std::size_t N>
class Descriptor
{
public:
  typedef Descriptor<T, N> This;
  typedef T value_type;
  typedef T bin_type;
  typedef std::size_t size_type;

  /// Compile-time length of the descriptor
  static const size_type static_size = N;

  /// Constructor
  inline Descriptor() {}

  inline Descriptor(T defaultValue)
  {
    for(size_type i = 0; i < N; ++i)
      data[i] = defaultValue;
  }

  /// capacity
  inline size_type size() const { return N; }

  /// Mutable and non-mutable bin getters
  inline bin_type& operator[](std::size_t i) { return data[i]; }
  inline bin_type operator[](std::size_t i) const { return data[i]; }

  // Atomic addition between two descriptors
  inline This& operator+=(const This other)
  {
    for(size_type i = 0; i < size(); ++i)
      data[i] += other[i];
    return *this;
  }

  // Division between two descriptors
  inline This operator/(const This other) const
  {
    This res;
    for(size_type i = 0; i < size(); ++i)
      res[i] = data[i] / other[i];
    return res;
  }

  inline This& operator*=(const value_type scalar)
  {
    for(size_type i = 0; i < size(); ++i)
      data[i] *= scalar;
    return *this;
  }

  inline bin_type* getData() const {return (bin_type* ) (&data[0]);}

  /// Ostream interface
  std::ostream& print(std::ostream& os) const;
  /// Istream interface
  std::istream& read(std::istream& in);

  template<class Archive>
  void save(Archive & archive) const
  {
    std::vector<T> array(data,data+N);
    archive( array );
  }

  template<class Archive>
  void load(Archive & archive)
  {
    std::vector<T> array(N);
    archive( array );
    std::memcpy(data, array.data(), sizeof(T)*N);
  }

private:
  bin_type data[N];
};

// Output stream definition
template <typename T, std::size_t N>
inline std::ostream& operator<<(std::ostream& out, const Descriptor<T, N>& obj)
{
  return obj.print(out); //simply call the print method.
}

// Input stream definition
template <typename T, std::size_t N>
inline std::istream& operator>>(std::istream& in, Descriptor<T, N>& obj)
{
  return obj.read(in); //simply call the read method.
}

//-- Use specialization to handle unsigned char case.
//-- We do not want confuse unsigned char value with the spaces written in the file

template<typename T>
inline std::ostream& printT(std::ostream& os, T *tab, size_t N)
{
  std::copy( tab, &tab[N], std::ostream_iterator<T>(os," "));
  return os;
}

template<>
inline std::ostream& printT<unsigned char>(std::ostream& os, unsigned char *tab, size_t N)
{
  for(size_t i=0; i < N; ++i)
    os << (int)tab[i] << " ";
  return os;
}

template<typename T>
inline std::istream& readT(std::istream& is, T *tab, size_t N)
{
  for(size_t i=0; i<N; ++i) is >> tab[i];
  return is;
}

template<>
inline std::istream& readT<unsigned char>(std::istream& is, unsigned char *tab, size_t N)
{
  int temp = -1;
  for(size_t i=0; i < N; ++i){
    is >> temp; tab[i] = (unsigned char)temp;
  }
  return is;
}

template<typename T, std::size_t N>
std::ostream& Descriptor<T,N>::print(std::ostream& os) const
{
  return printT<T>(os, (T*) &data[0], N);
}

template<typename T, std::size_t N>
std::istream& Descriptor<T,N>::read(std::istream& in)
{
  return readT<T>(in, (T*) &data[0], N);
}

/// Read descriptors from file
template<typename DescriptorsT >
static bool loadDescsFromFile(
  const std::string & sfileNameDescs,
  DescriptorsT & vec_desc)
{
  vec_desc.clear();

  std::ifstream fileIn(sfileNameDescs.c_str());
  std::copy(
    std::istream_iterator<typename DescriptorsT::value_type >(fileIn),
    std::istream_iterator<typename DescriptorsT::value_type >(),
    std::back_inserter(vec_desc));
  bool bOk = !fileIn.bad();
  fileIn.close();
  return bOk;
}

/// Write descriptors to file
template<typename DescriptorsT >
static bool saveDescsToFile(
  const std::string & sfileNameDescs,
  DescriptorsT & vec_desc)
{
  std::ofstream file(sfileNameDescs.c_str());
  std::copy(vec_desc.begin(), vec_desc.end(),
            std::ostream_iterator<typename DescriptorsT::value_type >(file,"\n"));
  bool bOk = file.good();
  file.close();
  return bOk;
}

/// Read descriptors from file (in binary mode)
template<typename DescriptorsT >
static bool loadDescsFromBinFile(
  const std::string & sfileNameDescs,
  DescriptorsT & vec_desc,
  bool append = false)
{
  typedef typename DescriptorsT::value_type VALUE;

  if( !append ) // for compatibility
    vec_desc.clear();

  std::ifstream fileIn(sfileNameDescs.c_str(), std::ios::in | std::ios::binary);

  if(!fileIn.is_open())
  {
    std::cerr << "Unable to open file " << sfileNameDescs << std::endl;
    throw std::invalid_argument("Unable to open file " + sfileNameDescs);
  }

  //Read the number of descriptor in the file
  std::size_t cardDesc = 0;
  fileIn.read((char*) &cardDesc,  sizeof(std::size_t));
  // Reserve is necessary to avoid iterator problems in case of cleared vector
  vec_desc.reserve(vec_desc.size() + cardDesc);
  typename DescriptorsT::const_iterator begin = vec_desc.end();
  vec_desc.resize(vec_desc.size() + cardDesc);
  for (typename DescriptorsT::const_iterator iter = begin;
    iter != vec_desc.end(); ++iter)
  {
    fileIn.read((char*) (*iter).getData(),
      VALUE::static_size*sizeof(typename VALUE::bin_type));
  }
  bool bOk = !fileIn.bad();
  fileIn.close();
  return bOk;
}

/// Write descriptors to file (in binary mode)
template<typename DescriptorsT >
static bool saveDescsToBinFile(
  const std::string & sfileNameDescs,
  DescriptorsT & vec_desc)
{
  typedef typename DescriptorsT::value_type VALUE;

  std::ofstream file(sfileNameDescs.c_str(), std::ios::out | std::ios::binary);
  //Write the number of descriptor
  const std::size_t cardDesc = vec_desc.size();
  file.write((const char*) &cardDesc,  sizeof(std::size_t));
  for (typename DescriptorsT::const_iterator iter = vec_desc.begin();
    iter != vec_desc.end(); ++iter) {
    file.write((const char*) (*iter).getData(),
      VALUE::static_size*sizeof(typename VALUE::bin_type));
  }
  bool bOk = file.good();
  file.close();
  return bOk;
}

} // namespace features
} // namespace openMVG

#endif  // OPENMVG_FEATURES_DESCRIPTOR_HPP
<|endoftext|>