<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 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/>.
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <util/RefHashTableOf.hpp>
#include <util/TransService.hpp>
#include <util/XMLString.hpp>
#include <util/XML88591Transcoder.hpp>
#include <util/XMLASCIITranscoder.hpp>
#include <util/XMLEBCDICTranscoder.hpp>
#include <util/XMLUCS4Transcoder.hpp>
#include <util/XMLUTF8Transcoder.hpp>
#include <util/XMLUTF16Transcoder.hpp>
#include <util/XMLUni.hpp>

// ---------------------------------------------------------------------------
//  Local types
//
//  This class is a very simple class used to hold mappings from encoding
//  names to factory methods for our intrinsic transcoders. This allows us
//  to quickly find one of these objects, via a hash table, and invoke the
//  factory to create the appropriate type of transcoder.
//
//  Derived from it is a simple templatized class that lets us provide the
//  correct implementation of the virtual factory method.
// ---------------------------------------------------------------------------
class ENameMap
{
public :
    // -----------------------------------------------------------------------
    //  Destructor
    // -----------------------------------------------------------------------
    ~ENameMap()
    {
        delete [] fEncodingName;
    }

    // -----------------------------------------------------------------------
    //  Virtual factory method
    // -----------------------------------------------------------------------
    virtual XMLTranscoder* makeNew
    (
        const   unsigned int    blockSize
    )   const = 0;

    // -----------------------------------------------------------------------
    //  Getter methods
    // -----------------------------------------------------------------------
    const XMLCh* getKey() const
    {
        return fEncodingName;
    }

protected :
    // -----------------------------------------------------------------------
    //  Hidden constructors
    // -----------------------------------------------------------------------
    ENameMap(const XMLCh* const encodingName) :

        fEncodingName(XMLString::replicate(encodingName))
    {
    }

private :
    // -----------------------------------------------------------------------
    //  Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    ENameMap(const ENameMap&);
    void operator=(const ENameMap&);

    // -----------------------------------------------------------------------
    //  Private data members
    //
    //  fEncodingName
    //      This is the encoding name for the transcoder that is controlled
    //      by this map instance.
    // -----------------------------------------------------------------------
    XMLCh*  fEncodingName;
};

template <class TType> class ENameMapFor : public ENameMap
{
public :
    // -----------------------------------------------------------------------
    //  Constructors and Destructor
    // -----------------------------------------------------------------------
    ENameMapFor(const XMLCh* const encodingName) :

        ENameMap(encodingName)
    {
    }

    ~ENameMapFor()
    {
    }

    // -----------------------------------------------------------------------
    //  Implementation of virtual factory method
    // -----------------------------------------------------------------------
    virtual XMLTranscoder* makeNew(const unsigned int blockSize) const
    {
        return new TType(getKey(), blockSize);
    }

private :
    // -----------------------------------------------------------------------
    //  Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    ENameMapFor(const ENameMapFor<TType>&);
    void operator=(const ENameMapFor<TType>&);
};

template <class TType> class EEndianNameMapFor : public ENameMap
{
public :
    // -----------------------------------------------------------------------
    //  Constructors and Destructor
    // -----------------------------------------------------------------------
    EEndianNameMapFor(const XMLCh* const encodingName, const bool swapped) :

        ENameMap(encodingName)
        , fSwapped(swapped)
    {
    }

    ~EEndianNameMapFor()
    {
    }

    // -----------------------------------------------------------------------
    //  Implementation of virtual factory method
    // -----------------------------------------------------------------------
    virtual XMLTranscoder* makeNew(const unsigned int blockSize) const
    {
        return new TType(getKey(), blockSize, fSwapped);
    }

private :
    // -----------------------------------------------------------------------
    //  Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    ENameMapFor(const ENameMapFor<TType>&);
    void operator=(const ENameMapFor<TType>&);

    // -----------------------------------------------------------------------
    //  Private data members
    //
    //  fSwapped
    //      Indicates whether the endianess of the encoding is opposite of
    //      that of the local host.
    // -----------------------------------------------------------------------
    bool    fSwapped;
};

// ---------------------------------------------------------------------------
//  Local, static data
//
//  gMappings
//      This is a hash table of ENameMap objects. It is created and filled
//      in when the platform init calls our initTransService() method.
// ---------------------------------------------------------------------------
static RefHashTableOf<ENameMap>*    gMappings = 0;

// ---------------------------------------------------------------------------
//  XLMTransService: Constructors and destructor
// ---------------------------------------------------------------------------
XMLTransService::XMLTransService()
{
}

XMLTransService::~XMLTransService()
{
}

// ---------------------------------------------------------------------------
//  XLMTranscoder: Non-virtual API
// ---------------------------------------------------------------------------
XMLTranscoder*
XMLTransService::makeNewTranscoderFor(  const   XMLCh* const            encodingName
                                        ,       XMLTransService::Codes& resValue
                                        , const unsigned int            blockSize)
{
    //
    //  First try to find it in our list of mappings to intrinsically
    //  supported encodings. We have to upper case the passed encoding
    //  name because we use a hash table and we stored all our mappings
    //  in all uppercase.
    //
    const unsigned int bufSize = 2048;
    XMLCh upBuf[bufSize + 1];
    if (!XMLString::copyNString(upBuf, encodingName, bufSize))
        return 0;
    XMLString::upperCase(upBuf);
    ENameMap* ourMapping = gMappings->get(upBuf);

    // If we found it, then call the factory method for it
    if (ourMapping)
        return ourMapping->makeNew(blockSize);

    // It wasn't an intrinsic, so pass it on to the trans service
    return makeNewXMLTranscoder(encodingName, resValue, blockSize);
}

// ---------------------------------------------------------------------------
//  XLMTranscoder: Public Destructor
// ---------------------------------------------------------------------------
XMLTranscoder::~XMLTranscoder()
{
    delete [] fEncodingName;
}

// ---------------------------------------------------------------------------
//  XLMTranscoder: Hidden Constructors
// ---------------------------------------------------------------------------
XMLTranscoder::XMLTranscoder(const  XMLCh* const    encodingName
                            , const unsigned int    blockSize) :
    fEncodingName(0)
    , fBlockSize(blockSize)
{
    fEncodingName = XMLString::replicate(encodingName);
}

// ---------------------------------------------------------------------------
//  XLMTranscoder: Protected helpers
// ---------------------------------------------------------------------------
void XMLTranscoder::checkBlockSize(const unsigned int toCheck)
{
    if (toCheck > fBlockSize)
    {
        // <TBD> Throw an exception here
    }
}

// ---------------------------------------------------------------------------
//  XLMLCPTranscoder: Public Destructor
// ---------------------------------------------------------------------------
XMLLCPTranscoder::XMLLCPTranscoder()
{
}

// ---------------------------------------------------------------------------
//  XLMTranscoder: Hidden Constructors
// ---------------------------------------------------------------------------
XMLLCPTranscoder::~XMLLCPTranscoder()
{
}

// ---------------------------------------------------------------------------
//  XLMTranscoder: Hidden Init Method
//
//  This is called by platform utils during startup.
// ---------------------------------------------------------------------------
void XMLTransService::initTransService()
{
    //
    //  Create our hash table that we will fill with mappings. The default
    //  is to adopt the elements, which is fine with us.
    //
    gMappings = new RefHashTableOf<ENameMap>(103);

    //
    //  Add in our mappings for ASCII.
    //
    gMappings->put(new ENameMapFor<XMLASCIITranscoder>(XMLUni::fgUSASCIIEncodingString));
    gMappings->put(new ENameMapFor<XMLASCIITranscoder>(XMLUni::fgUSASCIIEncodingString2));
    gMappings->put(new ENameMapFor<XMLASCIITranscoder>(XMLUni::fgUSASCIIEncodingString3));
    gMappings->put(new ENameMapFor<XMLASCIITranscoder>(XMLUni::fgUSASCIIEncodingString4));

    //
    //  Add in our mappings for UTF-8
    //
    gMappings->put(new ENameMapFor<XMLUTF8Transcoder>(XMLUni::fgUTF8EncodingString));
    gMappings->put(new ENameMapFor<XMLUTF8Transcoder>(XMLUni::fgUTF8EncodingString2));

    //
    //  Add in our mappings for Latin1
    //
    gMappings->put(new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString));
    gMappings->put(new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString2));
    gMappings->put(new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString3));
    gMappings->put(new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString4));
    gMappings->put(new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString5));
    gMappings->put(new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString6));
    gMappings->put(new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString7));
    gMappings->put(new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString8));

    //
    //  Add in our mappings for UTF-16 and UCS-4, little endian
    //
    bool swapped = false;

    #if defined(ENDIANMODE_BIG)
    swapped = true;
    #endif
    gMappings->put
    (
        new EEndianNameMapFor<XMLUTF16Transcoder>
        (
            XMLUni::fgUTF16LEncodingString
            , swapped
        )
    );

    gMappings->put
    (
        new EEndianNameMapFor<XMLUTF16Transcoder>
        (
            XMLUni::fgUTF16LEncodingString2
            , swapped
        )
    );

    gMappings->put
    (
        new EEndianNameMapFor<XMLUCS4Transcoder>
        (
            XMLUni::fgUCS4LEncodingString
            , swapped
        )
    );

    gMappings->put
    (
        new EEndianNameMapFor<XMLUCS4Transcoder>
        (
            XMLUni::fgUCS4LEncodingString2
            , swapped
        )
    );

    //
    //  Add in our mappings for UTF-16 and UCS-4, big endian
    //
    swapped = false;
    #if defined(ENDIANMODE_LITTLE)
    swapped = true;
    #endif
    gMappings->put
    (
        new EEndianNameMapFor<XMLUTF16Transcoder>
        (
            XMLUni::fgUTF16BEncodingString
            , swapped
        )
    );

    gMappings->put
    (
        new EEndianNameMapFor<XMLUTF16Transcoder>
        (
            XMLUni::fgUTF16BEncodingString2
            , swapped
        )
    );

    gMappings->put
    (
        new EEndianNameMapFor<XMLUCS4Transcoder>
        (
            XMLUni::fgUCS4BEncodingString
            , swapped
        )
    );

    gMappings->put
    (
        new EEndianNameMapFor<XMLUCS4Transcoder>
        (
            XMLUni::fgUCS4BEncodingString2
            , swapped
        )
    );

    //
    //  Add in our mappings for EBCDIC-US
    //
    gMappings->put(new ENameMapFor<XMLEBCDICTranscoder>(XMLUni::fgDefaultEBCDICEncodingString));
    gMappings->put(new ENameMapFor<XMLEBCDICTranscoder>(XMLUni::fgEBCDICEncodingString));
    gMappings->put(new ENameMapFor<XMLEBCDICTranscoder>(XMLUni::fgEBCDICEncodingString2));
}
<commit_msg>Template classes functions modified<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 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/>.
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <util/RefHashTableOf.hpp>
#include <util/TransService.hpp>
#include <util/XMLString.hpp>
#include <util/XML88591Transcoder.hpp>
#include <util/XMLASCIITranscoder.hpp>
#include <util/XMLEBCDICTranscoder.hpp>
#include <util/XMLUCS4Transcoder.hpp>
#include <util/XMLUTF8Transcoder.hpp>
#include <util/XMLUTF16Transcoder.hpp>
#include <util/XMLUni.hpp>

