<commit_before>#include <GDE/Core/ConfigReader.hpp>
#include <GDE/Core/StringsUtil.hpp>
#include <GDE/Core/Log.hpp>

#include <cstdio>
#include <cstring>

namespace GDE
{

ConfigReader::ConfigReader()
{
    ////ILOGM("ConfigReader::ctor()");
}

ConfigReader::ConfigReader(const ConfigReader& theCopy) :
    sections(theCopy.sections)
{
}

ConfigReader::~ConfigReader()
{
    ////ILOGM("ConfigReader::dtor()");

    // Borra todos los pares <clave,valor> del mapa
    std::map<const std::string, typeNameValue*>::iterator iter;
    iter = this->sections.begin();
    while (iter != this->sections.end())
    {
        typeNameValue* anMap = iter->second;
        this->sections.erase(iter++);
        delete anMap;
    }
}

bool ConfigReader::isSectionEmpty(const std::string theSection) const
{
    bool anResult = false;

    // Comprueba si una sección existe
    std::map<const std::string, typeNameValue*>::const_iterator iter;
    iter = this->sections.find(theSection);
    if (iter != this->sections.end())
    {
        typeNameValue* anMap = iter->second;
        if (NULL != anMap)
        {
            anResult = anMap->empty();
        }
    }

    // Devuelve el resultado obtenido anteriormente o false en caso de no encontrase la sección
    return anResult;
}

bool ConfigReader::getBool(const std::string theSection,
    const std::string theName, const bool theDefault) const
{
    bool anResult = theDefault;

    // Comprueba si la sección existe
    std::map<const std::string, typeNameValue*>::const_iterator iter;
    iter = this->sections.find(theSection);
    if (iter != this->sections.end())
    {
        // Intenta obtener el par <clave, valor>
        typeNameValue* anMap = iter->second;
        if (NULL != anMap)
        {
            typeNameValueIter iterNameValue;
            iterNameValue = anMap->find(theName);
            if (iterNameValue != anMap->end())
            {
                anResult = parseBool(iterNameValue->second, theDefault);
            }
        }
    }

    // Devuelve el resultado encontrado o el valor de theDefault
    return anResult;
}

float ConfigReader::getFloat(const std::string theSection,
    const std::string theName, const float theDefault) const
{
    float anResult = theDefault;

    // Comprueba si la sección existe
    std::map<const std::string, typeNameValue*>::const_iterator iter;
    iter = this->sections.find(theSection);
    if (iter != this->sections.end())
    {
        // Intenta obtener el par <clave, valor>
        typeNameValue* anMap = iter->second;
        if (NULL != anMap)
        {
            typeNameValueIter iterNameValue;
            iterNameValue = anMap->find(theName);
            if (iterNameValue != anMap->end())
            {
                anResult = parseFloat(iterNameValue->second, theDefault);
            }
        }
    }

    // Devuelve el resultado encontrado o el valor de theDefault
    return anResult;
}

std::string ConfigReader::getString(const std::string theSection,
    const std::string theName, const std::string theDefault) const
{
    std::string anResult = theDefault;

    // Comprueba si la sección existe
    std::map<const std::string, typeNameValue*>::const_iterator iter;
    iter = this->sections.find(theSection);
    if (iter != this->sections.end())
    {
        // Intenta obtener el par <clave, valor>
        typeNameValue* anMap = iter->second;
        if (NULL != anMap)
        {
            typeNameValueIter iterNameValue;
            iterNameValue = anMap->find(theName);
            if (iterNameValue != anMap->end())
            {
                anResult = iterNameValue->second;
            }
        }
    }

    // Devuelve el resultado encontrado o el valor de theDefault
    return anResult;
}

sf::Uint32 ConfigReader::getUint32(const std::string theSection, const std::string theName, const sf::Uint32 theDefault) const
{
    sf::Uint32 anResult = theDefault;
    // Comprueba si la sección existe
    std::map<const std::string, typeNameValue*>::const_iterator iter;
    iter = this->sections.find(theSection);
    if (iter != this->sections.end())
    {
        // Intenta obtener el par <clave, valor>
        typeNameValue* anMap = iter->second;
        if (NULL != anMap)
        {
            typeNameValueIter iterNameValue;
            iterNameValue = anMap->find(theName);
            if (iterNameValue != anMap->end())
            {
                anResult = parseUint32(iterNameValue->second, theDefault);
            }
        }
    }

    // Devuelve el resultado encontrado o el valor de theDefault
    return anResult;
}

bool ConfigReader::loadFromFile(const std::string& theFilename)
{
    bool anResult = false;
    char anLine[MAX_CHARS];
    std::string anSection;
    unsigned long anCount = 1;

	// Indicamos en el log que estamos cargando un fichero
    GDE::Log::info("ConfigReader::loadFromFile","Abriendo fichero "+theFilename+".");

    // Intentamos abrir el fichero
    FILE* anFile = fopen(theFilename.c_str(), "r");

    // Leemos el fichero si se abrió correctamente
    if (NULL != anFile)
    {
        // Leemos hasta que lleguemos al final del fichero
        while (!feof(anFile))
        {
            // Obtenemos la primera línea del fichero
            if (fgets(anLine, MAX_CHARS, anFile) == NULL)
            {
                // Si ocurre un error lo metemos en el log
                if (!feof(anFile))
                {
                    GDE::Log::error("ConfigReader::Read", "Error leyendo la línea " + anCount);
                }
                // Salimos del bucle
                break;
            }
            else
            {
                // Parseamos la línea
                anSection = parseLine(anLine, anCount, anSection);
            }

            // Incrementamos el contador de líneas
            anCount++;
        }

        // Cerramos el fichero
        fclose(anFile);

        // Indicamos que todo se realizó correctamente
        anResult = true;
    }
    else
    {
        GDE::Log::error("ConfigReader::loadFromFile","Error al leer fichero " + theFilename+".");
    }

    // Devuelve true en caso de éxito, false en caso contrario
    return anResult;
}

ConfigReader& ConfigReader::operator=(const ConfigReader& theRight)
{
    // Usamos el contructor de copia
    ConfigReader temp(theRight);

    // Intercambiamos las copias
    std::swap(this->sections, temp.sections);

    // Devolvemos el puntero
    return *this;
}

std::string ConfigReader::parseLine(const char* theLine,
    const unsigned long theCount, const std::string theSection)
{
    std::string anResult = theSection;
    size_t anLength = strlen(theLine);
    if (anLength > 1)
    {
        // Ignoramos los espacios
        size_t anOffset = 0;
        while (anOffset < anLength && theLine[anOffset] == ' ')
        {
            anOffset++;
        }

        // Comprobamos si hay comentarios
        if (theLine[anOffset] != '#' && theLine[anOffset] != ';')
        {
            // Comprobamos el comienzo de una nueva sección
            if (theLine[anOffset] == '[')
            {
                // Saltamos el inicio de sección '['
                anOffset++;

                // Ignoramos los espacios
                while (anOffset < anLength && theLine[anOffset] == ' ')
                {
                    anOffset++;
                }

                // Obtenemos el nombre de la sección mientras buscamos el final de la sección ']'
                size_t anIndex = 0;
                char anSection[MAX_CHARS] = { 0 };
                while ((anOffset + anIndex) < anLength && theLine[anOffset + anIndex] != ']')
                {
                    // Obtenemos el nombre de la sección de theLine
                    anSection[anIndex] = theLine[anOffset + anIndex];

                    // Incrementamos anIndex
                    anIndex++;
                }
                // Añadimos el delimitador de final de cadena
                anSection[anIndex] = '\0';
                // Eliminamos espacios finales
                while (anIndex > 0 && anSection[anIndex - 1] == ' ')
                {
                    // Ponemos el delimitador de final de cadena a la sección
                    anSection[--anIndex] = '\0';
                }

                //Solo actualizamos el nombre de sección si encontramos el deliminador de sección ']'
                //antes del final de la línea
                if ((anOffset + anIndex) < anLength && anIndex > 0)
                {
                    // Actualizamos el nombre de la sección
                    anResult = anSection;
                }
                else
                {
                    GDE::Log::error("ConfigReader::parseLine", "No se encontró el delimitador de sección ']' en la línea " + theCount);
                }
            }
            // Leemos el par <clave,valor> de la sección actual.
            else
            {
                size_t anNameIndex = 0;
                char anName[MAX_CHARS];

                // Obtenemos la clave mientras buscamos "=" o ":"
                while ((anOffset + anNameIndex) < anLength &&
                    theLine[(anOffset + anNameIndex)] != '=' &&
                    theLine[(anOffset + anNameIndex)] != ':')
                {
                    // Obtenemos anName de theLine
                    anName[anNameIndex] = theLine[anOffset + anNameIndex];

                    // Incrementamos anNameIndex
                    anNameIndex++;
                }
                // Asignamos nuestro valor offset
                anOffset += anNameIndex;
                // Ponemos el delimitador de cadena
                anName[anNameIndex] = '\0';
                // Eliminamos los espacios del final
                while (anNameIndex > 0 && anName[anNameIndex - 1] == ' ')
                {
                    // Ponemos el delimitador de cadena
                    anName[--anNameIndex] = '\0';
                }

                // Solo buscamos el valor si encontramos el delimitador ":" o "="
                if (anOffset < anLength && anNameIndex > 0)
                {
                    size_t anValueIndex = 0;
                    char anValue[MAX_CHARS];

                    // Nos saltamos el delimitador ":" o "="
                    anOffset++;

                    // Eliminamos espacios
                    while (anOffset < anLength && theLine[anOffset] == ' ')
                    {
                        anOffset++;
                    }
                    // Obtenemos el valor mientras buscamos el final de línea o el comienzo de un comentario
                    while ((anOffset + anValueIndex) < anLength &&
                        theLine[(anOffset + anValueIndex)] != '\r' &&
                        theLine[(anOffset + anValueIndex)] != '\n' &&
                        theLine[(anOffset + anValueIndex)] != ';' &&
                        theLine[(anOffset + anValueIndex)] != '#')
                    {
                        // Obtenemos anValue de theLine
                        anValue[anValueIndex] = theLine[anOffset + anValueIndex];

                        // Incrementamos anValueIndex
                        anValueIndex++;
                    }
                    // Ponemos el delimitador de final de cadena
                    anValue[anValueIndex] = '\0';
                    // Eliminamos los espacios
                    while (anValueIndex > 0 && anValue[anValueIndex - 1] == ' ')
                    {
                        // Ponemos el delimitador de final de cadena
                        anValue[--anValueIndex] = '\0';
                    }

                    // Almacenamos el par <clave,valor>
                    storeNameValue(theSection, anName, anValue);
                }
                else
                {
                    GDE::Log::error("ConfigReader::parseLine","No se encontró el delimitador de nombre o valor '=' o ':' en la línea " + theCount);
                }
            }
        } // if(theLine[anOffset] != '#' && theLine[anOffset] != ';')
    } // if(anLength > 1)

    // Devolvemos la el nombre de la nueva sección en caso de encontrarla, en caso contrario
    // se devuelve el nombre de la sección anterior
    return anResult;
}

void ConfigReader::storeNameValue(const std::string theSection,
    const std::string theName, const std::string theValue)
{
    // Comprobamos si el par <clave,valor> ya existe para theSection
    std::map<const std::string, typeNameValue*>::iterator iterSection;
    iterSection = this->sections.find(theSection);
    if (iterSection == this->sections.end())
    {
        // Intentamos crear un nuevo mapa para almacenar los pares <clave,valor> de dicha sección
        typeNameValue* anMap = new(std::nothrow) typeNameValue;

        // Nos aseguramos de que hemos creado el mapa correctamente
        if (NULL != anMap)
        {
            GDE::Log::info("ConfigReader::StoreNameValue","Añadiendo "+theName+"="+theValue + " a la sección [" + theSection+"].");

            // Añadimos el nuevo par <clave,valor> al mapa
            anMap->insert(std::pair<const std::string, const std::string>(theName, theValue));

            // Añadimos el mapa creado anteriormente a la sección
            this->sections.insert(std::pair<const std::string, typeNameValue*>(theSection, anMap));
        }
        else
        {
            GDE::Log::error("ConfigReader::StoreNameValue","Imposible añadir "+theName+"="+theValue + " a la sección [" + theSection+"] posible falta de memoria.");
        }
    }
    else
    {
        // Retrieve the existing name, value pair map
        typeNameValue* anMap = iterSection->second;

        // Nos aseguramos de que hemos creado el mapa correctamente
        if (NULL != anMap)
        {
            // Nos aseguramos de que el par <clave,valor> no esté ya en el mapa
            typeNameValueIter iterNameValue;
            iterNameValue = anMap->find(theName);
            if (iterNameValue == anMap->end())
            {
                GDE::Log::info("ConfigReader::StoreNameValue","Añadiendo "+theName+"="+theValue + " a la sección [" + theSection+"].");
                // Añadimos el nuevo par <clave,valor>
                anMap->insert(std::pair<const std::string, const std::string>(theName, theValue));
            }
            else
            {
                GDE::Log::error("ConfigReader::StoreNameValue","Imposible añadir "+theName+"="+theValue + " a la sección [" + theSection+"] porque ya existe.");
            }
        }
    } // else(iterSection == mSections.end())
}

} // namespace GDE
<commit_msg>Eliminados comentarios innecesarios<commit_after>#include <GDE/Core/ConfigReader.hpp>
#include <GDE/Core/StringsUtil.hpp>
#include <GDE/Core/Log.hpp>