// ---------------------------------------------------------------------------
//  Local types
//
//  This class is a very simple class used to hold mappings from encoding
//  names to factory methods for our intrinsic transcoders. This allows us
//  to quickly find one of these objects, via a hash table, and invoke the
//  factory to create the appropriate type of transcoder.
//
//  Derived from it is a simple templatized class that lets us provide the
//  correct implementation of the virtual factory method.
// ---------------------------------------------------------------------------
class ENameMap
{
public :
    // -----------------------------------------------------------------------
    //  Destructor
    // -----------------------------------------------------------------------
    ~ENameMap()
    {
        delete [] fEncodingName;
    }

    // -----------------------------------------------------------------------
    //  Virtual factory method
    // -----------------------------------------------------------------------
    virtual XMLTranscoder* makeNew
    (
        const   unsigned int    blockSize
    )   const = 0;

    // -----------------------------------------------------------------------
    //  Getter methods
    // -----------------------------------------------------------------------
    const XMLCh* getKey() const
    {
        return fEncodingName;
    }

protected :
    // -----------------------------------------------------------------------
    //  Hidden constructors
    // -----------------------------------------------------------------------
    ENameMap(const XMLCh* const encodingName) :

        fEncodingName(XMLString::replicate(encodingName))
    {
    }

    ENameMap(){};
private :
    // -----------------------------------------------------------------------
    //  Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    ENameMap(const ENameMap&);
    void operator=(const ENameMap&);

    // -----------------------------------------------------------------------
    //  Private data members
    //
    //  fEncodingName
    //      This is the encoding name for the transcoder that is controlled
    //      by this map instance.
    // -----------------------------------------------------------------------
    XMLCh*  fEncodingName;
};

template <class TType> class ENameMapFor : public ENameMap
{
public :
    // -----------------------------------------------------------------------
    //  Constructors and Destructor
    // -----------------------------------------------------------------------
    ENameMapFor(const XMLCh* const encodingName) :

        ENameMap(encodingName)
    {
    }

    ~ENameMapFor()
    {
    }

    // -----------------------------------------------------------------------
    //  Implementation of virtual factory method
    // -----------------------------------------------------------------------
    virtual XMLTranscoder* makeNew(const unsigned int blockSize) const
    {
        return new TType(getKey(), blockSize);
    }

private :
    // -----------------------------------------------------------------------
    //  Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    ENameMapFor(){};
    ENameMapFor(const ENameMapFor<TType>&){};
    void operator=(const ENameMapFor<TType>&){};
};

template <class TType> class EEndianNameMapFor : public ENameMap
{
public :
    // -----------------------------------------------------------------------
    //  Constructors and Destructor
    // -----------------------------------------------------------------------
    EEndianNameMapFor(const XMLCh* const encodingName, const bool swapped) :

        ENameMap(encodingName)
        , fSwapped(swapped)
    {
    }

    ~EEndianNameMapFor()
    {
    }

    // -----------------------------------------------------------------------
    //  Implementation of virtual factory method
    // -----------------------------------------------------------------------
    virtual XMLTranscoder* makeNew(const unsigned int blockSize) const
    {
        return new TType(getKey(), blockSize, fSwapped);
    }

private :
    // -----------------------------------------------------------------------
    //  Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    EEndianNameMapFor(const EEndianNameMapFor<TType>&);
    void operator=(const EEndianNameMapFor<TType>&);

    // -----------------------------------------------------------------------
    //  Private data members
    //
    //  fSwapped
    //      Indicates whether the endianess of the encoding is opposite of
    //      that of the local host.
    // -----------------------------------------------------------------------
    bool    fSwapped;
};

// ---------------------------------------------------------------------------
//  Local, static data
//
//  gMappings
//      This is a hash table of ENameMap objects. It is created and filled
//      in when the platform init calls our initTransService() method.
// ---------------------------------------------------------------------------
static RefHashTableOf<ENameMap>*    gMappings = 0;

// ---------------------------------------------------------------------------
//  XLMTransService: Constructors and destructor
// ---------------------------------------------------------------------------
XMLTransService::XMLTransService()
{
}

XMLTransService::~XMLTransService()
{
}

// ---------------------------------------------------------------------------
//  XLMTranscoder: Non-virtual API
// ---------------------------------------------------------------------------
XMLTranscoder*
XMLTransService::makeNewTranscoderFor(  const   XMLCh* const            encodingName
                                        ,       XMLTransService::Codes& resValue
                                        , const unsigned int            blockSize)
{
    //
    //  First try to find it in our list of mappings to intrinsically
    //  supported encodings. We have to upper case the passed encoding
    //  name because we use a hash table and we stored all our mappings
    //  in all uppercase.
    //
    const unsigned int bufSize = 2048;
    XMLCh upBuf[bufSize + 1];
    if (!XMLString::copyNString(upBuf, encodingName, bufSize))
        return 0;
    XMLString::upperCase(upBuf);
    ENameMap* ourMapping = gMappings->get(upBuf);

    // If we found it, then call the factory method for it
    if (ourMapping)
        return ourMapping->makeNew(blockSize);

    // It wasn't an intrinsic, so pass it on to the trans service
    return makeNewXMLTranscoder(encodingName, resValue, blockSize);
}

// ---------------------------------------------------------------------------
//  XLMTranscoder: Public Destructor
// ---------------------------------------------------------------------------
XMLTranscoder::~XMLTranscoder()
{
    delete [] fEncodingName;
}

// ---------------------------------------------------------------------------
//  XLMTranscoder: Hidden Constructors
// ---------------------------------------------------------------------------
XMLTranscoder::XMLTranscoder(const  XMLCh* const    encodingName
                            , const unsigned int    blockSize) :
    fEncodingName(0)
    , fBlockSize(blockSize)
{
    fEncodingName = XMLString::replicate(encodingName);
}

// ---------------------------------------------------------------------------
//  XLMTranscoder: Protected helpers
// ---------------------------------------------------------------------------
void XMLTranscoder::checkBlockSize(const unsigned int toCheck)
{
    if (toCheck > fBlockSize)
    {
        // <TBD> Throw an exception here
    }
}

// ---------------------------------------------------------------------------
//  XLMLCPTranscoder: Public Destructor
// ---------------------------------------------------------------------------
XMLLCPTranscoder::XMLLCPTranscoder()
{
}

// ---------------------------------------------------------------------------
//  XLMTranscoder: Hidden Constructors
// ---------------------------------------------------------------------------
XMLLCPTranscoder::~XMLLCPTranscoder()
{
}

// ---------------------------------------------------------------------------
//  XLMTranscoder: Hidden Init Method
//
//  This is called by platform utils during startup.
// ---------------------------------------------------------------------------
void XMLTransService::initTransService()
{
    //
    //  Create our hash table that we will fill with mappings. The default
    //  is to adopt the elements, which is fine with us.
    //
    gMappings = new RefHashTableOf<ENameMap>(103);

    //
    //  Add in our mappings for ASCII.
    //
    gMappings->put(new ENameMapFor<XMLASCIITranscoder>(XMLUni::fgUSASCIIEncodingString));
    gMappings->put(new ENameMapFor<XMLASCIITranscoder>(XMLUni::fgUSASCIIEncodingString2));
    gMappings->put(new ENameMapFor<XMLASCIITranscoder>(XMLUni::fgUSASCIIEncodingString3));
    gMappings->put(new ENameMapFor<XMLASCIITranscoder>(XMLUni::fgUSASCIIEncodingString4));

    //
    //  Add in our mappings for UTF-8
    //
    gMappings->put(new ENameMapFor<XMLUTF8Transcoder>(XMLUni::fgUTF8EncodingString));
    gMappings->put(new ENameMapFor<XMLUTF8Transcoder>(XMLUni::fgUTF8EncodingString2));

    //
    //  Add in our mappings for Latin1
    //
    gMappings->put(new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString));
    gMappings->put(new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString2));
    gMappings->put(new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString3));
    gMappings->put(new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString4));
    gMappings->put(new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString5));
    gMappings->put(new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString6));
    gMappings->put(new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString7));
    gMappings->put(new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString8));

    //
    //  Add in our mappings for UTF-16 and UCS-4, little endian
    //
    bool swapped = false;

    #if defined(ENDIANMODE_BIG)
    swapped = true;
    #endif
    gMappings->put
    (
        new EEndianNameMapFor<XMLUTF16Transcoder>
        (
            XMLUni::fgUTF16LEncodingString
            , swapped
        )
    );

    gMappings->put
    (
        new EEndianNameMapFor<XMLUTF16Transcoder>
        (
            XMLUni::fgUTF16LEncodingString2
            , swapped
        )
    );

    gMappings->put
    (
        new EEndianNameMapFor<XMLUCS4Transcoder>
        (
            XMLUni::fgUCS4LEncodingString
            , swapped
        )
    );

    gMappings->put
    (
        new EEndianNameMapFor<XMLUCS4Transcoder>
        (
            XMLUni::fgUCS4LEncodingString2
            , swapped
        )
    );

    //
    //  Add in our mappings for UTF-16 and UCS-4, big endian
    //
    swapped = false;
    #if defined(ENDIANMODE_LITTLE)
    swapped = true;
    #endif
    gMappings->put
    (
        new EEndianNameMapFor<XMLUTF16Transcoder>
        (
            XMLUni::fgUTF16BEncodingString
            , swapped
        )
    );

    gMappings->put
    (
        new EEndianNameMapFor<XMLUTF16Transcoder>
        (
            XMLUni::fgUTF16BEncodingString2
            , swapped
        )
    );

    gMappings->put
    (
        new EEndianNameMapFor<XMLUCS4Transcoder>
        (
            XMLUni::fgUCS4BEncodingString
            , swapped
        )
    );

    gMappings->put
    (
        new EEndianNameMapFor<XMLUCS4Transcoder>
        (
            XMLUni::fgUCS4BEncodingString2
            , swapped
        )
    );

    //
    //  Add in our mappings for EBCDIC-US
    //
    gMappings->put(new ENameMapFor<XMLEBCDICTranscoder>(XMLUni::fgDefaultEBCDICEncodingString));
    gMappings->put(new ENameMapFor<XMLEBCDICTranscoder>(XMLUni::fgEBCDICEncodingString));
    gMappings->put(new ENameMapFor<XMLEBCDICTranscoder>(XMLUni::fgEBCDICEncodingString2));
}
<|endoftext|>


<commit_before>/*
* Copyright (C) 2008-2013 The Communi Project
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
* License for more details.
*/

#include "irccompleter.h"
#include "irccommandparser.h"
#include "irccommandparser_p.h"
#include "ircbuffermodel.h"
#include "ircusermodel.h"
#include "ircchannel.h"
#include "ircuser.h"

#include <QTextBoundaryFinder>
#include <QPointer>
#include <QList>
#include <QPair>

IRC_BEGIN_NAMESPACE

/*!
    \file irccompleter.h
    \brief \#include <IrcCompleter>
 */

/*!
    \since 3.1
    \class IrcCompleter irccompleter.h <IrcCompleter>
    \ingroup util
    \brief Provides command and name completion.

    IrcCompleter provides command and name completion for a text input field. The completer
    is made context aware by assigning a command \ref IrcCompleter::parser "parser" and a
    \ref buffer that is currently active in the GUI. The parser is used for completing
    commands, and the buffer is used for completing buffer and user names.

    In order to perform a completion, call complete() with the current text input field
    content and the cursor position. If a suitable completion is found, the completed()
    signal is emitted with a suggestion for a new content and cursor position for the
    text input field.

    \code
    TextField {
        id: textField

        Keys.onTabPressed: completer.complete(text, cursorPosition)

        IrcCompleter {
            id: completer

            buffer: ...
            parser: ...

            onCompleted: {
                textField.text = text
                textField.cursorPosition = cursor
            }
        }
    }
    \endcode

    \sa IrcCommandParser, IrcBuffer
 */

/*!
    \fn void IrcCompleter::completed(const QString& text, int cursor)

    This signal is emitted when a suitable completion with \a text and \a cursor position is found.
 */

#ifndef IRC_DOXYGEN

#if QT_VERSION < 0x050000
#define StartOfItem StartWord
#define EndOfItem EndWord
#endif // QT_VERSION

static QPair<int, int> findWordBoundaries(const QString& text, int pos)
{
    QTextBoundaryFinder finder(QTextBoundaryFinder::Word, text);
    finder.setPosition(pos);

    if (finder.boundaryReasons() & QTextBoundaryFinder::StartOfItem) {
        int end = finder.toNextBoundary();
        return qMakePair(pos, end - pos);
    } else if (finder.boundaryReasons() & QTextBoundaryFinder::EndOfItem) {
        int begin = finder.toPreviousBoundary();
        return qMakePair(begin, pos - begin);
    } else {
        int begin = finder.toPreviousBoundary();
        if (finder.boundaryReasons() & QTextBoundaryFinder::StartOfItem) {
            int end = finder.toNextBoundary();
            return qMakePair(begin, end - begin);
        } else {
            int end = finder.toPreviousBoundary();
            return qMakePair(end, begin - end);
        }
    }
    return qMakePair(-1, -1);
}

static int indexOfWord(const QString& text, int pos)
{
    return text.left(pos + 1).split(QLatin1Char(' '), QString::SkipEmptyParts).count() - 1;
}

static int indexOfNonSpace(const QString& text, int pos = 0)
{
    while (pos >= 0 && pos < text.length() && text.at(pos) == QLatin1Char(' '))
        ++pos;
    return pos;
}

static QString replaceWord(const QString& text, int index, const QString& word)
{
    if (index >= 0) {
        int from = indexOfNonSpace(text);
        while (index > 0 && from < text.length()) {
            from = indexOfNonSpace(text, text.indexOf(QLatin1Char(' '), from));
            --index;
        }
        if (from < text.length()) {
            int to = text.indexOf(QLatin1Char(' '), from);
            if (to == -1)
                to = text.length();
            return QString(text).replace(from, to - from, word);
        }
    }
    return text;
}

struct IrcCompletion
{
    IrcCompletion(const QString& txt, int pos) : text(txt), cursor(pos) { }
    bool operator ==(const IrcCompletion& other) const { return text == other.text && cursor == other.cursor; }
    bool operator !=(const IrcCompletion& other) const { return text != other.text || cursor != other.cursor; }
    QString text;
    int cursor;
};

class IrcCompleterPrivate
{
    Q_DECLARE_PUBLIC(IrcCompleter)

public:
    IrcCompleterPrivate();

    void completeNext();
    QList<IrcCompletion> completeCommands(const QString& text, int pos) const;
    QList<IrcCompletion> completeWords(const QString& text, int pos) const;

    IrcCompleter* q_ptr;

    int index;
    int cursor;
    QString text;
    QList<IrcCompletion> completions;

    QPointer<IrcBuffer> buffer;
    QPointer<IrcCommandParser> parser;
};

IrcCompleterPrivate::IrcCompleterPrivate() : q_ptr(0), index(-1), cursor(-1), buffer(0), parser(0)
{
}

void IrcCompleterPrivate::completeNext()
{
    Q_Q(IrcCompleter);
    Q_ASSERT(!completions.isEmpty());
    if (++index >= 0) {
        index %= completions.length();
        const IrcCompletion completion = completions.at(index);
        text = completion.text;
        cursor = completion.cursor;
        emit q->completed(text, cursor);
    }
}

static IrcCompletion completeCommand(const QString& text, const QString& command)
{
    QString completion = replaceWord(text, 0, command);
    int next = command.length();
    if (next >= completion.length() || completion.at(next) != QLatin1Char(' '))
        completion.insert(next, QLatin1Char(' '));
    return IrcCompletion(completion, ++next);
}

QList<IrcCompletion> IrcCompleterPrivate::completeCommands(const QString& text, int pos) const
{
    if (!parser)
        return QList<IrcCompletion>();

    QList<IrcCompletion> completions;

    int removed = 0;
    QString input = text;
    IrcCommandParserPrivate* pp = IrcCommandParserPrivate::get(parser);
    if (pp->processCommand(&input, &removed)) {
        const QString command = input.split(QLatin1Char(' '), QString::SkipEmptyParts).value(0).toUpper();
        if (!command.isEmpty()) {
            foreach (const IrcCommandInfo& cmd, pp->commands) {
                if (cmd.command == command)
                    return QList<IrcCompletion>() << completeCommand(text, text.left(removed) + cmd.command);
                if (cmd.command.startsWith(command))
                    completions += completeCommand(text, text.left(removed) + cmd.command);
            }
        }
        // TODO: context sensitive command parameter completion
        Q_UNUSED(pos);
    }
    return completions;
}

static IrcCompletion completeWord(const QString& text, int from, int len, const QString& word)
{
    QString completion = QString(text).replace(from, len, word);
    int next = from + word.length();
    if (next >= completion.length() || completion.at(next) != QLatin1Char(' '))
        completion.insert(next, QLatin1Char(' '));
    return IrcCompletion(completion, ++next);
}

QList<IrcCompletion> IrcCompleterPrivate::completeWords(const QString& text, int pos) const
{
    if (!buffer)
        return QList<IrcCompletion>();

    QList<IrcCompletion> completions;

    const QPair<int, int> bounds = findWordBoundaries(text, pos);
    if (bounds.first != -1 && bounds.second != -1) {
        const QString word = text.mid(bounds.first, bounds.second);

        const IrcBufferModel* model = buffer->model();
        foreach (IrcBuffer* buffer, model->buffers()) {
            const QString title = buffer->title();
            if (title.startsWith(word, Qt::CaseInsensitive))
                completions += completeWord(text, bounds.first, bounds.second, title);
        }

        IrcUserModel userModel;
        userModel.setSortMethod(Irc::SortByActivity);
        userModel.setChannel(qobject_cast<IrcChannel*>(buffer));
        foreach (IrcUser* user, userModel.users()) {
            if (user->name().startsWith(word, Qt::CaseInsensitive)) {
                QString name = user->name();
                if (indexOfWord(text, pos) == 0)
                    name += QLatin1Char(':'); // TODO: configurable
                completions += completeWord(text, bounds.first, bounds.second, name);
            }
        }
    }
    return completions;
}
#endif // IRC_DOXYGEN