#include <cstdio>
#include <cstring>

namespace GDE
{

ConfigReader::ConfigReader()
{
}

ConfigReader::ConfigReader(const ConfigReader& theCopy) :
    sections(theCopy.sections)
{
}

ConfigReader::~ConfigReader()
{
    // Borra todos los pares <clave,valor> del mapa
    std::map<const std::string, typeNameValue*>::iterator iter;
    iter = this->sections.begin();
    while (iter != this->sections.end())
    {
        typeNameValue* anMap = iter->second;
        this->sections.erase(iter++);
        delete anMap;
    }
}

bool ConfigReader::isSectionEmpty(const std::string theSection) const
{
    bool anResult = false;

    // Comprueba si una sección existe
    std::map<const std::string, typeNameValue*>::const_iterator iter;
    iter = this->sections.find(theSection);
    if (iter != this->sections.end())
    {
        typeNameValue* anMap = iter->second;
        if (NULL != anMap)
        {
            anResult = anMap->empty();
        }
    }

    // Devuelve el resultado obtenido anteriormente o false en caso de no encontrase la sección
    return anResult;
}

bool ConfigReader::getBool(const std::string theSection,
    const std::string theName, const bool theDefault) const
{
    bool anResult = theDefault;

    // Comprueba si la sección existe
    std::map<const std::string, typeNameValue*>::const_iterator iter;
    iter = this->sections.find(theSection);
    if (iter != this->sections.end())
    {
        // Intenta obtener el par <clave, valor>
        typeNameValue* anMap = iter->second;
        if (NULL != anMap)
        {
            typeNameValueIter iterNameValue;
            iterNameValue = anMap->find(theName);
            if (iterNameValue != anMap->end())
            {
                anResult = parseBool(iterNameValue->second, theDefault);
            }
        }
    }

    // Devuelve el resultado encontrado o el valor de theDefault
    return anResult;
}

float ConfigReader::getFloat(const std::string theSection,
    const std::string theName, const float theDefault) const
{
    float anResult = theDefault;

    // Comprueba si la sección existe
    std::map<const std::string, typeNameValue*>::const_iterator iter;
    iter = this->sections.find(theSection);
    if (iter != this->sections.end())
    {
        // Intenta obtener el par <clave, valor>
        typeNameValue* anMap = iter->second;
        if (NULL != anMap)
        {
            typeNameValueIter iterNameValue;
            iterNameValue = anMap->find(theName);
            if (iterNameValue != anMap->end())
            {
                anResult = parseFloat(iterNameValue->second, theDefault);
            }
        }
    }

    // Devuelve el resultado encontrado o el valor de theDefault
    return anResult;
}

std::string ConfigReader::getString(const std::string theSection,
    const std::string theName, const std::string theDefault) const
{
    std::string anResult = theDefault;

    // Comprueba si la sección existe
    std::map<const std::string, typeNameValue*>::const_iterator iter;
    iter = this->sections.find(theSection);
    if (iter != this->sections.end())
    {
        // Intenta obtener el par <clave, valor>
        typeNameValue* anMap = iter->second;
        if (NULL != anMap)
        {
            typeNameValueIter iterNameValue;
            iterNameValue = anMap->find(theName);
            if (iterNameValue != anMap->end())
            {
                anResult = iterNameValue->second;
            }
        }
    }

    // Devuelve el resultado encontrado o el valor de theDefault
    return anResult;
}

sf::Uint32 ConfigReader::getUint32(const std::string theSection, const std::string theName, const sf::Uint32 theDefault) const
{
    sf::Uint32 anResult = theDefault;
    // Comprueba si la sección existe
    std::map<const std::string, typeNameValue*>::const_iterator iter;
    iter = this->sections.find(theSection);
    if (iter != this->sections.end())
    {
        // Intenta obtener el par <clave, valor>
        typeNameValue* anMap = iter->second;
        if (NULL != anMap)
        {
            typeNameValueIter iterNameValue;
            iterNameValue = anMap->find(theName);
            if (iterNameValue != anMap->end())
            {
                anResult = parseUint32(iterNameValue->second, theDefault);
            }
        }
    }

    // Devuelve el resultado encontrado o el valor de theDefault
    return anResult;
}

bool ConfigReader::loadFromFile(const std::string& theFilename)
{
    bool anResult = false;
    char anLine[MAX_CHARS];
    std::string anSection;
    unsigned long anCount = 1;

	// Indicamos en el log que estamos cargando un fichero
    GDE::Log::info("ConfigReader::loadFromFile","Abriendo fichero "+theFilename+".");

    // Intentamos abrir el fichero
    FILE* anFile = fopen(theFilename.c_str(), "r");

    // Leemos el fichero si se abrió correctamente
    if (NULL != anFile)
    {
        // Leemos hasta que lleguemos al final del fichero
        while (!feof(anFile))
        {
            // Obtenemos la primera línea del fichero
            if (fgets(anLine, MAX_CHARS, anFile) == NULL)
            {
                // Si ocurre un error lo metemos en el log
                if (!feof(anFile))
                {
                    GDE::Log::error("ConfigReader::Read", "Error leyendo la línea " + anCount);
                }
                // Salimos del bucle
                break;
            }
            else
            {
                // Parseamos la línea
                anSection = parseLine(anLine, anCount, anSection);
            }

            // Incrementamos el contador de líneas
            anCount++;
        }

        // Cerramos el fichero
        fclose(anFile);

        // Indicamos que todo se realizó correctamente
        anResult = true;
    }
    else
    {
        GDE::Log::error("ConfigReader::loadFromFile","Error al leer fichero " + theFilename+".");
    }

    // Devuelve true en caso de éxito, false en caso contrario
    return anResult;
}

ConfigReader& ConfigReader::operator=(const ConfigReader& theRight)
{
    // Usamos el contructor de copia
    ConfigReader temp(theRight);

    // Intercambiamos las copias
    std::swap(this->sections, temp.sections);

    // Devolvemos el puntero
    return *this;
}

std::string ConfigReader::parseLine(const char* theLine,
    const unsigned long theCount, const std::string theSection)
{
    std::string anResult = theSection;
    size_t anLength = strlen(theLine);
    if (anLength > 1)
    {
        // Ignoramos los espacios
        size_t anOffset = 0;
        while (anOffset < anLength && theLine[anOffset] == ' ')
        {
            anOffset++;
        }

        // Comprobamos si hay comentarios
        if (theLine[anOffset] != '#' && theLine[anOffset] != ';')
        {
            // Comprobamos el comienzo de una nueva sección
            if (theLine[anOffset] == '[')
            {
                // Saltamos el inicio de sección '['
                anOffset++;

                // Ignoramos los espacios
                while (anOffset < anLength && theLine[anOffset] == ' ')
                {
                    anOffset++;
                }

                // Obtenemos el nombre de la sección mientras buscamos el final de la sección ']'
                size_t anIndex = 0;
                char anSection[MAX_CHARS] = { 0 };
                while ((anOffset + anIndex) < anLength && theLine[anOffset + anIndex] != ']')
                {
                    // Obtenemos el nombre de la sección de theLine
                    anSection[anIndex] = theLine[anOffset + anIndex];

                    // Incrementamos anIndex
                    anIndex++;
                }
                // Añadimos el delimitador de final de cadena
                anSection[anIndex] = '\0';
                // Eliminamos espacios finales
                while (anIndex > 0 && anSection[anIndex - 1] == ' ')
                {
                    // Ponemos el delimitador de final de cadena a la sección
                    anSection[--anIndex] = '\0';
                }

                //Solo actualizamos el nombre de sección si encontramos el deliminador de sección ']'
                //antes del final de la línea
                if ((anOffset + anIndex) < anLength && anIndex > 0)
                {
                    // Actualizamos el nombre de la sección
                    anResult = anSection;
                }
                else
                {
                    GDE::Log::error("ConfigReader::parseLine", "No se encontró el delimitador de sección ']' en la línea " + theCount);
                }
            }
            // Leemos el par <clave,valor> de la sección actual.
            else
            {
                size_t anNameIndex = 0;
                char anName[MAX_CHARS];

                // Obtenemos la clave mientras buscamos "=" o ":"
                while ((anOffset + anNameIndex) < anLength &&
                    theLine[(anOffset + anNameIndex)] != '=' &&
                    theLine[(anOffset + anNameIndex)] != ':')
                {
                    // Obtenemos anName de theLine
                    anName[anNameIndex] = theLine[anOffset + anNameIndex];

                    // Incrementamos anNameIndex
                    anNameIndex++;
                }
                // Asignamos nuestro valor offset
                anOffset += anNameIndex;
                // Ponemos el delimitador de cadena
                anName[anNameIndex] = '\0';
                // Eliminamos los espacios del final
                while (anNameIndex > 0 && anName[anNameIndex - 1] == ' ')
                {
                    // Ponemos el delimitador de cadena
                    anName[--anNameIndex] = '\0';
                }

                // Solo buscamos el valor si encontramos el delimitador ":" o "="
                if (anOffset < anLength && anNameIndex > 0)
                {
                    size_t anValueIndex = 0;
                    char anValue[MAX_CHARS];

                    // Nos saltamos el delimitador ":" o "="
                    anOffset++;

                    // Eliminamos espacios
                    while (anOffset < anLength && theLine[anOffset] == ' ')
                    {
                        anOffset++;
                    }
                    // Obtenemos el valor mientras buscamos el final de línea o el comienzo de un comentario
                    while ((anOffset + anValueIndex) < anLength &&
                        theLine[(anOffset + anValueIndex)] != '\r' &&
                        theLine[(anOffset + anValueIndex)] != '\n' &&
                        theLine[(anOffset + anValueIndex)] != ';' &&
                        theLine[(anOffset + anValueIndex)] != '#')
                    {
                        // Obtenemos anValue de theLine
                        anValue[anValueIndex] = theLine[anOffset + anValueIndex];

                        // Incrementamos anValueIndex
                        anValueIndex++;
                    }
                    // Ponemos el delimitador de final de cadena
                    anValue[anValueIndex] = '\0';
                    // Eliminamos los espacios
                    while (anValueIndex > 0 && anValue[anValueIndex - 1] == ' ')
                    {
                        // Ponemos el delimitador de final de cadena
                        anValue[--anValueIndex] = '\0';
                    }

                    // Almacenamos el par <clave,valor>
                    storeNameValue(theSection, anName, anValue);
                }
                else
                {
                    GDE::Log::error("ConfigReader::parseLine","No se encontró el delimitador de nombre o valor '=' o ':' en la línea " + theCount);
                }
            }
        } // if(theLine[anOffset] != '#' && theLine[anOffset] != ';')
    } // if(anLength > 1)

    // Devolvemos la el nombre de la nueva sección en caso de encontrarla, en caso contrario
    // se devuelve el nombre de la sección anterior
    return anResult;
}

void ConfigReader::storeNameValue(const std::string theSection,
    const std::string theName, const std::string theValue)
{
    // Comprobamos si el par <clave,valor> ya existe para theSection
    std::map<const std::string, typeNameValue*>::iterator iterSection;
    iterSection = this->sections.find(theSection);
    if (iterSection == this->sections.end())
    {
        // Intentamos crear un nuevo mapa para almacenar los pares <clave,valor> de dicha sección
        typeNameValue* anMap = new(std::nothrow) typeNameValue;

        // Nos aseguramos de que hemos creado el mapa correctamente
        if (NULL != anMap)
        {
            GDE::Log::info("ConfigReader::StoreNameValue","Añadiendo "+theName+"="+theValue + " a la sección [" + theSection+"].");

            // Añadimos el nuevo par <clave,valor> al mapa
            anMap->insert(std::pair<const std::string, const std::string>(theName, theValue));

            // Añadimos el mapa creado anteriormente a la sección
            this->sections.insert(std::pair<const std::string, typeNameValue*>(theSection, anMap));
        }
        else
        {
            GDE::Log::error("ConfigReader::StoreNameValue","Imposible añadir "+theName+"="+theValue + " a la sección [" + theSection+"] posible falta de memoria.");
        }
    }
    else
    {
        // Retrieve the existing name, value pair map
        typeNameValue* anMap = iterSection->second;

        // Nos aseguramos de que hemos creado el mapa correctamente
        if (NULL != anMap)
        {
            // Nos aseguramos de que el par <clave,valor> no esté ya en el mapa
            typeNameValueIter iterNameValue;
            iterNameValue = anMap->find(theName);
            if (iterNameValue == anMap->end())
            {
                GDE::Log::info("ConfigReader::StoreNameValue","Añadiendo "+theName+"="+theValue + " a la sección [" + theSection+"].");
                // Añadimos el nuevo par <clave,valor>
                anMap->insert(std::pair<const std::string, const std::string>(theName, theValue));
            }
            else
            {
                GDE::Log::error("ConfigReader::StoreNameValue","Imposible añadir "+theName+"="+theValue + " a la sección [" + theSection+"] porque ya existe.");
            }
        }
    } // else(iterSection == mSections.end())
}

} // namespace GDE
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: provider.cxx,v $
 *
 *  $Revision: 1.1 $
 *
 *  last change: $Author: dg $ $Date: 2000-11-10 22:42:46 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#include "provider.hxx"