/*!
    Constructs a completer with \a parent.
 */
IrcCompleter::IrcCompleter(QObject* parent) : QObject(parent), d_ptr(new IrcCompleterPrivate)
{
    Q_D(IrcCompleter);
    d->q_ptr = this;
}

/*!
    Destructs the completer.
 */
IrcCompleter::~IrcCompleter()
{
}

/*!
    This property holds the buffer used for name completion.

    \par Access functions:
    \li \ref IrcBuffer* buffer() const
    \li void setBuffer(\ref IrcBuffer* buffer)

    \par Notifier signal:
    \li void bufferChanged(\ref IrcBuffer* buffer)
 */
IrcBuffer* IrcCompleter::buffer() const
{
    Q_D(const IrcCompleter);
    return d->buffer;
}

void IrcCompleter::setBuffer(IrcBuffer* buffer)
{
    Q_D(IrcCompleter);
    if (d->buffer != buffer) {
        d->buffer = buffer;
        emit bufferChanged(buffer);
    }
}

/*!
    This property holds the parser used for command completion.

    \par Access functions:
    \li \ref IrcCommandParser* parser() const
    \li void setParser(\ref IrcCommandParser* parser)

    \par Notifier signal:
    \li void parserChanged(\ref IrcCommandParser* parser)
 */
IrcCommandParser* IrcCompleter::parser() const
{
    Q_D(const IrcCompleter);
    return d->parser;
}

void IrcCompleter::setParser(IrcCommandParser* parser)
{
    Q_D(IrcCompleter);
    if (d->parser != parser) {
        d->parser = parser;
        emit parserChanged(parser);
    }
}

/*!
    Completes \a text at \a cursor position and emits
    completed() if a suitable completion is found.
 */
void IrcCompleter::complete(const QString& text, int cursor)
{
    Q_D(IrcCompleter);
    if (!d->completions.isEmpty() && d->cursor == cursor && d->text == text) {
        d->completeNext();
        return;
    }

    QList<IrcCompletion> completions = d->completeCommands(text, cursor);
    if (completions.isEmpty() || indexOfWord(text, cursor) > 0)
        completions = d->completeWords(text, cursor);

    if (d->completions != completions) {
        d->index = -1;
        d->completions = completions;
    }
    if (!d->completions.isEmpty())
        d->completeNext();
}

#include "moc_irccompleter.cpp"

IRC_END_NAMESPACE
<commit_msg>IrcCompleter: make channel name completion smarter<commit_after>/*
* Copyright (C) 2008-2013 The Communi Project
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
* License for more details.
*/

#include "irccompleter.h"
#include "irccommandparser.h"
#include "irccommandparser_p.h"
#include "ircbuffermodel.h"
#include "ircusermodel.h"
#include "ircnetwork.h"
#include "ircchannel.h"
#include "ircuser.h"

#include <QTextBoundaryFinder>
#include <QPointer>
#include <QList>
#include <QPair>

IRC_BEGIN_NAMESPACE

/*!
    \file irccompleter.h
    \brief \#include <IrcCompleter>
 */

/*!
    \since 3.1
    \class IrcCompleter irccompleter.h <IrcCompleter>
    \ingroup util
    \brief Provides command and name completion.

    IrcCompleter provides command and name completion for a text input field. The completer
    is made context aware by assigning a command \ref IrcCompleter::parser "parser" and a
    \ref buffer that is currently active in the GUI. The parser is used for completing
    commands, and the buffer is used for completing buffer and user names.

    In order to perform a completion, call complete() with the current text input field
    content and the cursor position. If a suitable completion is found, the completed()
    signal is emitted with a suggestion for a new content and cursor position for the
    text input field.

    \code
    TextField {
        id: textField

        Keys.onTabPressed: completer.complete(text, cursorPosition)

        IrcCompleter {
            id: completer

            buffer: ...
            parser: ...

            onCompleted: {
                textField.text = text
                textField.cursorPosition = cursor
            }
        }
    }
    \endcode

    \sa IrcCommandParser, IrcBuffer
 */

/*!
    \fn void IrcCompleter::completed(const QString& text, int cursor)

    This signal is emitted when a suitable completion with \a text and \a cursor position is found.
 */

#ifndef IRC_DOXYGEN

#if QT_VERSION < 0x050000
#define StartOfItem StartWord
#define EndOfItem EndWord
#endif // QT_VERSION

static bool isPrefixed(const QString& text, int pos, const QStringList& prefixes, int* len)
{
    foreach (const QString& prefix, prefixes) {
        const int ll = prefix.length();
        if (text.mid(pos, ll) == prefix) {
            if (len)
                *len = 0;
            return true;
        } else if (text.mid(pos - ll, ll) == prefix) {
            if (len)
                *len = ll;
            return true;
        }
    }
    return false;
}

static QPair<int, int> findWordBoundaries(const QString& text, int pos, const QStringList& prefixes)
{
    QTextBoundaryFinder finder(QTextBoundaryFinder::Word, text);
    finder.setPosition(pos);

    int pfx = 0;
    if (finder.boundaryReasons() & QTextBoundaryFinder::StartOfItem || (finder.isAtBoundary() && isPrefixed(text, pos, prefixes, &pfx))) {
        int end = finder.toNextBoundary();
        if (end == -1)
            end = pos;
        pos -= pfx;
        return qMakePair(pos, end - pos);
    } else if (finder.boundaryReasons() & QTextBoundaryFinder::EndOfItem) {
        int begin = finder.toPreviousBoundary();
        return qMakePair(begin, pos - begin);
    } else {
        int begin = finder.toPreviousBoundary();
        if (finder.boundaryReasons() & QTextBoundaryFinder::StartOfItem || (finder.isAtBoundary() && isPrefixed(text, pos, prefixes, &pfx))) {
            int end = finder.toNextBoundary();
            if (end == -1)
                end = begin;
            begin -= pfx;
            return qMakePair(begin, end - begin);
        } else {
            int end = finder.toPreviousBoundary();
            return qMakePair(end, begin - end);
        }
    }
    return qMakePair(-1, -1);
}

static int indexOfWord(const QString& text, int pos)
{
    return text.left(pos + 1).split(QLatin1Char(' '), QString::SkipEmptyParts).count() - 1;
}

static int indexOfNonSpace(const QString& text, int pos = 0)
{
    while (pos >= 0 && pos < text.length() && text.at(pos) == QLatin1Char(' '))
        ++pos;
    return pos;
}

static QString replaceWord(const QString& text, int index, const QString& word)
{
    if (index >= 0) {
        int from = indexOfNonSpace(text);
        while (index > 0 && from < text.length()) {
            from = indexOfNonSpace(text, text.indexOf(QLatin1Char(' '), from));
            --index;
        }
        if (from < text.length()) {
            int to = text.indexOf(QLatin1Char(' '), from);
            if (to == -1)
                to = text.length();
            return QString(text).replace(from, to - from, word);
        }
    }
    return text;
}

struct IrcCompletion
{
    IrcCompletion(const QString& txt, int pos) : text(txt), cursor(pos) { }
    bool operator ==(const IrcCompletion& other) const { return text == other.text && cursor == other.cursor; }
    bool operator !=(const IrcCompletion& other) const { return text != other.text || cursor != other.cursor; }
    QString text;
    int cursor;
};

class IrcCompleterPrivate
{
    Q_DECLARE_PUBLIC(IrcCompleter)

public:
    IrcCompleterPrivate();

    void completeNext();
    QList<IrcCompletion> completeCommands(const QString& text, int pos) const;
    QList<IrcCompletion> completeWords(const QString& text, int pos) const;

    IrcCompleter* q_ptr;

    int index;
    int cursor;
    QString text;
    QList<IrcCompletion> completions;

    QPointer<IrcBuffer> buffer;
    QPointer<IrcCommandParser> parser;
};

IrcCompleterPrivate::IrcCompleterPrivate() : q_ptr(0), index(-1), cursor(-1), buffer(0), parser(0)
{
}

void IrcCompleterPrivate::completeNext()
{
    Q_Q(IrcCompleter);
    Q_ASSERT(!completions.isEmpty());
    if (++index >= 0) {
        index %= completions.length();
        const IrcCompletion completion = completions.at(index);
        text = completion.text;
        cursor = completion.cursor;
        emit q->completed(text, cursor);
    }
}

static IrcCompletion completeCommand(const QString& text, const QString& command)
{
    QString completion = replaceWord(text, 0, command);
    int next = command.length();
    if (next >= completion.length() || completion.at(next) != QLatin1Char(' '))
        completion.insert(next, QLatin1Char(' '));
    return IrcCompletion(completion, ++next);
}

QList<IrcCompletion> IrcCompleterPrivate::completeCommands(const QString& text, int pos) const
{
    if (!parser)
        return QList<IrcCompletion>();

    QList<IrcCompletion> completions;

    int removed = 0;
    QString input = text;
    IrcCommandParserPrivate* pp = IrcCommandParserPrivate::get(parser);
    if (pp->processCommand(&input, &removed)) {
        const QString command = input.split(QLatin1Char(' '), QString::SkipEmptyParts).value(0).toUpper();
        if (!command.isEmpty()) {
            foreach (const IrcCommandInfo& cmd, pp->commands) {
                if (cmd.command == command)
                    return QList<IrcCompletion>() << completeCommand(text, text.left(removed) + cmd.command);
                if (cmd.command.startsWith(command))
                    completions += completeCommand(text, text.left(removed) + cmd.command);
            }
        }
        // TODO: context sensitive command parameter completion
        Q_UNUSED(pos);
    }
    return completions;
}

static IrcCompletion completeWord(const QString& text, int from, int len, const QString& word)
{
    QString completion = QString(text).replace(from, len, word);
    int next = from + word.length();
    if (next >= completion.length() || completion.at(next) != QLatin1Char(' '))
        completion.insert(next, QLatin1Char(' '));
    return IrcCompletion(completion, ++next);
}

QList<IrcCompletion> IrcCompleterPrivate::completeWords(const QString& text, int pos) const
{
    if (!buffer || !buffer->network())
        return QList<IrcCompletion>();

    QList<IrcCompletion> completions;

    const QPair<int, int> bounds = findWordBoundaries(text, pos, buffer->network()->channelTypes());
    if (bounds.first != -1 && bounds.second != -1) {
        const QString word = text.mid(bounds.first, bounds.second);

        int pfx = 0;
        QString prefix;
        bool isChannel = isPrefixed(text, bounds.first, buffer->network()->channelTypes(), &pfx);
        if (isChannel && pfx > 0)
            prefix = text.mid(bounds.first - pfx, pfx);

        QList<IrcBuffer*> buffers = buffer->model()->buffers();
        buffers.move(buffers.indexOf(buffer), 0); // promote the current buffer
        foreach (IrcBuffer* buffer, buffers) {
            const QString title = buffer->title();
            if (title.startsWith(word, Qt::CaseInsensitive))
                completions += completeWord(text, bounds.first, bounds.second, title);
            else if (isChannel && !prefix.isEmpty() && title.startsWith(prefix + word, Qt::CaseInsensitive))
                completions += completeWord(text, bounds.first - prefix.length(), bounds.second + prefix.length(), title);
        }

        if (!isChannel) {
            IrcUserModel userModel;
            userModel.setSortMethod(Irc::SortByActivity);
            userModel.setChannel(qobject_cast<IrcChannel*>(buffer));
            foreach (IrcUser* user, userModel.users()) {
                if (user->name().startsWith(word, Qt::CaseInsensitive)) {
                    QString name = user->name();
                    if (indexOfWord(text, pos) == 0)
                        name += QLatin1Char(':'); // TODO: configurable
                    completions += completeWord(text, bounds.first, bounds.second, name);
                }
            }
        }
    }
    return completions;
}
#endif // IRC_DOXYGEN

/*!
    Constructs a completer with \a parent.
 */
IrcCompleter::IrcCompleter(QObject* parent) : QObject(parent), d_ptr(new IrcCompleterPrivate)
{
    Q_D(IrcCompleter);
    d->q_ptr = this;
}

/*!
    Destructs the completer.
 */
IrcCompleter::~IrcCompleter()
{
}

/*!
    This property holds the buffer used for name completion.

    \par Access functions:
    \li \ref IrcBuffer* buffer() const
    \li void setBuffer(\ref IrcBuffer* buffer)

    \par Notifier signal:
    \li void bufferChanged(\ref IrcBuffer* buffer)
 */
IrcBuffer* IrcCompleter::buffer() const
{
    Q_D(const IrcCompleter);
    return d->buffer;
}

void IrcCompleter::setBuffer(IrcBuffer* buffer)
{
    Q_D(IrcCompleter);
    if (d->buffer != buffer) {
        d->buffer = buffer;
        emit bufferChanged(buffer);
    }
}

/*!
    This property holds the parser used for command completion.

    \par Access functions:
    \li \ref IrcCommandParser* parser() const
    \li void setParser(\ref IrcCommandParser* parser)

    \par Notifier signal:
    \li void parserChanged(\ref IrcCommandParser* parser)
 */
IrcCommandParser* IrcCompleter::parser() const
{
    Q_D(const IrcCompleter);
    return d->parser;
}

void IrcCompleter::setParser(IrcCommandParser* parser)
{
    Q_D(IrcCompleter);
    if (d->parser != parser) {
        d->parser = parser;
        emit parserChanged(parser);
    }
}

/*!
    Completes \a text at \a cursor position and emits
    completed() if a suitable completion is found.
 */
void IrcCompleter::complete(const QString& text, int cursor)
{
    Q_D(IrcCompleter);
    if (!d->completions.isEmpty() && d->cursor == cursor && d->text == text) {
        d->completeNext();
        return;
    }

    QList<IrcCompletion> completions = d->completeCommands(text, cursor);
    if (completions.isEmpty() || indexOfWord(text, cursor) > 0)
        completions = d->completeWords(text, cursor);

    if (d->completions != completions) {
        d->index = -1;
        d->completions = completions;
    }
    if (!d->completions.isEmpty())
        d->completeNext();
}

#include "moc_irccompleter.cpp"

IRC_END_NAMESPACE
<|endoftext|>


<commit_before>/*
 * Copyright 2019-2019 Blender Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifdef _WIN32
#include <windows.h>
#endif

#include "util_windows.h"

CCL_NAMESPACE_BEGIN

bool system_windows_version_at_least(int major, int build)
{
#ifdef _WIN32
  HMODULE hMod = ::GetModuleHandleW(L"ntdll.dll");
  if (hMod == 0) {
    return false;
  }

  typedef NTSTATUS(WINAPI * RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
  RtlGetVersionPtr rtl_get_version = (RtlGetVersionPtr)::GetProcAddress(hMod, "RtlGetVersion");
  if (rtl_get_version == NULL) {
    return false;
  }

  RTL_OSVERSIONINFOW rovi = {0};
  rovi.dwOSVersionInfoSize = sizeof(rovi);
  if (rtl_get_version(&rovi) != 0) {
    return false;
  }

  return (rovi.dwMajorVersion > major ||
          (rovi.dwMajorVersion == major && rovi.dwBuildNumber >= build));
#else
  (void)major;
  (void)build;
  return false;
#endif
}

CCL_NAMESPACE_END
<commit_msg>Cleanup: warnings, formatting<commit_after>/*
 * Copyright 2019-2019 Blender Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifdef _WIN32
#  include <windows.h>
#endif

#include "util_windows.h"

CCL_NAMESPACE_BEGIN

bool system_windows_version_at_least(int major, int build)
{
#ifdef _WIN32
  HMODULE hMod = ::GetModuleHandleW(L"ntdll.dll");
  if (hMod == 0) {
    return false;
  }

  typedef NTSTATUS(WINAPI * RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
  RtlGetVersionPtr rtl_get_version = (RtlGetVersionPtr)::GetProcAddress(hMod, "RtlGetVersion");
  if (rtl_get_version == NULL) {
    return false;
  }

  RTL_OSVERSIONINFOW rovi = {0};
  rovi.dwOSVersionInfoSize = sizeof(rovi);
  if (rtl_get_version(&rovi) != 0) {
    return false;
  }

  return (rovi.dwMajorVersion > major ||
          (rovi.dwMajorVersion == major && rovi.dwBuildNumber >= build));
#else
  (void)major;
  (void)build;
  return false;
#endif
}

CCL_NAMESPACE_END
<|endoftext|>


<commit_before>/* -------------------------------------------------------------------------- */
/* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org)             */
/*                                                                            */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
/* not use this file except in compliance with the License. You may obtain    */
/* a copy of the License at                                                   */
/*                                                                            */
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
/*                                                                            */
/* Unless required by applicable law or agreed to in writing, software        */
/* distributed under the License is distributed on an "AS IS" BASIS,          */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
/* See the License for the specific language governing permissions and        */
/* limitations under the License.                                             */
/* -------------------------------------------------------------------------- */

#include "VirtualNetwork.h"
#include "NebulaLog.h"
#include "RangedLeases.h"
#include "FixedLeases.h"

/* ************************************************************************** */
/* Virtual Network :: Constructor/Destructor                                  */
/* ************************************************************************** */

VirtualNetwork::VirtualNetwork(unsigned int  mp, int ds):
                PoolObjectSQL(-1),
                name(""),
                uid(-1),
                bridge(""),
                type(UNINITIALIZED),
                leases(0),
                mac_prefix(mp),
                default_size(ds){};

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

VirtualNetwork::~VirtualNetwork()
{
    if (leases != 0)
    {
        delete leases;
    }
}

/* ************************************************************************** */
/* Virtual Network :: Database Access Functions                               */
/* ************************************************************************** */

const char * VirtualNetwork::table               = "network_pool";

const char * VirtualNetwork::db_names            = "(oid,uid,name,type,bridge)";