#ifndef CONFIGMGR_MODULE_HXX_
#include "configmodule.hxx"
#endif
#ifndef CONFIGMGR_CMTREEMODEL_HXX
#include "cmtreemodel.hxx"
#endif
#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif
#ifndef __SGI_STL_ALGORITHM
#include <stl/algorithm>
#endif
#ifndef _COMPHELPER_SEQUENCE_HXX_
#include <comphelper/sequence.hxx>
#endif
#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
#include <cppuhelper/typeprovider.hxx>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif

#define THISREF() static_cast< ::cppu::OWeakObject* >(this)

namespace configmgr
{
    namespace css  = ::com::sun::star;
    namespace uno  = css::uno;
    namespace lang = css::lang;
    namespace beans = css::beans;
    using ::rtl::OUString;
    using ::vos::ORef;
    using namespace osl;

    //=============================================================================
    //= OProvider
    //=============================================================================
    //-----------------------------------------------------------------------------
    OProvider::OProvider(Module& aModule, ServiceInfo const* pInfo)
              :ServiceComponentImpl(pInfo)
              ,m_aModule(aModule)
    {
    }

    // XTypeOProvider
    //-----------------------------------------------------------------------------
    uno::Sequence< uno::Type > SAL_CALL OProvider::getTypes(  ) throw(uno::RuntimeException)
    {
        return ::comphelper::concatSequences(ServiceComponentImpl::getTypes(), OProvider_Base::getTypes());
    }

    // XInterface
    //-----------------------------------------------------------------------------
    uno::Any SAL_CALL OProvider::queryInterface(uno::Type const& rType) throw(uno::RuntimeException)
    {
        uno::Any aRet( ServiceComponentImpl::queryInterface(rType) );
        if ( !aRet.hasValue() )
            aRet = OProvider_Base::queryInterface(rType);
        return aRet;
    }

    //-----------------------------------------------------------------------------
    void SAL_CALL OProvider::disposing()
    {
        sal_Bool bIsConnected = isConnected();
        if (bIsConnected)
        {
            ::osl::MutexGuard aGuard(m_aMutex);
            if (isConnected())
                disconnect();
        }
        ServiceComponentImpl::disposing();
    }

    // XInitialization
    //-----------------------------------------------------------------------------
    void SAL_CALL OProvider::initialize( const uno::Sequence< uno::Any >& _rArguments ) throw (uno::Exception, uno::RuntimeException)
    {
        ::osl::MutexGuard aGuard(m_aMutex);
        if (isConnected() || m_aSecurityOverride.size())
        {
            if (0 == _rArguments.getLength())
                // allow initialize without arguments ....
                return; //? Should this not ensureConnection() ?

            throw uno::Exception(::rtl::OUString::createFromAscii("The configuration OProvider has already been initialized."), THISREF());
        }

        const uno::Any* pArguments = _rArguments.getConstArray();
        beans::PropertyValue aCurrentArg;
        for (sal_Int32 i=0; i<_rArguments.getLength(); ++i, ++pArguments)
        {
            if (!((*pArguments) >>= aCurrentArg))
                throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii("Arguments have to be com.sun.star.beans.PropertyValue's."), THISREF(), i);

            // no check if the argument is known and valid. This would require to much testing
            m_aSecurityOverride[aCurrentArg.Name] = aCurrentArg.Value;
        }

        // connect here and now, thus the createInstanceWithArguments fails if no connection is made
        connect();
    }
} // namespace configmgr