const char * VirtualNetwork::db_bootstrap        = "CREATE TABLE network_pool ("
     "oid INTEGER,uid INTEGER, name TEXT PRIMARY KEY,type INTEGER, bridge TEXT)";

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int VirtualNetwork::select_cb(void * nil, int num, char **values, char **names)
{
    if ((!values[OID])  ||
        (!values[UID])  ||
        (!values[NAME]) ||
        (!values[TYPE]) ||
        (!values[BRIDGE]) ||
        (num != LIMIT ))
    {
        return -1;
    }

    oid    = atoi(values[OID]);
    uid    = atoi(values[UID]);

    name   = values[NAME];

    type   = (NetworkType)atoi(values[TYPE]);

    bridge = values[BRIDGE];

    // Virtual Network template ID is the Network ID
    vn_template.id = oid;

    return 0;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int VirtualNetwork::select(SqlDB * db)
{
    ostringstream   oss;
    ostringstream   ose;

    int             rc;
    int             boid;

    string          network_address;

    set_callback(
        static_cast<Callbackable::Callback>(&VirtualNetwork::select_cb));

    oss << "SELECT * FROM " << table << " WHERE oid = " << oid;

    boid = oid;
    oid  = -1;

    rc = db->exec(oss, this);

    if ((rc != 0) || (oid != boid ))
    {
        goto error_id;
    }

    //Get the template
    rc = vn_template.select(db);

    if (rc != 0)
    {
        goto error_template;
    }

    //Get the leases
    if (type == RANGED)
    {
        string  nclass = "";
        int     size = 0;

        // retrieve specific information from template
        get_template_attribute("NETWORK_ADDRESS",network_address);

        if (network_address.empty())
        {
            goto error_addr;
        }

        get_template_attribute("NETWORK_SIZE",nclass);

        if ( nclass == "B" || nclass == "b" )
        {
            size = 65534;
        }
        else if ( nclass == "C" || nclass == "c" )
        {
            size = 254;
        }
        else if (!nclass.empty()) //Assume its a number
        {
            istringstream iss(nclass);
            iss >> size;
        }

        if (size == 0)
        {
            size = default_size;
        }

        leases = new RangedLeases::RangedLeases(db,
                                                oid,
                                                size,
                                                mac_prefix,
                                                network_address);
    }
    else if(type == FIXED)
    {
        leases = new  FixedLeases(db,
                                  oid,
                                  mac_prefix);
    }
    else
    {
        goto error_type;
    }

    if (leases == 0)
    {
        goto error_leases;
    }

    return leases->select(db);

error_id:
    ose << "Error getting Virtual Network nid: " << oid;
    goto error_common;

error_template:
    ose << "Can not get template for Virtual Network nid: " << oid;
    goto error_common;

error_leases:
    ose << "Error getting Virtual Network leases nid: " << oid;
    goto error_common;

error_type:
    ose << "Wrong type of Virtual Network: " << type;
    goto error_common;

error_addr:
    ose << "Network address is not defined nid: " << oid;

error_common:
    NebulaLog::log("VNM", Log::ERROR, ose);
    return -1;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int VirtualNetwork::dump(ostringstream& oss,
                         int            num,
                         char **        values,
                         char **        names)
{
    if ((!values[OID])   ||
        (!values[UID])   ||
        (!values[NAME])  ||
        (!values[TYPE])  ||
        (!values[BRIDGE])||
        (!values[LIMIT]) ||
        (num != LIMIT + 2 ))
    {
        return -1;
    }

    oss <<
        "<VNET>" <<
            "<ID>"       << values[OID]     << "</ID>"        <<
            "<UID>"      << values[UID]     << "</UID>"       <<
            "<USERNAME>" << values[LIMIT+1]  << "</USERNAME>" <<
            "<NAME>"     << values[NAME]    << "</NAME>"      <<
            "<TYPE>"     << values[TYPE]    << "</TYPE>"      <<
            "<BRIDGE>"   << values[BRIDGE]  << "</BRIDGE>"    <<
            "<TOTAL_LEASES>" << values[LIMIT]<< "</TOTAL_LEASES>" <<
        "</VNET>";

    return 0;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int VirtualNetwork::insert(SqlDB * db)
{
    ostringstream   ose;
    int             rc;

    if ( vn_template.id == -1 )
    {
        vn_template.id = oid;
    }

    // Insert the template first
    rc = vn_template.update(db);

    if ( rc != 0 )
    {
    	goto error_template;
    }

    // Insert the Virtual Network
    rc = update(db);

    if ( rc != 0 )
    {
        goto error_update;
    }

    //Get the leases
    if (type == VirtualNetwork::RANGED)
    {
        string nclass = "";
        string naddr  = "";
        int    size   = 0;

        // retrieve specific information from template
        get_template_attribute("NETWORK_ADDRESS",naddr);

        if (naddr.empty())
        {
            goto error_addr;
        }

        get_template_attribute("NETWORK_SIZE",nclass);

        if ( nclass == "B" || nclass == "b"  )
        {
            size = 65534;
        }
        else if ( nclass == "C" || nclass == "c"  )
        {
            size = 254;
        }
        else if (!nclass.empty())//Assume its a number
        {
            istringstream iss(nclass);

            iss >> size;
        }

        if (size == 0)
        {
            size = default_size;
        }

        leases = new RangedLeases::RangedLeases(db,
                                                oid,
                                                size,
                                                mac_prefix,
                                                naddr);
    }
    else if(type == VirtualNetwork::FIXED)
    {
        vector<const Attribute *>   vector_leases;

        get_template_attribute("LEASES",vector_leases);

        leases = new FixedLeases::FixedLeases(db,
                                              oid,
                                              mac_prefix,
                                              vector_leases);
    }
    else
    {
        goto error_type;
    }

    if (leases == 0)
    {
        goto error_null_leases;
    }

    return 0;

error_template:
    ose << "Can not insert in DB template for Virtual Network id " << oid;
    goto error_common;

error_update:
    ose << "Can not update Virtual Network id " << oid;
    vn_template.drop(db);
    goto error_common;

error_type:
    ose << "Wrong type of Virtual Network: " << type;
    goto error_leases;

error_addr:
    ose << "Network address is not defined nid: " << oid;
    goto error_leases;

error_null_leases:
    ose << "Error getting Virtual Network leases nid: " << oid;

error_leases:
    vn_drop(db);

error_common:
    NebulaLog::log("VNM", Log::ERROR, ose);
    return -1;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int VirtualNetwork::update(SqlDB * db)
{
    ostringstream   oss;
    int             rc;

    char * sql_name = db->escape_str(name.c_str());

    if ( sql_name == 0 )
    {
        return -1;
    }

    char * sql_bridge = db->escape_str(bridge.c_str());

    if ( sql_bridge == 0 )
    {
        db->free_str(sql_name);
        return -1;
    }

    oss << "INSERT OR REPLACE INTO " << table << " "<< db_names <<" VALUES ("<<
        oid << "," <<
        uid << "," <<
        "'" << sql_name << "',"  <<
        type << "," <<
        "'" << sql_bridge << "')";

    rc = db->exec(oss);

    db->free_str(sql_name);
    db->free_str(sql_bridge);

    return rc;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int VirtualNetwork::vn_drop(SqlDB * db)
{
    ostringstream   oss;
    int             rc;

    vn_template.drop(db);

    leases->drop(db);

    oss << "DELETE FROM " << table << " WHERE OID=" << oid;

    rc = db->exec(oss);

    if ( rc == 0 )
    {
        set_valid(false);
    }

    return rc;
}

/* ************************************************************************** */
/* Virtual Network :: Misc                                                    */
/* ************************************************************************** */

ostream& operator<<(ostream& os, VirtualNetwork& vn)
{
    string vnet_xml;

    os << vn.to_xml(vnet_xml);

    return os;
};

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

string& VirtualNetwork::to_xml(string& xml) const
{
    ostringstream os;

    string template_xml;
    string leases_xml;

    os <<
        "<VNET>" <<
            "<ID>"    << oid   << "</ID>"   <<
            "<UID>"   << uid   << "</UID>"  <<
            "<NAME>"  << name  << "</NAME>" <<
            "<TYPE>"  << type  << "</TYPE>" <<
            "<BRIDGE>"<< bridge<< "</BRIDGE>" <<
            vn_template.to_xml(template_xml);
    if (leases)
        os << leases->to_xml(leases_xml);
    os << "</VNET>";

    xml = os.str();

    return xml;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

string& VirtualNetwork::to_str(string& str) const
{
    ostringstream os;

    string template_str;
    string leases_str;

    os << "ID                : " << oid << endl;
    os << "UID               : " << uid << endl;
    os << "NAME              : " << name << endl;
    os << "Type              : ";
    if ( type==VirtualNetwork::RANGED )
    {
        os << "Ranged" << endl;
    }
    else
    {
       os << "Fixed" << endl;
    }

    os << "Bridge            : " << bridge << endl << endl;

    os << "....: Template :...." << vn_template.to_str(template_str) << endl << endl;

    if (leases)
    {
        os << "....: Leases :...." << endl << leases->to_str(leases_str) << endl;
    }

    str = os.str();

    return str;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */<commit_msg>bug : Fix compilation bug for g++ 4.5.0<commit_after>/* -------------------------------------------------------------------------- */
/* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org)             */
/*                                                                            */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
/* not use this file except in compliance with the License. You may obtain    */
/* a copy of the License at                                                   */
/*                                                                            */
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
/*                                                                            */
/* Unless required by applicable law or agreed to in writing, software        */
/* distributed under the License is distributed on an "AS IS" BASIS,          */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
/* See the License for the specific language governing permissions and        */
/* limitations under the License.                                             */
/* -------------------------------------------------------------------------- */

#include "VirtualNetwork.h"
#include "NebulaLog.h"
#include "RangedLeases.h"
#include "FixedLeases.h"

/* ************************************************************************** */
/* Virtual Network :: Constructor/Destructor                                  */
/* ************************************************************************** */

VirtualNetwork::VirtualNetwork(unsigned int  mp, int ds):
                PoolObjectSQL(-1),
                name(""),
                uid(-1),
                bridge(""),
                type(UNINITIALIZED),
                leases(0),
                mac_prefix(mp),
                default_size(ds){};

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

VirtualNetwork::~VirtualNetwork()
{
    if (leases != 0)
    {
        delete leases;
    }
}

/* ************************************************************************** */
/* Virtual Network :: Database Access Functions                               */
/* ************************************************************************** */

const char * VirtualNetwork::table               = "network_pool";

const char * VirtualNetwork::db_names            = "(oid,uid,name,type,bridge)";

const char * VirtualNetwork::db_bootstrap        = "CREATE TABLE network_pool ("
     "oid INTEGER,uid INTEGER, name TEXT PRIMARY KEY,type INTEGER, bridge TEXT)";

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int VirtualNetwork::select_cb(void * nil, int num, char **values, char **names)
{
    if ((!values[OID])  ||
        (!values[UID])  ||
        (!values[NAME]) ||
        (!values[TYPE]) ||
        (!values[BRIDGE]) ||
        (num != LIMIT ))
    {
        return -1;
    }

    oid    = atoi(values[OID]);
    uid    = atoi(values[UID]);

    name   = values[NAME];

    type   = (NetworkType)atoi(values[TYPE]);

    bridge = values[BRIDGE];

    // Virtual Network template ID is the Network ID
    vn_template.id = oid;

    return 0;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int VirtualNetwork::select(SqlDB * db)
{
    ostringstream   oss;
    ostringstream   ose;

    int             rc;
    int             boid;

    string          network_address;

    set_callback(
        static_cast<Callbackable::Callback>(&VirtualNetwork::select_cb));

    oss << "SELECT * FROM " << table << " WHERE oid = " << oid;

    boid = oid;
    oid  = -1;

    rc = db->exec(oss, this);

    if ((rc != 0) || (oid != boid ))
    {
        goto error_id;
    }

    //Get the template
    rc = vn_template.select(db);

    if (rc != 0)
    {
        goto error_template;
    }

    //Get the leases
    if (type == RANGED)
    {
        string  nclass = "";
        int     size = 0;

        // retrieve specific information from template
        get_template_attribute("NETWORK_ADDRESS",network_address);

        if (network_address.empty())
        {
            goto error_addr;
        }

        get_template_attribute("NETWORK_SIZE",nclass);

        if ( nclass == "B" || nclass == "b" )
        {
            size = 65534;
        }
        else if ( nclass == "C" || nclass == "c" )
        {
            size = 254;
        }
        else if (!nclass.empty()) //Assume its a number
        {
            istringstream iss(nclass);
            iss >> size;
        }

        if (size == 0)
        {
            size = default_size;
        }

        leases = new RangedLeases(db,
                                  oid,
                                  size,
                                  mac_prefix,
                                  network_address);
    }
    else if(type == FIXED)
    {
        leases = new  FixedLeases(db,
                                  oid,
                                  mac_prefix);
    }
    else
    {
        goto error_type;
    }

    if (leases == 0)
    {
        goto error_leases;
    }

    return leases->select(db);

error_id:
    ose << "Error getting Virtual Network nid: " << oid;
    goto error_common;

error_template:
    ose << "Can not get template for Virtual Network nid: " << oid;
    goto error_common;

error_leases:
    ose << "Error getting Virtual Network leases nid: " << oid;
    goto error_common;

error_type:
    ose << "Wrong type of Virtual Network: " << type;
    goto error_common;

error_addr:
    ose << "Network address is not defined nid: " << oid;

error_common:
    NebulaLog::log("VNM", Log::ERROR, ose);
    return -1;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int VirtualNetwork::dump(ostringstream& oss,
                         int            num,
                         char **        values,
                         char **        names)
{
    if ((!values[OID])   ||
        (!values[UID])   ||
        (!values[NAME])  ||
        (!values[TYPE])  ||
        (!values[BRIDGE])||
        (!values[LIMIT]) ||
        (num != LIMIT + 2 ))
    {
        return -1;
    }

    oss <<
        "<VNET>" <<
            "<ID>"       << values[OID]     << "</ID>"        <<
            "<UID>"      << values[UID]     << "</UID>"       <<
            "<USERNAME>" << values[LIMIT+1]  << "</USERNAME>" <<
            "<NAME>"     << values[NAME]    << "</NAME>"      <<
            "<TYPE>"     << values[TYPE]    << "</TYPE>"      <<
            "<BRIDGE>"   << values[BRIDGE]  << "</BRIDGE>"    <<
            "<TOTAL_LEASES>" << values[LIMIT]<< "</TOTAL_LEASES>" <<
        "</VNET>";

    return 0;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int VirtualNetwork::insert(SqlDB * db)
{
    ostringstream   ose;
    int             rc;

    if ( vn_template.id == -1 )
    {
        vn_template.id = oid;
    }

    // Insert the template first
    rc = vn_template.update(db);

    if ( rc != 0 )
    {
    	goto error_template;
    }

    // Insert the Virtual Network
    rc = update(db);

    if ( rc != 0 )
    {
        goto error_update;
    }

    //Get the leases
    if (type == VirtualNetwork::RANGED)
    {
        string nclass = "";
        string naddr  = "";
        int    size   = 0;

        // retrieve specific information from template
        get_template_attribute("NETWORK_ADDRESS",naddr);

        if (naddr.empty())
        {
            goto error_addr;
        }

        get_template_attribute("NETWORK_SIZE",nclass);

        if ( nclass == "B" || nclass == "b"  )
        {
            size = 65534;
        }
        else if ( nclass == "C" || nclass == "c"  )
        {
            size = 254;
        }
        else if (!nclass.empty())//Assume its a number
        {
            istringstream iss(nclass);

            iss >> size;
        }

        if (size == 0)
        {
            size = default_size;
        }

        leases = new RangedLeases(db,
                                  oid,
                                  size,
                                  mac_prefix,
                                  naddr);
    }
    else if(type == VirtualNetwork::FIXED)
    {
        vector<const Attribute *>   vector_leases;

        get_template_attribute("LEASES",vector_leases);

        leases = new FixedLeases(db,
                                 oid,
                                 mac_prefix,
                                 vector_leases);
    }
    else
    {
        goto error_type;
    }

    if (leases == 0)
    {
        goto error_null_leases;
    }

    return 0;

error_template:
    ose << "Can not insert in DB template for Virtual Network id " << oid;
    goto error_common;

error_update:
    ose << "Can not update Virtual Network id " << oid;
    vn_template.drop(db);
    goto error_common;

error_type:
    ose << "Wrong type of Virtual Network: " << type;
    goto error_leases;

error_addr:
    ose << "Network address is not defined nid: " << oid;
    goto error_leases;

error_null_leases:
    ose << "Error getting Virtual Network leases nid: " << oid;

error_leases:
    vn_drop(db);

error_common:
    NebulaLog::log("VNM", Log::ERROR, ose);
    return -1;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int VirtualNetwork::update(SqlDB * db)
{
    ostringstream   oss;
    int             rc;

    char * sql_name = db->escape_str(name.c_str());

    if ( sql_name == 0 )
    {
        return -1;
    }

    char * sql_bridge = db->escape_str(bridge.c_str());

    if ( sql_bridge == 0 )
    {
        db->free_str(sql_name);
        return -1;
    }

    oss << "INSERT OR REPLACE INTO " << table << " "<< db_names <<" VALUES ("<<
        oid << "," <<
        uid << "," <<
        "'" << sql_name << "',"  <<
        type << "," <<
        "'" << sql_bridge << "')";

    rc = db->exec(oss);

    db->free_str(sql_name);
    db->free_str(sql_bridge);

    return rc;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int VirtualNetwork::vn_drop(SqlDB * db)
{
    ostringstream   oss;
    int             rc;

    vn_template.drop(db);

    leases->drop(db);

    oss << "DELETE FROM " << table << " WHERE OID=" << oid;

    rc = db->exec(oss);

    if ( rc == 0 )
    {
        set_valid(false);
    }

    return rc;
}

/* ************************************************************************** */
/* Virtual Network :: Misc                                                    */
/* ************************************************************************** */

ostream& operator<<(ostream& os, VirtualNetwork& vn)
{
    string vnet_xml;

    os << vn.to_xml(vnet_xml);

    return os;
};

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

string& VirtualNetwork::to_xml(string& xml) const
{
    ostringstream os;

    string template_xml;
    string leases_xml;

    os <<
        "<VNET>" <<
            "<ID>"    << oid   << "</ID>"   <<
            "<UID>"   << uid   << "</UID>"  <<
            "<NAME>"  << name  << "</NAME>" <<
            "<TYPE>"  << type  << "</TYPE>" <<
            "<BRIDGE>"<< bridge<< "</BRIDGE>" <<
            vn_template.to_xml(template_xml);
    if (leases)
        os << leases->to_xml(leases_xml);
    os << "</VNET>";

    xml = os.str();

    return xml;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

string& VirtualNetwork::to_str(string& str) const
{
    ostringstream os;

    string template_str;
    string leases_str;

    os << "ID                : " << oid << endl;
    os << "UID               : " << uid << endl;
    os << "NAME              : " << name << endl;
    os << "Type              : ";
    if ( type==VirtualNetwork::RANGED )
    {
        os << "Ranged" << endl;
    }
    else
    {
       os << "Fixed" << endl;
    }

    os << "Bridge            : " << bridge << endl << endl;

    os << "....: Template :...." << vn_template.to_str(template_str) << endl << endl;

    if (leases)
    {
        os << "....: Leases :...." << endl << leases->to_str(leases_str) << endl;
    }

    str = os.str();

    return str;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
<|endoftext|>


<commit_before>/*
* Copyright (C) 2011 Daniele E. Domenichelli <daniele.domenichelli@gmail.com>
* Copyright (C) 1999 Preston Brown <pbrown@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "telepathy-handler-application.h"

#include <QTimer>
#include <KCmdLineArgs>
#include <KDebug>

#include <TelepathyQt4/Types>
#include <TelepathyQt4/Debug>

extern bool kde_kdebug_enable_dbus_interface;

namespace KTelepathy {

class TelepathyHandlerApplication::Private
{
public:
    Private(TelepathyHandlerApplication *q);
    ~Private();

    void _k_onInitialTimeout();
    void _k_onTimeout();

    static KComponentData initHack();
    void init(int initialTimeout, int timeout);

    TelepathyHandlerApplication *q;

    static bool s_persist;
    static bool s_debug;

    int timeout;
    QTimer *timer;
    bool firstJobStarted;
    QAtomicInt jobCount;
};

TelepathyHandlerApplication::Private::Private(TelepathyHandlerApplication *q)
    : q(q),
      firstJobStarted(false),
      jobCount(0)
{
}

TelepathyHandlerApplication::Private::~Private()
{
}

void TelepathyHandlerApplication::Private::_k_onInitialTimeout()
{
    if (jobCount == 0 && jobCount.fetchAndAddOrdered(-1) == 0) {
        // m_jobCount is now -1
        kDebug() << "No job received. Exiting";
        QCoreApplication::quit();
    }
}

void TelepathyHandlerApplication::Private::_k_onTimeout()
{
    if (jobCount == 0 && jobCount.fetchAndAddOrdered(-1) == 0) {
        // m_jobCount is now -1
        kDebug() << "Timeout. Exiting";
        QCoreApplication::quit();
    }
}

// this gets called before even entering QApplication::QApplication()
KComponentData TelepathyHandlerApplication::Private::initHack()
{
    KComponentData cData(KCmdLineArgs::aboutData());
    KCmdLineOptions handler_options;
    handler_options.add("persist", ki18n("Persistent mode (do not exit on timeout)"));
    handler_options.add("debug", ki18n("Show Telepathy debugging information"));
    KCmdLineArgs::addCmdLineOptions(handler_options, ki18n("KDE Telepathy"), "kde-telepathy", "kde");
    KCmdLineArgs *args = KCmdLineArgs::parsedArgs("kde-telepathy");
    Private::s_persist = args->isSet("persist");
    Private::s_debug = args->isSet("debug");
    return cData;
}

void TelepathyHandlerApplication::Private::init(int initialTimeout, int timeout)
{
    q->setQuitOnLastWindowClosed(false);

    Tp::registerTypes();
    //Enable telepathy-Qt4 debug
    Tp::enableDebug(s_debug);
    Tp::enableWarnings(true);

    if (s_debug) {
        kde_kdebug_enable_dbus_interface = true;
    }

    if (!Private::s_persist) {
        this->timeout = timeout;
        timer = new QTimer(q);
        q->connect(timer, SIGNAL(timeout()), q, SLOT(_k_onInitialTimeout()));
        timer->start(initialTimeout);
    }
}

bool TelepathyHandlerApplication::Private::s_persist = false;
bool TelepathyHandlerApplication::Private::s_debug = false;

TelepathyHandlerApplication::TelepathyHandlerApplication(bool GUIenabled,
                                                         int initialTimeout,
                                                         int timeout)
    : KApplication(GUIenabled, Private::initHack()),
      d(new Private(this))
{
    d->init(initialTimeout, timeout);
}

TelepathyHandlerApplication::TelepathyHandlerApplication(Display *display,
                                                         Qt::HANDLE visual,
                                                         Qt::HANDLE colormap,
                                                         int initialTimeout,
                                                         int timeout)
    : KApplication(display, visual, colormap, Private::initHack()),
      d(new Private(this))
{
    d->init(initialTimeout, timeout);
}

TelepathyHandlerApplication::~TelepathyHandlerApplication()
{
    delete d;
}

int TelepathyHandlerApplication::newJob()
{
    TelepathyHandlerApplication *app = qobject_cast<TelepathyHandlerApplication*>(KApplication::kApplication());
    TelepathyHandlerApplication::Private *d = app->d;

    int ret = d->jobCount.fetchAndAddOrdered(1);
    if (!Private::s_persist) {
        if (d->timer->isActive()) {
            d->timer->stop();
        }
        if (!d->firstJobStarted) {
            disconnect(d->timer, SIGNAL(timeout()), app, SLOT(_k_onInitialTimeout()));
            connect(d->timer, SIGNAL(timeout()), app, SLOT(_k_onTimeout()));
            d->firstJobStarted = true;
        }
    }
    return ret;
}

void TelepathyHandlerApplication::jobFinished()
{
    TelepathyHandlerApplication *app = qobject_cast<TelepathyHandlerApplication*>(KApplication::kApplication());
    TelepathyHandlerApplication::Private *d = app->d;

    if (d->jobCount.fetchAndAddOrdered(-1) <= 1) {
        kDebug() << "No other jobs at the moment. Starting timer.";
        if (!Private::s_persist) {
            d->timer->start(d->timeout);
        }
    }
}

} // namespace KTelepathy

#include "telepathy-handler-application.moc"
<commit_msg>Handle initialTimeout and timeout only if >= 0<commit_after>/*
* Copyright (C) 2011 Daniele E. Domenichelli <daniele.domenichelli@gmail.com>
* Copyright (C) 1999 Preston Brown <pbrown@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "telepathy-handler-application.h"

#include <QTimer>
#include <KCmdLineArgs>
#include <KDebug>

#include <TelepathyQt4/Types>
#include <TelepathyQt4/Debug>

extern bool kde_kdebug_enable_dbus_interface;

namespace KTelepathy {

class TelepathyHandlerApplication::Private
{
public:
    Private(TelepathyHandlerApplication *q);
    ~Private();

    void _k_onInitialTimeout();
    void _k_onTimeout();

    static KComponentData initHack();
    void init(int initialTimeout, int timeout);

    TelepathyHandlerApplication *q;

    static bool s_persist;
    static bool s_debug;

    int initialTimeout;
    int timeout;
    QTimer *timer;
    bool firstJobStarted;
    QAtomicInt jobCount;
};

TelepathyHandlerApplication::Private::Private(TelepathyHandlerApplication *q)
    : q(q),
      firstJobStarted(false),
      jobCount(0)
{
}

TelepathyHandlerApplication::Private::~Private()
{
}

void TelepathyHandlerApplication::Private::_k_onInitialTimeout()
{
    if (jobCount == 0 && jobCount.fetchAndAddOrdered(-1) == 0) {
        // m_jobCount is now -1
        kDebug() << "No job received. Exiting";
        QCoreApplication::quit();
    }
}

void TelepathyHandlerApplication::Private::_k_onTimeout()
{
    if (jobCount == 0 && jobCount.fetchAndAddOrdered(-1) == 0) {
        // m_jobCount is now -1
        kDebug() << "Timeout. Exiting";
        QCoreApplication::quit();
    }
}

// this gets called before even entering QApplication::QApplication()
KComponentData TelepathyHandlerApplication::Private::initHack()
{
    KComponentData cData(KCmdLineArgs::aboutData());
    KCmdLineOptions handler_options;
    handler_options.add("persist", ki18n("Persistent mode (do not exit on timeout)"));
    handler_options.add("debug", ki18n("Show Telepathy debugging information"));
    KCmdLineArgs::addCmdLineOptions(handler_options, ki18n("KDE Telepathy"), "kde-telepathy", "kde");
    KCmdLineArgs *args = KCmdLineArgs::parsedArgs("kde-telepathy");
    Private::s_persist = args->isSet("persist");
    Private::s_debug = args->isSet("debug");
    return cData;
}

void TelepathyHandlerApplication::Private::init(int initialTimeout, int timeout)
{
    this->initialTimeout = timeout;
    this->timeout = timeout;

    // If timeout < 0 we let the application exit when the last window is closed,
    // Otherwise we handle it with the timeout
    if (timeout >= 0) {
        q->setQuitOnLastWindowClosed(false);
    }

    Tp::registerTypes();
    //Enable telepathy-Qt4 debug
    Tp::enableDebug(s_debug);
    Tp::enableWarnings(true);

    if (s_debug) {
        kde_kdebug_enable_dbus_interface = true;
    }

    if (!Private::s_persist) {
        timer = new QTimer(q);
        if (initialTimeout >= 0) {
            q->connect(timer, SIGNAL(timeout()), q, SLOT(_k_onInitialTimeout()));
            timer->start(initialTimeout);
        }
    }
}

bool TelepathyHandlerApplication::Private::s_persist = false;
bool TelepathyHandlerApplication::Private::s_debug = false;

TelepathyHandlerApplication::TelepathyHandlerApplication(bool GUIenabled,
                                                         int initialTimeout,
                                                         int timeout)
    : KApplication(GUIenabled, Private::initHack()),
      d(new Private(this))
{
    d->init(initialTimeout, timeout);
}

TelepathyHandlerApplication::TelepathyHandlerApplication(Display *display,
                                                         Qt::HANDLE visual,
                                                         Qt::HANDLE colormap,
                                                         int initialTimeout,
                                                         int timeout)
    : KApplication(display, visual, colormap, Private::initHack()),
      d(new Private(this))
{
    d->init(initialTimeout, timeout);
}

TelepathyHandlerApplication::~TelepathyHandlerApplication()
{
    delete d;
}

int TelepathyHandlerApplication::newJob()
{
    TelepathyHandlerApplication *app = qobject_cast<TelepathyHandlerApplication*>(KApplication::kApplication());
    TelepathyHandlerApplication::Private *d = app->d;

    int ret = d->jobCount.fetchAndAddOrdered(1);
    if (!Private::s_persist) {
        if (d->timer->isActive()) {
            d->timer->stop();
        }
        if (!d->firstJobStarted) {
            if (d->initialTimeout) {
                disconnect(d->timer, SIGNAL(timeout()), app, SLOT(_k_onInitialTimeout()));
            }
            if (d->timeout >= 0) {
                connect(d->timer, SIGNAL(timeout()), app, SLOT(_k_onTimeout()));
            }
            d->firstJobStarted = true;
        }
    }
    return ret;
}

void TelepathyHandlerApplication::jobFinished()
{
    TelepathyHandlerApplication *app = qobject_cast<TelepathyHandlerApplication*>(KApplication::kApplication());
    TelepathyHandlerApplication::Private *d = app->d;

    if (d->jobCount.fetchAndAddOrdered(-1) <= 1) {
        kDebug() << "No other jobs at the moment. Starting timer.";
        if (!Private::s_persist && d->timeout >= 0) {
            d->timer->start(d->timeout);
        }
    }
}

} // namespace KTelepathy

#include "telepathy-handler-application.moc"
<|endoftext|>