<commit_msg>compiler problems<commit_after>/*************************************************************************
 *
 *  $RCSfile: provider.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: dg $ $Date: 2000-11-10 23:02:35 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#include "provider.hxx"

#ifndef CONFIGMGR_MODULE_HXX_
#include "configmodule.hxx"
#endif
#ifndef CONFIGMGR_CMTREEMODEL_HXX
#include "cmtreemodel.hxx"
#endif
#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif
#ifndef __SGI_STL_ALGORITHM
#include <stl/algorithm>
#endif
#ifndef _COMPHELPER_SEQUENCE_HXX_
#include <comphelper/sequence.hxx>
#endif
#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
#include <cppuhelper/typeprovider.hxx>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif

#define THISREF() static_cast< ::cppu::OWeakObject* >(this)

namespace configmgr
{
    namespace css  = ::com::sun::star;
    namespace uno  = css::uno;
    namespace lang = css::lang;
    namespace beans = css::beans;
    using ::rtl::OUString;
    using ::vos::ORef;
    using namespace osl;

    //=============================================================================
    //= OProvider
    //=============================================================================
    //-----------------------------------------------------------------------------
    OProvider::OProvider(Module& aModule, ServiceInfo const* pInfo)
              :ServiceComponentImpl(pInfo)
              ,m_aModule(aModule)
    {
    }

    // XTypeOProvider
    //-----------------------------------------------------------------------------
    uno::Sequence< uno::Type > SAL_CALL OProvider::getTypes(  ) throw(uno::RuntimeException)
    {
        return ::comphelper::concatSequences(ServiceComponentImpl::getTypes(), OProvider_Base::getTypes());
    }

    // XInterface
    //-----------------------------------------------------------------------------
    uno::Any SAL_CALL OProvider::queryInterface(uno::Type const& rType) throw(uno::RuntimeException)
    {
        uno::Any aRet( ServiceComponentImpl::queryInterface(rType) );
        if ( !aRet.hasValue() )
            aRet = OProvider_Base::queryInterface(rType);
        return aRet;
    }

    //-----------------------------------------------------------------------------
    void SAL_CALL OProvider::disposing()
    {
        sal_Bool bIsConnected = isConnected();
        if (bIsConnected)
        {
            ::osl::MutexGuard aGuard(m_aMutex);
            if (isConnected())
                disconnect();
        }
        ServiceComponentImpl::disposing();
    }

    // XInitialization
    //-----------------------------------------------------------------------------
    void SAL_CALL OProvider::initialize( const uno::Sequence< uno::Any >& _rArguments ) throw (uno::Exception, uno::RuntimeException)
    {
        ::osl::MutexGuard aGuard(m_aMutex);
        if (isConnected() || m_aSecurityOverride.size())
        {
            if (0 == _rArguments.getLength())
                // allow initialize without arguments ....
                return; //? Should this not ensureConnection() ?

            throw uno::Exception(::rtl::OUString::createFromAscii("The configuration OProvider has already been initialized."), THISREF());
        }

        const uno::Any* pArguments = _rArguments.getConstArray();
        beans::PropertyValue aCurrentArg;
        for (sal_Int32 i=0; i<_rArguments.getLength(); ++i, ++pArguments)
        {
            if (!((*pArguments) >>= aCurrentArg))
            {
                throw uno::Exception(::rtl::OUString::createFromAscii("The configuration OProvider has already been initialized."), THISREF());
//throw lang::IllegalArgumentException(::rtl::OUString::createFromAscii("Arguments have to be com.sun.star.beans.PropertyValue's."), THISREF());
            }

            // no check if the argument is known and valid. This would require to much testing
            m_aSecurityOverride[aCurrentArg.Name] = aCurrentArg.Value;
        }

        // connect here and now, thus the createInstanceWithArguments fails if no connection is made
        connect();
    }
} // namespace configmgr

<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (c) Juergen Riegel          (juergen.riegel@web.de) 2012    *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library 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 Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"

#ifndef _PreComp_
# include <sstream>
# include <QApplication>
# include <Inventor/SoPickedPoint.h>
# include <Inventor/events/SoMouseButtonEvent.h>
# include <Inventor/nodes/SoSeparator.h>
# include <Inventor/nodes/SoBaseColor.h>
# include <Inventor/nodes/SoFontStyle.h>
# include <Inventor/nodes/SoPickStyle.h>
# include <Inventor/nodes/SoText2.h>
# include <Inventor/nodes/SoTranslation.h>
# include <Inventor/nodes/SoCoordinate3.h>
# include <Inventor/nodes/SoIndexedLineSet.h>
# include <Inventor/nodes/SoMarkerSet.h>
# include <Inventor/nodes/SoDrawStyle.h>
#endif

#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoAnnotation.h>
#include <Inventor/details/SoLineDetail.h>
#include <Inventor/nodes/SoAsciiText.h>
#include "ViewProviderPlane.h"
#include "SoFCSelection.h"
#include "Application.h"
#include "Document.h"
#include "View3DInventorViewer.h"
#include "Inventor/SoAutoZoomTranslation.h"
#include "SoAxisCrossKit.h"
//#include <SoDepthBuffer.h>

#include <App/PropertyGeo.h>
#include <App/PropertyStandard.h>
#include <App/MeasureDistance.h>
#include <Base/Console.h>

using namespace Gui;

PROPERTY_SOURCE(Gui::ViewProviderPlane, Gui::ViewProviderGeometryObject)

ViewProviderPlane::ViewProviderPlane()
{

    ADD_PROPERTY(Size,(1.0));

    pMat = new SoMaterial();
    pMat->ref();

    float size = Size.getValue(); // Note: If you change this, you need to also adapt App/Plane.cpp getBoundBox()

    SbVec3f verts[4] =
    {
        SbVec3f(size,size,0), SbVec3f(size,-size,0),
        SbVec3f(-size,-size,0), SbVec3f(-size,size,0),
    };

    // indexes used to create the edges
    static const int32_t lines[6] =
    {
        0,1,2,3,0,-1
    };

    pMat->diffuseColor.setNum(1);
    pMat->diffuseColor.set1Value(0, SbColor(1.0f, 1.0f, 1.0f));

    pCoords = new SoCoordinate3();
    pCoords->ref();
    pCoords->point.setNum(4);
    pCoords->point.setValues(0, 4, verts);

    pLines  = new SoIndexedLineSet();
    pLines->ref();
    pLines->coordIndex.setNum(6);
    pLines->coordIndex.setValues(0, 6, lines);

    pFont = new SoFont();
    pFont->size.setValue(Size.getValue()/10.);

    pTranslation = new SoTranslation();
    pTranslation->translation.setValue(SbVec3f(-1,9./10.,0));

    pText = new SoAsciiText();
    pText->width.setValue(-1);

    sPixmap = "view-measurement";
}

ViewProviderPlane::~ViewProviderPlane()
{
    pCoords->unref();
    pLines->unref();
    pMat->unref();
}

void ViewProviderPlane::onChanged(const App::Property* prop)
{
        if (prop == &Size){
                float size = Size.getValue(); // Note: If you change this, you need to also adapt App/Plane.cpp getBoundBox()

                SbVec3f verts[4] =
                {
                    SbVec3f(size,size,0), SbVec3f(size,-size,0),
                    SbVec3f(-size,-size,0), SbVec3f(-size,size,0),
                };

                pCoords->point.setValues(0, 4, verts);
                pFont->size.setValue(Size.getValue()/10.);
                pTranslation->translation.setValue(SbVec3f(-size,size*9./10.,0));
        }
        else
         ViewProviderGeometryObject::onChanged(prop);
}

std::vector<std::string> ViewProviderPlane::getDisplayModes(void) const
{
    // add modes
    std::vector<std::string> StrList;
    StrList.push_back("Base");
    return StrList;
}

void ViewProviderPlane::setDisplayMode(const char* ModeName)
{
    if (strcmp(ModeName, "Base") == 0)
        setDisplayMaskMode("Base");
    ViewProviderGeometryObject::setDisplayMode(ModeName);
}

void ViewProviderPlane::attach(App::DocumentObject* pcObject)
{
    ViewProviderGeometryObject::attach(pcObject);

    SoSeparator  *sep = new SoSeparator();
    SoAnnotation *lineSep = new SoAnnotation();

    SoDrawStyle* style = new SoDrawStyle();
    style->lineWidth = 1.0f;

    SoMaterialBinding* matBinding = new SoMaterialBinding;
    matBinding->value = SoMaterialBinding::PER_FACE;

    sep->addChild(style);
    sep->addChild(matBinding);
    sep->addChild(pMat);
    sep->addChild(pCoords);
    sep->addChild(pLines);

    style = new SoDrawStyle();
    style->lineWidth = 1.0f;
    style->linePattern.setValue(0x00FF);
    lineSep->addChild(style);
    lineSep->addChild(pLines);
    lineSep->addChild(pFont);
    pText->string.setValue(SbString(pcObject->Label.getValue()));
    lineSep->addChild(pTranslation);
    lineSep->addChild(pText);
    sep->addChild(lineSep);

    addDisplayMaskMode(sep, "Base");
}

void ViewProviderPlane::updateData(const App::Property* prop)
{
    pText->string.setValue(SbString(pcObject->Label.getValue()));
    ViewProviderGeometryObject::updateData(prop);
}

std::string ViewProviderPlane::getElement(const SoDetail* detail) const
{
    if (detail) {
        if (detail->getTypeId() == SoLineDetail::getClassTypeId()) {
            const SoLineDetail* line_detail = static_cast<const SoLineDetail*>(detail);
            int edge = line_detail->getLineIndex();
            if (edge == 0)
            {
                return std::string("Main");
            }
        }
    }

    return std::string("");
}

SoDetail* ViewProviderPlane::getDetail(const char* subelement) const
{
    SoLineDetail* detail = 0;
    std::string subelem(subelement);
    int edge = -1;

    if(subelem == "Main") edge = 0;

    if(edge >= 0) {
         detail = new SoLineDetail();
         detail->setPartIndex(edge);
    }

    return detail;
}

bool ViewProviderPlane::isSelectable(void) const
{
    return true;
}
// ----------------------------------------------------------------------------

<commit_msg>highlight planes<commit_after>/***************************************************************************
 *   Copyright (c) Juergen Riegel          (juergen.riegel@web.de) 2012    *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library 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 Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"

#ifndef _PreComp_
# include <sstream>
# include <QApplication>
# include <Inventor/SoPickedPoint.h>
# include <Inventor/events/SoMouseButtonEvent.h>
# include <Inventor/nodes/SoSeparator.h>
# include <Inventor/nodes/SoBaseColor.h>
# include <Inventor/nodes/SoFontStyle.h>
# include <Inventor/nodes/SoPickStyle.h>
# include <Inventor/nodes/SoText2.h>
# include <Inventor/nodes/SoTranslation.h>
# include <Inventor/nodes/SoCoordinate3.h>
# include <Inventor/nodes/SoIndexedLineSet.h>
# include <Inventor/nodes/SoMarkerSet.h>
# include <Inventor/nodes/SoDrawStyle.h>
#endif

#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoAnnotation.h>
#include <Inventor/details/SoLineDetail.h>
#include <Inventor/nodes/SoAsciiText.h>
#include "ViewProviderPlane.h"
#include "SoFCSelection.h"
#include "Application.h"
#include "Document.h"
#include "View3DInventorViewer.h"
#include "Inventor/SoAutoZoomTranslation.h"
#include "SoAxisCrossKit.h"
//#include <SoDepthBuffer.h>

#include <App/PropertyGeo.h>
#include <App/PropertyStandard.h>
#include <App/MeasureDistance.h>
#include <Base/Console.h>

using namespace Gui;

PROPERTY_SOURCE(Gui::ViewProviderPlane, Gui::ViewProviderGeometryObject)

ViewProviderPlane::ViewProviderPlane()
{

    ADD_PROPERTY(Size,(1.0));

    pMat = new SoMaterial();
    pMat->ref();

    float size = Size.getValue(); // Note: If you change this, you need to also adapt App/Plane.cpp getBoundBox()

    SbVec3f verts[4] =
    {
        SbVec3f(size,size,0), SbVec3f(size,-size,0),
        SbVec3f(-size,-size,0), SbVec3f(-size,size,0),
    };

    // indexes used to create the edges
    static const int32_t lines[6] =
    {
        0,1,2,3,0,-1
    };

    pMat->diffuseColor.setNum(1);
    pMat->diffuseColor.set1Value(0, SbColor(1.0f, 1.0f, 1.0f));

    pCoords = new SoCoordinate3();
    pCoords->ref();
    pCoords->point.setNum(4);
    pCoords->point.setValues(0, 4, verts);

    pLines  = new SoIndexedLineSet();
    pLines->ref();
    pLines->coordIndex.setNum(6);
    pLines->coordIndex.setValues(0, 6, lines);

    pFont = new SoFont();
    pFont->size.setValue(Size.getValue()/10.);

    pTranslation = new SoTranslation();
    pTranslation->translation.setValue(SbVec3f(-1,9./10.,0));

    pText = new SoAsciiText();
    pText->width.setValue(-1);

    sPixmap = "view-measurement";
}

ViewProviderPlane::~ViewProviderPlane()
{
    pCoords->unref();
    pLines->unref();
    pMat->unref();
}

void ViewProviderPlane::onChanged(const App::Property* prop)
{
        if (prop == &Size){
                float size = Size.getValue(); // Note: If you change this, you need to also adapt App/Plane.cpp getBoundBox()

                SbVec3f verts[4] =
                {
                    SbVec3f(size,size,0), SbVec3f(size,-size,0),
                    SbVec3f(-size,-size,0), SbVec3f(-size,size,0),
                };

                pCoords->point.setValues(0, 4, verts);
                pFont->size.setValue(Size.getValue()/10.);
                pTranslation->translation.setValue(SbVec3f(-size,size*9./10.,0));
        }
        else
         ViewProviderGeometryObject::onChanged(prop);
}

std::vector<std::string> ViewProviderPlane::getDisplayModes(void) const
{
    // add modes
    std::vector<std::string> StrList;
    StrList.push_back("Base");
    return StrList;
}

void ViewProviderPlane::setDisplayMode(const char* ModeName)
{
    if (strcmp(ModeName, "Base") == 0)
        setDisplayMaskMode("Base");
    ViewProviderGeometryObject::setDisplayMode(ModeName);
}

void ViewProviderPlane::attach(App::DocumentObject* pcObject)
{
    ViewProviderGeometryObject::attach(pcObject);

    SoSeparator  *sep = new SoSeparator();
    SoAnnotation *lineSep = new SoAnnotation();
    SoFCSelection *highlight = new SoFCSelection();

    SoDrawStyle* style = new SoDrawStyle();
    style->lineWidth = 2.0f;

    SoMaterialBinding* matBinding = new SoMaterialBinding;
    matBinding->value = SoMaterialBinding::OVERALL;

    sep->addChild(matBinding);
    sep->addChild(pMat);
    sep->addChild(highlight);
    highlight->addChild(style);
    highlight->addChild(pCoords);
    highlight->addChild(pLines);

    style = new SoDrawStyle();
    style->lineWidth = 2.0f;
    style->linePattern.setValue(0x00FF);
    lineSep->addChild(style);
    lineSep->addChild(pLines);
    lineSep->addChild(pFont);
    pText->string.setValue(SbString(pcObject->Label.getValue()));
    lineSep->addChild(pTranslation);
    lineSep->addChild(pText);
    highlight->addChild(lineSep);

    highlight->style = SoFCSelection::EMISSIVE_DIFFUSE;
    addDisplayMaskMode(sep, "Base");
}

void ViewProviderPlane::updateData(const App::Property* prop)
{
    pText->string.setValue(SbString(pcObject->Label.getValue()));
    ViewProviderGeometryObject::updateData(prop);
}

std::string ViewProviderPlane::getElement(const SoDetail* detail) const
{
    if (detail) {
        if (detail->getTypeId() == SoLineDetail::getClassTypeId()) {
            const SoLineDetail* line_detail = static_cast<const SoLineDetail*>(detail);
            int edge = line_detail->getLineIndex();
            if (edge == 0)
            {
                return std::string("Main");
            }
        }
    }

    return std::string("");
}

SoDetail* ViewProviderPlane::getDetail(const char* subelement) const
{
    SoLineDetail* detail = 0;
    std::string subelem(subelement);
    int edge = -1;

    if(subelem == "Main") edge = 0;

    if(edge >= 0) {
         detail = new SoLineDetail();
         detail->setPartIndex(edge);
    }

    return detail;
}

bool ViewProviderPlane::isSelectable(void) const
{
    return true;
}
// ----------------------------------------------------------------------------

<|endoftext|>


<commit_before>// Copyright 2020 Google LLC
//
// 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
//
//      https://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 "iree/compiler/Dialect/HAL/Target/LLVM/LLVMAOTTargetLinker.h"

namespace mlir {
namespace iree_compiler {
namespace IREE {
namespace HAL {

iree::StatusOr<std::string> linkLLVMAOTObjects(
    const std::string& linkerToolPath, const std::string& objData) {
  std::string archiveFile, sharedLibFile;
  ASSIGN_OR_RETURN(archiveFile, iree::file_io::GetTempFile("objfile"));
  RETURN_IF_ERROR(iree::file_io::SetFileContents(archiveFile, objData));
  ASSIGN_OR_RETURN(sharedLibFile, iree::file_io::GetTempFile("dylibfile"));
  std::string linkingCmd =
      linkerToolPath + " -shared " + archiveFile + " -o " + sharedLibFile;
  system(linkingCmd.c_str());
  return iree::file_io::GetFileContents(sharedLibFile);
}

iree::StatusOr<std::string> linkLLVMAOTObjectsWithLLDElf(
    const std::string& objData) {
  return iree::UnimplementedErrorBuilder(IREE_LOC)
         << "linkLLVMAOTObjectsWithLLD not implemented yet!";
}

}  // namespace HAL
}  // namespace IREE
}  // namespace iree_compiler
}  // namespace mlir
<commit_msg>Avoid unused result warning (#2469)<commit_after>// Copyright 2020 Google LLC
//
// 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
//
//      https://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 "iree/compiler/Dialect/HAL/Target/LLVM/LLVMAOTTargetLinker.h"

#include "iree/base/status.h"

namespace mlir {
namespace iree_compiler {
namespace IREE {
namespace HAL {

iree::StatusOr<std::string> linkLLVMAOTObjects(
    const std::string& linkerToolPath, const std::string& objData) {
  std::string archiveFile, sharedLibFile;
  ASSIGN_OR_RETURN(archiveFile, iree::file_io::GetTempFile("objfile"));
  RETURN_IF_ERROR(iree::file_io::SetFileContents(archiveFile, objData));
  ASSIGN_OR_RETURN(sharedLibFile, iree::file_io::GetTempFile("dylibfile"));
  std::string linkingCmd =
      linkerToolPath + " -shared " + archiveFile + " -o " + sharedLibFile;
  int systemRet = system(linkingCmd.c_str());
  if (systemRet != 0) {
    return iree::InternalErrorBuilder(IREE_LOC)
           << linkingCmd << " failed with exit code " << systemRet;
  }
  return iree::file_io::GetFileContents(sharedLibFile);
}

iree::StatusOr<std::string> linkLLVMAOTObjectsWithLLDElf(
    const std::string& objData) {
  return iree::UnimplementedErrorBuilder(IREE_LOC)
         << "linkLLVMAOTObjectsWithLLD not implemented yet!";
}

}  // namespace HAL
}  // namespace IREE
}  // namespace iree_compiler
}  // namespace mlir
<|endoftext|>


<commit_before>/*
This file is part of the ORK library.
Full copyright and license terms can be found in the LICENSE.txt file.
*/
#include "ork/ork.hpp"
#include "ork/string_utils.hpp"

#define CATCH_CONFIG_MAIN 1
#include "ork/test/catch_include.hpp"

ORK_GLOBAL_LOG(ORK("../Logs"))

using namespace ork;

TEST_CASE("Strings are encoded", "[string]")
{
    const bstring test_1{BORK("Encode this 1!")};
    const bstring result_1{BORK("RW5jb2RlIHRoaXMgMSE=")};
    REQUIRE(
        encode(
            reinterpret_cast<const unsigned char*>(test_1.data()),
            test_1.size(),
            encoding::base_64) == result_1);
    REQUIRE(decode(result_1, encoding::base_64) == test_1);
}

// We to avoid a second project to generate code
TEST_CASE("Macro Generation", "[pp_meta]")
{
    static const size_t macro_max = 40;
    ORK_FILE_WRITE_B(ORK("generated.cpp"));

    LOOPI(macro_max)
    {
        fout << BORK("#define ORK_GET_ARG_")
             << (i / 10 > 0 ? BORK("") : BORK("0")) << i << BORK("_(");
        LOOPJ(i + 1)
        {
            fout << BORK('A') << j << BORK(", ");
        }
        fout << BORK("...) A") << i << BORK('\n');
    }

    fout << BORK("\n");
    fout << BORK("#define ORK_ARG_N_(");
    LOOPI(macro_max + 1)
    {
        fout << BORK('A') << i + 1 << BORK(", ");
    }
    fout << BORK("...) A") << macro_max + 1 << BORK('\n');

    fout << BORK("\n");
    fout << BORK("#define ORK_DESCENDING_N_ ");
    LOOPRI(macro_max + 1)
    {
        fout << i << (i > 0 ? BORK(", ") : BORK(""));
    }

    const int arg_1 = ORK_NUM_ARG(a);
    REQUIRE(arg_1 == 1);

    const int arg_3 = ORK_NUM_ARG(a, b, c);
    REQUIRE(arg_3 == 3);
}
TEST_CASE("Macro Test", "[pp_meta]")
{
    REQUIRE(ORK_IF_(1)(4, 5) == 4);
    REQUIRE(ORK_IF_(0)(4, 5) == 5);
#define T() 1
#define F() 0
    REQUIRE(ORK_IF_(T())(4, 5) == 4);
    REQUIRE(ORK_IF_(F())(4, 5) == 5);

    REQUIRE(ORK_CHECK_1_() == 0);
    REQUIRE(ORK_CHECK_1_(1) == 0);
    REQUIRE(ORK_CHECK_1_(1, 2) == 2);
    REQUIRE(ORK_CHECK_1_(1, 2, 3) == 2);
#define A1() 1
#define A2() 1, 2
#define A3() 1, 2, 3
    REQUIRE(ORK_CHECK_1_(A1()) == 0);
    REQUIRE(ORK_CHECK_1_(A2()) == 2);
    REQUIRE(ORK_CHECK_1_(A3()) == 2);

    REQUIRE(ORK_CHECK_1_(ORK_APPEND_1_(1)) == 1);
    REQUIRE(ORK_CHECK_1_(ORK_APPEND_1_(1, 2)) == 2);
    REQUIRE(ORK_CHECK_1_(ORK_APPEND_1_(A1())) == 1);
    REQUIRE(ORK_CHECK_1_(ORK_APPEND_1_(A2())) == 2);

    REQUIRE(ORK_IS_PAREN(()) == 1);
    REQUIRE(ORK_IS_PAREN(~) == 0);
#define P() ()
#define NP() ~
    REQUIRE(ORK_IS_PAREN(P()) == 1);
    REQUIRE(ORK_IS_PAREN(NP()) == 0);

    REQUIRE(ORK_NOT(0) == 1);
    REQUIRE(ORK_NOT(1) == 0);
    REQUIRE(ORK_NOT(F()) == 1);
    REQUIRE(ORK_NOT(T()) == 0);

    REQUIRE(ORK_BOOL(0) == 0);
    REQUIRE(ORK_BOOL(1) == 1);
    REQUIRE(ORK_BOOL(a) == 1);
    static const char a = 'a';
    static const char b = 'b';
#define A() a
#define B() b
    REQUIRE(ORK_BOOL(F()) == 0);
    REQUIRE(ORK_BOOL(T()) == 1);
    REQUIRE(ORK_BOOL(A()) == 1);

    REQUIRE(ORK_IF(0)(a, b) == b);
    REQUIRE(ORK_IF(1)(a, b) == a);
    REQUIRE(ORK_IF(a)(a, b) == a);
    REQUIRE(ORK_IF(B())(a, b) == a);

    REQUIRE(1 ORK_WHEN(0)(+1) == 1);
    REQUIRE(1 ORK_WHEN(1)(+1) == 2);

    // clang-format off
#define ORK_SQUARE(A, I) A*A
#define ORK_ADD(A, B, I) A + B
    // clang-format on

    const ork::bstring square_list{ORK_STR(ORK_MAP(ORK_SQUARE, ORK_ADD, 1, 2))};
    REQUIRE(square_list == BORK("1*1 + 2*2"));
    int val = ORK_MAP(ORK_SQUARE, ORK_ADD, 1, 2);
    REQUIRE(val == 5);

    // clang-format off
#define CALL(ARG, I) my--ARG
#define STITCH(X, Y, I) (X + Y)
    // clang-format on
    const ork::bstring assoc_list{ORK_STR(ORK_MAP(CALL, STITCH, a, b, c))};
    REQUIRE(assoc_list == BORK("(my--a + (my--b + my--c))"));
}
<commit_msg>Added increment and decrement macros<commit_after>/*
This file is part of the ORK library.
Full copyright and license terms can be found in the LICENSE.txt file.
*/
#include "ork/ork.hpp"
#include "ork/string_utils.hpp"

#define CATCH_CONFIG_MAIN 1
#include "ork/test/catch_include.hpp"

ORK_GLOBAL_LOG(ORK("../Logs"))

using namespace ork;

TEST_CASE("Strings are encoded", "[string]")
{
    const bstring test_1{BORK("Encode this 1!")};
    const bstring result_1{BORK("RW5jb2RlIHRoaXMgMSE=")};
    REQUIRE(
        encode(
            reinterpret_cast<const unsigned char*>(test_1.data()),
            test_1.size(),
            encoding::base_64) == result_1);
    REQUIRE(decode(result_1, encoding::base_64) == test_1);
}

// We to avoid a second project to generate code
TEST_CASE("Macro Generation", "[pp_meta]")
{
    static const size_t dumb_macro_max = 40;
    ORK_FILE_WRITE_B(ORK("generated.cpp"));

    LOOPI(dumb_macro_max)
    {
        fout << BORK("#define ORK_GET_ARG_")
             << (i / 10 > 0 ? BORK("") : BORK("0")) << i << BORK("_(");
        LOOPJ(i + 1)
        {
            fout << BORK('A') << j << BORK(", ");
        }
        fout << BORK("...) A") << i << BORK('\n');
    }

    fout << BORK("\n");
    fout << BORK("#define ORK_ARG_N_(");
    LOOPI(dumb_macro_max + 1)
    {
        fout << BORK('A') << i + 1 << BORK(", ");
    }
    fout << BORK("...) A") << dumb_macro_max + 1 << BORK('\n');

    fout << BORK("\n");
    fout << BORK("#define ORK_DESCENDING_N_ ");
    LOOPRI(dumb_macro_max + 1)
    {
        fout << i << (i > 0 ? BORK(", ") : BORK(""));
    }

    static const size_t macro_max = 256;

	fout << BORK("\n\n");
    LOOPI(macro_max)
    {
        fout << BORK("#define ORK_INC_") << i << BORK(" ") << i + 1 << BORK('\n');
    }

	fout << BORK("\n");
    LOOPI(macro_max)
    {
        fout << BORK("#define ORK_DEC_") << i + 1 << BORK(" ") << i << BORK('\n');
    }
}
TEST_CASE("Macro Test", "[pp_meta]")
{
    REQUIRE(ORK_IF_(1)(4, 5) == 4);
    REQUIRE(ORK_IF_(0)(4, 5) == 5);
#define T() 1
#define F() 0
    REQUIRE(ORK_IF_(T())(4, 5) == 4);
    REQUIRE(ORK_IF_(F())(4, 5) == 5);

    REQUIRE(ORK_CHECK_1_() == 0);
    REQUIRE(ORK_CHECK_1_(1) == 0);
    REQUIRE(ORK_CHECK_1_(1, 2) == 2);
    REQUIRE(ORK_CHECK_1_(1, 2, 3) == 2);
#define A1() 1
#define A2() 1, 2
#define A3() 1, 2, 3
    REQUIRE(ORK_CHECK_1_(A1()) == 0);
    REQUIRE(ORK_CHECK_1_(A2()) == 2);
    REQUIRE(ORK_CHECK_1_(A3()) == 2);

    REQUIRE(ORK_CHECK_1_(ORK_APPEND_1_(1)) == 1);
    REQUIRE(ORK_CHECK_1_(ORK_APPEND_1_(1, 2)) == 2);
    REQUIRE(ORK_CHECK_1_(ORK_APPEND_1_(A1())) == 1);
    REQUIRE(ORK_CHECK_1_(ORK_APPEND_1_(A2())) == 2);

    REQUIRE(ORK_IS_PAREN(()) == 1);
    REQUIRE(ORK_IS_PAREN(~) == 0);
#define P() ()
#define NP() ~
    REQUIRE(ORK_IS_PAREN(P()) == 1);
    REQUIRE(ORK_IS_PAREN(NP()) == 0);

    REQUIRE(ORK_NOT(0) == 1);
    REQUIRE(ORK_NOT(1) == 0);
    REQUIRE(ORK_NOT(F()) == 1);
    REQUIRE(ORK_NOT(T()) == 0);

    REQUIRE(ORK_BOOL(0) == 0);
    REQUIRE(ORK_BOOL(1) == 1);
    REQUIRE(ORK_BOOL(a) == 1);
    static const char a = 'a';
    static const char b = 'b';
#define A() a
#define B() b
    REQUIRE(ORK_BOOL(F()) == 0);
    REQUIRE(ORK_BOOL(T()) == 1);
    REQUIRE(ORK_BOOL(A()) == 1);

    REQUIRE(ORK_IF(0)(a, b) == b);
    REQUIRE(ORK_IF(1)(a, b) == a);
    REQUIRE(ORK_IF(a)(a, b) == a);
    REQUIRE(ORK_IF(B())(a, b) == a);

    REQUIRE(1 ORK_WHEN(0)(+1) == 1);
    REQUIRE(1 ORK_WHEN(1)(+1) == 2);

    // clang-format off
#define ORK_SQUARE(A, I) A*A
#define ORK_ADD(A, B, I) A + B
    // clang-format on

    const ork::bstring square_list{ORK_STR(ORK_MAP(ORK_SQUARE, ORK_ADD, 1, 2))};
    REQUIRE(square_list == BORK("1*1 + 2*2"));
    int val = ORK_MAP(ORK_SQUARE, ORK_ADD, 1, 2);
    REQUIRE(val == 5);

    // clang-format off
#define CALL(ARG, I) my--ARG
#define STITCH(X, Y, I) (X + Y)
    // clang-format on
    const ork::bstring assoc_list{ORK_STR(ORK_MAP(CALL, STITCH, a, b, c))};
    REQUIRE(assoc_list == BORK("(my--a + (my--b + my--c))"));
}
<|endoftext|>


<commit_before>#include <iostream>

#include <arc_utilities/dijkstras.hpp>
#include <arc_utilities/pretty_print.hpp>

int main(int argc, char* argv[])
{
    (void)argc;
    (void)argv;

    std::cout << "Creating graph with nodes indices:\n\n";
    std::cout << "  2 | 5 | 8\n"
              << "  --+---+--\n"
              << "  1 | 4 | 7\n"
              << "  --+---+--\n"
              << "  0 | 3 | 6\n\n";

    arc_dijkstras::Graph<Eigen::Vector2d> graph(9);
    for (double x = -1; x <= 1; x += 1)
    {
        for (double y = -1; y <= 1; y += 1)
        {
            graph.AddNode(Eigen::Vector2d(x, y));
        }
    }

    // Y-direction edges
    graph.AddEdgesBetweenNodes(0, 1, 1.0);
    graph.AddEdgesBetweenNodes(1, 2, 1.0);
    graph.AddEdgesBetweenNodes(3, 4, 1.0);
    graph.AddEdgesBetweenNodes(4, 5, 1.0);
    graph.AddEdgesBetweenNodes(6, 7, 1.0);
    graph.AddEdgesBetweenNodes(7, 8, 1.0);

    // X-direction edges
    graph.AddEdgesBetweenNodes(0, 3, 1.0);
    graph.AddEdgesBetweenNodes(3, 6, 1.0);
    graph.AddEdgesBetweenNodes(1, 4, 1.0);
    graph.AddEdgesBetweenNodes(4, 7, 1.0);
    graph.AddEdgesBetweenNodes(2, 5, 1.0);
    graph.AddEdgesBetweenNodes(5, 8, 1.0);

    assert(graph.CheckGraphLinkage());

    auto dijkstras_result_4connected = arc_dijkstras::SimpleDijkstrasAlgorithm<Eigen::Vector2d, std::allocator<Eigen::Vector2d>>::PerformDijkstrasAlgorithm(graph, 0);

    std::cout << "4-connected edges\n"
              << "Node index            : 0, 1, 2, 3, 4, 5, 6, 7, 8\n";
    std::cout << "Previous graph indices: " << PrettyPrint::PrettyPrint(dijkstras_result_4connected.second.first) << std::endl;
    std::cout << "Distance              : " << PrettyPrint::PrettyPrint(dijkstras_result_4connected.second.second) << std::endl;

    // Diagonal edges
    graph.AddEdgesBetweenNodes(0, 4, std::sqrt(2));
    graph.AddEdgesBetweenNodes(1, 5, std::sqrt(2));
    graph.AddEdgesBetweenNodes(3, 7, std::sqrt(2));
    graph.AddEdgesBetweenNodes(4, 8, std::sqrt(2));

    graph.AddEdgesBetweenNodes(1, 3, std::sqrt(2));
    graph.AddEdgesBetweenNodes(2, 4, std::sqrt(2));
    graph.AddEdgesBetweenNodes(4, 6, std::sqrt(2));
    graph.AddEdgesBetweenNodes(5, 7, std::sqrt(2));

    assert(graph.CheckGraphLinkage());
    auto dijkstras_result_8connected = arc_dijkstras::SimpleDijkstrasAlgorithm<Eigen::Vector2d, std::allocator<Eigen::Vector2d>>::PerformDijkstrasAlgorithm(graph, 0);

    std::cout << "\n8-connected edges\n"
              << "Node index            : 0, 1, 2, 3, 4, 5, 6, 7, 8\n";
    std::cout << "Previous graph indices: " << PrettyPrint::PrettyPrint(dijkstras_result_8connected.second.first) << std::endl;
    std::cout << "Distance              : " << PrettyPrint::PrettyPrint(dijkstras_result_8connected.second.second) << std::endl;

    std::cout << "Serialization test... ";
    // Define the graph value serialization function
    const auto value_serializer_fn = [] (const Eigen::Vector2d& value, std::vector<uint8_t>& buffer)
    {
//        return 0UL;

        const uint64_t start_buffer_size = buffer.size();
        uint64_t running_total = 0;

        running_total += arc_helpers::SerializeFixedSizePOD<double>(value(0), buffer);
        running_total += arc_helpers::SerializeFixedSizePOD<double>(value(1), buffer);

        const uint64_t end_buffer_size = buffer.size();
        const uint64_t bytes_written = end_buffer_size - start_buffer_size;

        assert(running_total == bytes_written);

        return bytes_written;
    };

    // Define the graph value serialization function
    const auto value_deserializer_fn = [] (const std::vector<uint8_t>& buffer, const int64_t current)
    {
//        return std::make_pair(Eigen::Vector2d(), 0UL);

        uint64_t current_position = current;

        // Deserialze 2 doubles
        std::pair<double, uint64_t> x = arc_helpers::DeserializeFixedSizePOD<double>(buffer, current_position);
        current_position += x.second;
        std::pair<double, uint64_t> y = arc_helpers::DeserializeFixedSizePOD<double>(buffer, current_position);
        current_position += y.second;

        const Eigen::Vector2d deserialized(x.first, y.first);

        // Figure out how many bytes were read
        const uint64_t bytes_read = current_position - current;
        return std::make_pair(deserialized, bytes_read);
    };

    // Serialze the graph
    std::vector<uint8_t> buffer;
    graph.SerializeSelf(buffer, value_serializer_fn);

    auto deserialized_result = arc_dijkstras::Graph<Eigen::Vector2d>::Deserialize(buffer, 0, value_deserializer_fn);
    assert(deserialized_result.first.CheckGraphLinkage());

    std::cout << "passed" << std::endl;

    return 0;
}
<commit_msg>Even simpler graph - 2 nodes, 1 single-directional edge<commit_after>#include <iostream>

#include <arc_utilities/dijkstras.hpp>
#include <arc_utilities/pretty_print.hpp>

int main(int argc, char* argv[])
{
    (void)argc;
    (void)argv;

    std::cout << "Creating graph with nodes indices:\n\n";
    std::cout << "  2 | 5 | 8\n"
              << "  --+---+--\n"
              << "  1 | 4 | 7\n"
              << "  --+---+--\n"
              << "  0 | 3 | 6\n\n";

    arc_dijkstras::Graph<Eigen::Vector2d> graph(9);
    graph.AddNode(Eigen::Vector2d(0,0));
    graph.AddNode(Eigen::Vector2d(1,1));
    for (double x = -1; x <= 1; x += 1)
    {
        for (double y = -1; y <= 1; y += 1)
        {
            graph.AddNode(Eigen::Vector2d(x, y));
        }
    }

    // Y-direction edges
    graph.AddEdgeBetweenNodes(0, 1, 1.0);
    graph.AddEdgesBetweenNodes(1, 2, 1.0);
    graph.AddEdgesBetweenNodes(3, 4, 1.0);
    graph.AddEdgesBetweenNodes(4, 5, 1.0);
    graph.AddEdgesBetweenNodes(6, 7, 1.0);
    graph.AddEdgesBetweenNodes(7, 8, 1.0);

    // X-direction edges
    graph.AddEdgesBetweenNodes(0, 3, 1.0);
    graph.AddEdgesBetweenNodes(3, 6, 1.0);
    graph.AddEdgesBetweenNodes(1, 4, 1.0);
    graph.AddEdgesBetweenNodes(4, 7, 1.0);
    graph.AddEdgesBetweenNodes(2, 5, 1.0);
    graph.AddEdgesBetweenNodes(5, 8, 1.0);

    assert(graph.CheckGraphLinkage());

    auto dijkstras_result_4connected = arc_dijkstras::SimpleDijkstrasAlgorithm<Eigen::Vector2d, std::allocator<Eigen::Vector2d>>::PerformDijkstrasAlgorithm(graph, 0);

    std::cout << "4-connected edges\n"
              << "Node index            : 0, 1, 2, 3, 4, 5, 6, 7, 8\n";
    std::cout << "Previous graph indices: " << PrettyPrint::PrettyPrint(dijkstras_result_4connected.second.first) << std::endl;
    std::cout << "Distance              : " << PrettyPrint::PrettyPrint(dijkstras_result_4connected.second.second) << std::endl;

    // Diagonal edges
    graph.AddEdgesBetweenNodes(0, 4, std::sqrt(2));
    graph.AddEdgesBetweenNodes(1, 5, std::sqrt(2));
    graph.AddEdgesBetweenNodes(3, 7, std::sqrt(2));
    graph.AddEdgesBetweenNodes(4, 8, std::sqrt(2));

    graph.AddEdgesBetweenNodes(1, 3, std::sqrt(2));
    graph.AddEdgesBetweenNodes(2, 4, std::sqrt(2));
    graph.AddEdgesBetweenNodes(4, 6, std::sqrt(2));
    graph.AddEdgesBetweenNodes(5, 7, std::sqrt(2));

    assert(graph.CheckGraphLinkage());
    auto dijkstras_result_8connected = arc_dijkstras::SimpleDijkstrasAlgorithm<Eigen::Vector2d, std::allocator<Eigen::Vector2d>>::PerformDijkstrasAlgorithm(graph, 0);

    std::cout << "\n8-connected edges\n"
              << "Node index            : 0, 1, 2, 3, 4, 5, 6, 7, 8\n";
    std::cout << "Previous graph indices: " << PrettyPrint::PrettyPrint(dijkstras_result_8connected.second.first) << std::endl;
    std::cout << "Distance              : " << PrettyPrint::PrettyPrint(dijkstras_result_8connected.second.second) << std::endl;

    std::cout << "Serialization test... ";

    arc_dijkstras::Graph<Eigen::Vector2d> serialization_test_graph(2);
    serialization_test_graph.AddNode(Eigen::Vector2d(0,0));
    serialization_test_graph.AddNode(Eigen::Vector2d(1,1));
    serialization_test_graph.AddEdgesBetweenNodes(0, 1, 1.0);

    // Define the graph value serialization function
    const auto value_serializer_fn = [] (const Eigen::Vector2d& value, std::vector<uint8_t>& buffer)
    {
//        return 0UL;

        const uint64_t start_buffer_size = buffer.size();
        uint64_t running_total = 0;

        running_total += arc_helpers::SerializeFixedSizePOD<double>(value(0), buffer);
        running_total += arc_helpers::SerializeFixedSizePOD<double>(value(1), buffer);

        const uint64_t end_buffer_size = buffer.size();
        const uint64_t bytes_written = end_buffer_size - start_buffer_size;

        assert(running_total == bytes_written);

        return bytes_written;
    };

    // Define the graph value serialization function
    const auto value_deserializer_fn = [] (const std::vector<uint8_t>& buffer, const int64_t current)
    {
//        return std::make_pair(Eigen::Vector2d(), 0UL);

        uint64_t current_position = current;

        // Deserialze 2 doubles
        std::pair<double, uint64_t> x = arc_helpers::DeserializeFixedSizePOD<double>(buffer, current_position);
        current_position += x.second;
        std::pair<double, uint64_t> y = arc_helpers::DeserializeFixedSizePOD<double>(buffer, current_position);
        current_position += y.second;

        const Eigen::Vector2d deserialized(x.first, y.first);

        // Figure out how many bytes were read
        const uint64_t bytes_read = current_position - current;
        return std::make_pair(deserialized, bytes_read);
    };

    // Serialze the graph
    std::vector<uint8_t> buffer;
    serialization_test_graph.SerializeSelf(buffer, value_serializer_fn);

    auto deserialized_result = arc_dijkstras::Graph<Eigen::Vector2d>::Deserialize(buffer, 0, value_deserializer_fn);
    assert(deserialized_result.first.CheckGraphLinkage());

    std::cout << "passed" << std::endl;

    return 0;
}
<|endoftext|>


<commit_before>/*
 *
 * AESCipher
 * ledger-core
 *
 * Created by Pierre Pollastri on 08/12/2016.
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2016 Ledger
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */
#include "AESCipher.hpp"
#include "PBKDF2.hpp"
#include "AES256.hpp"

namespace ledger {
    namespace core {
        AESCipher::AESCipher(const std::shared_ptr<api::RandomNumberGenerator> &rng, const std::string &password,
                             const std::string &salt, uint32_t iter) {
            _rng = rng;
            _key = PBKDF2::derive(
                    std::vector<uint8_t>(password.data(), password.data() + password.size()),
                    std::vector<uint8_t>(salt.data(), salt.data() + salt.size())
                    , iter, 32);
        }

        void AESCipher::encrypt(std::istream *input, std::ostream *output) {
#if defined(_WIN32) || defined(_WIN64)
#else
            input->seekg(0, input->beg);
            uint32_t maxRead = 254 * AES256::BLOCK_SIZE;
            uint8_t buffer[maxRead];
            do {
                // Read 254 * AES_BLOCK_SIZE bytes (we want at most 0xFF blocks to encrypt we the same IV)
                input->read((char *)buffer, maxRead);
                uint32_t read = input->gcount();

                // Create an IVt
                auto IV = _rng->getRandomBytes(AES256::BLOCK_SIZE);
                // Encrypt
                auto encrypted = AES256::encrypt(IV, _key, std::vector<uint8_t>(buffer, buffer + read));
                // Store number of blocks
                uint8_t blocksCount = (encrypted.size() / AES256::BLOCK_SIZE);
                (*output) << blocksCount;
                (*output) << read;
                // Store IV
                output->write((char *)IV.data(), IV.size());
                // Store encrypted data
                output->write((char *)encrypted.data(), encrypted.size());
            } while (!input->eof());
#endif
        }

        void AESCipher::decrypt(std::istream *input, std::ostream *output) {
#if defined(_WIN32) || defined(_WIN64)
#else
            input->seekg(0, input->beg);
            uint32_t maxRead = 255 * AES256::BLOCK_SIZE;
            uint8_t buffer[maxRead];
            do {
                uint8_t blocksCount;
                uint32_t dataSize;
                (*input) >> blocksCount;
                (*input) >> dataSize;

                std::vector<uint8_t> IV;
                IV.resize(AES256::BLOCK_SIZE);
                input->read((char *)IV.data(), IV.size());
                input->read((char *)buffer, blocksCount * AES256::BLOCK_SIZE);
                if (input->gcount() < blocksCount * AES256::BLOCK_SIZE)
                    break;
                auto decrypted = AES256::decrypt(IV, _key, std::vector<uint8_t>(buffer, buffer + (blocksCount * AES256::BLOCK_SIZE)));
                output->write((char *)decrypted.data(), dataSize);
            } while (!input->eof());
#endif
        }

        void AESCipher::encrypt(BytesReader& input, BytesWriter& output) {
            uint32_t maxRead = 254 * AES256::BLOCK_SIZE;
            do {
                // Read 254 * AES_BLOCK_SIZE bytes (we want at most 0xFF blocks to encrypt we the same IV)
                uint32_t available = input.available();
                uint32_t minEncryptedRead = std::min(maxRead,available);
                std::vector<uint8_t> dataToEncrypt = input.read(minEncryptedRead);
                uint32_t read = dataToEncrypt.size();
                // Create an IVt
                auto IV = _rng->getRandomBytes(AES256::BLOCK_SIZE);
                // Encrypt
                auto encrypted = AES256::encrypt(IV, _key, dataToEncrypt);
                // Store number of blocks
                uint8_t blocksCount = (encrypted.size() / AES256::BLOCK_SIZE);
                //Number of blocks of size AES256::BLOCK_SIZE in enrypted data
                output.writeByte(blocksCount);
                //Limit of reading (padding or string terminating before maxRead)
                output.writeVarInt(read);
                // Store IV
                output.writeByteArray(IV);
                // Store encrypted data
                output.writeByteArray(encrypted);
            } while (input.hasNext());
        }

        void AESCipher::decrypt(BytesReader& input, BytesWriter& output) {
            uint32_t maxRead = 255 * AES256::BLOCK_SIZE;
            do {
                //Get number of blocks in encrypted data
                uint8_t blocksCount = input.readNextByte();
                //Size of encrypted (chunk of) data
                uint32_t encryptedDataSize = blocksCount*AES256::BLOCK_SIZE;
                //Get data that we read
                uint32_t dataSize = input.readNextVarInt();
                //Read IV
                std::vector<uint8_t> IV = input.read(AES256::BLOCK_SIZE);
                //Get number of bytes to read
                uint32_t available = input.available();
                if(available < encryptedDataSize) {
                    //Should not read than more available data
                    break;
                }
                //Read encrypted data
                std::vector<uint8_t> encryptedData = input.read(encryptedDataSize);
                //Decrypt
                auto decrypted = AES256::decrypt(IV, _key, encryptedData);
                //Truncate if needed to size of encrypted data that we stored in dataSize bytes
                if(dataSize <  decrypted.size()){
                    decrypted.resize(dataSize);
                }
                //Store decrypted data
                output.writeByteArray(decrypted);
            } while (input.hasNext());
        }
    }
}
<commit_msg>Add an assert in the AESCipher to ensure IV is never null.<commit_after>/*
 *
 * AESCipher
 * ledger-core
 *
 * Created by Pierre Pollastri on 08/12/2016.
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2016 Ledger
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

#include "AESCipher.hpp"
#include "PBKDF2.hpp"
#include "AES256.hpp"

namespace ledger {
    namespace core {
        AESCipher::AESCipher(const std::shared_ptr<api::RandomNumberGenerator> &rng, const std::string &password,
                             const std::string &salt, uint32_t iter) {
            _rng = rng;
            _key = PBKDF2::derive(
                    std::vector<uint8_t>(password.data(), password.data() + password.size()),
                    std::vector<uint8_t>(salt.data(), salt.data() + salt.size())
                    , iter, 32);
        }

        void AESCipher::encrypt(std::istream *input, std::ostream *output) {
#if defined(_WIN32) || defined(_WIN64)
#else
            input->seekg(0, input->beg);
            uint32_t maxRead = 254 * AES256::BLOCK_SIZE;
            uint8_t buffer[maxRead];
            do {
                // Read 254 * AES_BLOCK_SIZE bytes (we want at most 0xFF blocks to encrypt we the same IV)
                input->read((char *)buffer, maxRead);
                uint32_t read = input->gcount();

                // Create an IVt
                auto IV = _rng->getRandomBytes(AES256::BLOCK_SIZE);
                assert(IV.size() == AES256::BLOCK_SIZE);

                // Encrypt
                auto encrypted = AES256::encrypt(IV, _key, std::vector<uint8_t>(buffer, buffer + read));
                // Store number of blocks
                uint8_t blocksCount = (encrypted.size() / AES256::BLOCK_SIZE);
                (*output) << blocksCount;
                (*output) << read;
                // Store IV
                output->write((char *)IV.data(), IV.size());
                // Store encrypted data
                output->write((char *)encrypted.data(), encrypted.size());
            } while (!input->eof());
#endif
        }

        void AESCipher::decrypt(std::istream *input, std::ostream *output) {
#if defined(_WIN32) || defined(_WIN64)
#else
            input->seekg(0, input->beg);
            uint32_t maxRead = 255 * AES256::BLOCK_SIZE;
            uint8_t buffer[maxRead];
            do {
                uint8_t blocksCount;
                uint32_t dataSize;
                (*input) >> blocksCount;
                (*input) >> dataSize;

                std::vector<uint8_t> IV;
                IV.resize(AES256::BLOCK_SIZE);
                input->read((char *)IV.data(), IV.size());
                input->read((char *)buffer, blocksCount * AES256::BLOCK_SIZE);
                if (input->gcount() < blocksCount * AES256::BLOCK_SIZE)
                    break;
                auto decrypted = AES256::decrypt(IV, _key, std::vector<uint8_t>(buffer, buffer + (blocksCount * AES256::BLOCK_SIZE)));
                output->write((char *)decrypted.data(), dataSize);
            } while (!input->eof());
#endif
        }

        void AESCipher::encrypt(BytesReader& input, BytesWriter& output) {
            uint32_t maxRead = 254 * AES256::BLOCK_SIZE;
            do {
                // Read 254 * AES_BLOCK_SIZE bytes (we want at most 0xFF blocks to encrypt we the same IV)
                uint32_t available = input.available();
                uint32_t minEncryptedRead = std::min(maxRead,available);
                std::vector<uint8_t> dataToEncrypt = input.read(minEncryptedRead);
                uint32_t read = dataToEncrypt.size();
                // Create an IVt
                auto IV = _rng->getRandomBytes(AES256::BLOCK_SIZE);
                // Encrypt
                auto encrypted = AES256::encrypt(IV, _key, dataToEncrypt);
                // Store number of blocks
                uint8_t blocksCount = (encrypted.size() / AES256::BLOCK_SIZE);
                //Number of blocks of size AES256::BLOCK_SIZE in enrypted data
                output.writeByte(blocksCount);
                //Limit of reading (padding or string terminating before maxRead)
                output.writeVarInt(read);
                // Store IV
                output.writeByteArray(IV);
                // Store encrypted data
                output.writeByteArray(encrypted);
            } while (input.hasNext());
        }

        void AESCipher::decrypt(BytesReader& input, BytesWriter& output) {
            uint32_t maxRead = 255 * AES256::BLOCK_SIZE;
            do {
                //Get number of blocks in encrypted data
                uint8_t blocksCount = input.readNextByte();
                //Size of encrypted (chunk of) data
                uint32_t encryptedDataSize = blocksCount*AES256::BLOCK_SIZE;
                //Get data that we read
                uint32_t dataSize = input.readNextVarInt();
                //Read IV
                std::vector<uint8_t> IV = input.read(AES256::BLOCK_SIZE);
                //Get number of bytes to read
                uint32_t available = input.available();
                if(available < encryptedDataSize) {
                    //Should not read than more available data
                    break;
                }
                //Read encrypted data
                std::vector<uint8_t> encryptedData = input.read(encryptedDataSize);
                //Decrypt
                auto decrypted = AES256::decrypt(IV, _key, encryptedData);
                //Truncate if needed to size of encrypted data that we stored in dataSize bytes
                if(dataSize <  decrypted.size()){
                    decrypted.resize(dataSize);
                }
                //Store decrypted data
                output.writeByteArray(decrypted);
            } while (input.hasNext());
        }
    }
}
<|endoftext|>