<commit_before>/* This file is part of Strigi Desktop Search
 *
 * Copyright (C) 2006 Flavio Castelli <flavio.castelli@gmail.com>
 *
 * 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., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
*/
#include <stdio.h>

#include "eventlistenerqueue.h"
#include "event.h"
#include "strigi_thread.h"
#include "strigilogging.h"

#include <algorithm>
#include <iostream>

using namespace std;

EventListenerQueue::EventListenerQueue(const char* name)
    : StrigiThread (name)
{
    STRIGI_MUTEX_INIT (&m_mutex);
    m_toProcessOldCount = 0;
    m_processedOldCount = 0;
    m_waitingOldCount = 0;
}

EventListenerQueue::~EventListenerQueue()
{
    clear();

    STRIGI_MUTEX_DESTROY (&m_mutex);
}

void EventListenerQueue::clearEvents( map<string, Event*>& events)
{
    map < string, Event*>:: iterator iter;

    for (iter = events.begin(); iter != events.end(); iter++)
    {
        delete iter->second;
    }

    events.clear();
}

void EventListenerQueue::clear()
{
    STRIGI_MUTEX_LOCK (&m_mutex);

    clearEvents (m_toProcess);
    clearEvents (m_processed);
    clearEvents (m_waiting);

    STRIGI_MUTEX_UNLOCK (&m_mutex);
}

void* EventListenerQueue::run(void*)
{
    while (getState() != Stopping)
    {
        sleep (5);
        if (STRIGI_MUTEX_TRY_LOCK(&m_mutex) == 0)
        {

            if (m_waiting.size() > 0)
            {
                // search all wainting events that can be promoted to
                // "toProcess" status

                map<string,Event*>::iterator iter = m_waiting.begin();

                time_t now;
                time (&now);
                double delta = 60;

                while (iter != m_waiting.end())
                {
                    if (checkElapsedTime(iter->second, now, delta))
                    {
                        m_toProcess.insert(make_pair(iter->first,iter->second));
                        map<string,Event*>::iterator itRm = iter;
                        iter++;
                        m_waiting.erase(itRm);
                    }
                    else
                        iter++;
                }
            }

            if (m_processed.size() > 0)
                purgeProcessedEvents();

            // print stats
            char buff [50];

            if (m_processed.size() != m_processedOldCount) {
                snprintf (buff, 50*sizeof(char), "%lu", (unsigned long)m_processed.size());
                STRIGI_LOG_DEBUG ("strigi.EventListenerQueue.run",
                            string(buff) + " events in \"processed\" queue");
                m_processedOldCount = m_processed.size();
            }

            if (m_toProcess.size() != m_toProcessOldCount) {
                snprintf (buff, 50*sizeof(char), "%lu", (unsigned long)m_toProcess.size());
                STRIGI_LOG_DEBUG ("strigi.EventListenerQueue.run",
                            string(buff) + " events in \"to process\" queue");
                m_toProcessOldCount = m_toProcess.size();
            }

            if (m_waiting.size() != m_waitingOldCount) {
                snprintf (buff, 50*sizeof(char), "%lu", (unsigned long)m_waiting.size());
                STRIGI_LOG_DEBUG ("strigi.EventListenerQueue.run",
                                string(buff) + " events in \"waiting\" queue");
                m_waitingOldCount = m_waiting.size();
            }

            STRIGI_MUTEX_UNLOCK (&m_mutex);
        }

        if (getState() == Working)
            setState(Idling);
    }

    STRIGI_LOG_DEBUG ("strigi.EventListenerQueue.run",
                       string("exit state: ") + getStringState());
    return 0;
}

bool EventListenerQueue::checkElapsedTime (Event* event,time_t now,double delta)
{
    double diff = difftime (now, event->getTime());

    if (diff > delta)
        return true;

    return false;
}

void EventListenerQueue::purgeProcessedEvents()
{
    unsigned int counter = 0;
    time_t now;
    time (&now);

    double delta = 120;

    map <string, Event*>::iterator iter = m_processed.begin();

    while (iter != m_processed.end())
    {
        if (checkElapsedTime(iter->second, now, delta))
        {
            map <string, Event*>::iterator itRm = iter;
            iter++;

            // we remove this event forever, free-up some memory
            delete itRm->second;
            itRm->second = NULL;
            m_processed.erase (itRm);
            counter++;
        }
        else
            iter++;
    }

    if (counter > 0)
    {
        char buff [50];
        snprintf (buff, 50*sizeof (char), "%i", counter);

        STRIGI_LOG_DEBUG ("strigi.EventListenerQueue.purgeProcessedEvents",
                        string(buff) + " has been removed from processed " +
                        "events queue");
    }
}

Event* EventListenerQueue::searchInProcessed(Event* event)
{
    if (event == NULL)
        return NULL;

    map<string, Event*>::iterator iter;
    iter = m_processed.find(event->getPath());

    if (iter == m_processed.end())
        return NULL;
    else
        return iter->second;
}

Event* EventListenerQueue::searchInWaiting (Event* event)
{
    map<string, Event*>::iterator iter;
    iter = m_waiting.find(event->getPath());

    if (iter == m_waiting.end())
        return NULL;
    else
        return iter->second;
}

Event* EventListenerQueue::searchInToProcess (Event* event)
{
    map<string, Event*>::iterator iter;
    iter = m_toProcess.find(event->getPath());

    if (iter == m_toProcess.end())
        return NULL;
    else
        return iter->second;
}

void EventListenerQueue::putInWaiting (Event* event)
{
    Event* waitingEvent = searchInWaiting(event);

    if (waitingEvent)
    {
        // there's already an event regarding this file/dir
        // let's update the event type
        updateEventType(waitingEvent, event, m_waiting);

        // we don't need event anymore, free-up some memory
        delete event;
        event = NULL;

        STRIGI_LOG_DEBUG ("strigi.EventListenerQueue.addEvents",
                          "updated waiting event status");
    }
    else
    {
        // add the new event to the wainting queue
        m_waiting.insert (make_pair(event->getPath(), event));
        STRIGI_LOG_DEBUG ("strigi.EventListenerQueue.putInWaiting",
                          "new event added to waiting queue");
    }
}

void EventListenerQueue::putInProcessed (Event* event)
{
    Event* processedEvent = searchInProcessed(event);

    if (processedEvent)
    {
        // there's already an event regarding this file/dir
        // let's update this one
        processedEvent->setType(event->getType());
        processedEvent->setTime(event->getTime());

        // we don't need event anymore, free-up some memory
        delete event;
        event = NULL;

        STRIGI_LOG_DEBUG ("strigi.EventListenerQueue.putInProcessed",
                          "updated processed event");
    }
    else
    {
        // add the new event to the wainting queue
        m_processed.insert (make_pair(event->getPath(), event));
        STRIGI_LOG_DEBUG ("strigi.EventListenerQueue.putInProcessed",
                          "new event added to processed queue");
    }
}

void EventListenerQueue::updateEventType (Event* oldEvent, Event* newEvent,
                                          map <string, Event*>& eventMap)
{
    // simplification table
    // old event | new event |   result
    //     C     |     C     | IMPOSSIBLE
    //     C     |     U     |     C
    //     C     |     D     |   REMOVE
    //     U     |     U     |     U
    //     U     |     C     | IMPOSSIBLE
    //     U     |     D     |     D
    //     D     |     D     | IMPOSSIBLE
    //     D     |     U     | IMPOSSIBLE
    //     D     |     C     |     U

    switch (oldEvent->getType())
    {
        case Event::CREATED:
        {
            switch (newEvent->getType())
            {
                case Event::CREATED:
                    STRIGI_LOG_INFO("strigi.EventListenerQueue.updateEventType",
                                    "Maybe we've lost some filesystem event");

                    // put in update state, it's the safer solution because with
                    // update event we make a delete and a create
                    oldEvent->setType( Event::UPDATED);
                    break;
                case Event::UPDATED:
                    STRIGI_LOG_ERROR("strigi.EventListenerQueue.updateEventType",
                                     "CREATED --> UPDATED = leave CREATED");
                    // leave CREATED state
                    break;
                case Event::DELETED:
                    // remove the old event, the new one makes it useless
                    eventMap.erase(oldEvent->getPath());

                    // deallocate event
                    delete oldEvent;
                    oldEvent = NULL;
                    break;
            }
            break;
        }
        case Event::UPDATED:
        {
            switch (newEvent->getType())
            {
                case Event::CREATED:
                    STRIGI_LOG_INFO("strigi.EventListenerQueue.updateEventType",
                                    "Maybe we've lost some filesystem event");
                    // leave UPDATED state, it's the safer solution because with
                    // update event we make a delete and a create
                    break;
                case Event::UPDATED:
                    // leave UPDATED state
                    STRIGI_LOG_ERROR("strigi.EventListenerQueue.updateEventType",
                                     "UPDATED --> UPDATED = leave UPDATED");

                    break;
                case Event::DELETED:
                    oldEvent->setType( Event::DELETED);
                    STRIGI_LOG_ERROR("strigi.EventListenerQueue.updateEventType",
                                     "UPDATED --> DELETED = DELETED");
                    break;
            }
            break;
        }
        case Event::DELETED:
        {
            switch (newEvent->getType())
            {
                case Event::CREATED:
                    oldEvent->setType( Event::UPDATED);
                    STRIGI_LOG_ERROR("strigi.EventListenerQueue.updateEventType",
                                     "DELETED --> CREATED = UPDATED");
                    break;
                case Event::UPDATED:
                    STRIGI_LOG_INFO("strigi.EventListenerQueue.updateEventType",
                                     "Maybe we've lost some filesystem event");

                    // put in update state, it's the safer solution because with
                    // update event we make a delete and a create
                    oldEvent->setType( Event::UPDATED);
                    break;
                case Event::DELETED:
                    STRIGI_LOG_INFO("strigi.EventListenerQueue.updateEventType",
                                    "Maybe we've lost some filesystem event");
                    //leave DELETED state
                    break;
            }
            break;
        }
    }
}

void EventListenerQueue::addEvents (vector<Event*> events)
{
    vector<Event*>::iterator iter;

    STRIGI_MUTEX_LOCK (&m_mutex);

    Event* event = NULL;

    for (iter = events.begin(); iter != events.end(); iter++)
    {
        event = searchInProcessed(*iter);
        if (event)
        {
            // not to much time ago we have processed an event regarding
            // the same file/dir, we've to wait a little before processing this
            // new event
            putInWaiting (*iter);
            continue;
        }

        event = searchInWaiting(*iter);
        if (event)
        {
            // there's another event in the wainting queue that is related with
            // this file/dir. Let's update its status
            updateEventType (event, *iter, m_waiting);

            // we don't need this new event anymore, free-up some memory
            delete *iter;
            *iter = NULL;

            continue;
        }

        event = searchInToProcess(*iter);
        if (event)
        {
            updateEventType (event, *iter, m_toProcess);

            // we don't need this new event anymore, free-up some memory
            delete *iter;
            *iter = NULL;

            continue;
        }
        else
        {
            Event* e = *iter;
            string temp;

            // if we're arrived here this new event has to be processed
            m_toProcess.insert (make_pair (e->getPath(), e));
            STRIGI_LOG_DEBUG ("strigi.EventListenerQueue.addEvents",
                              string("event regarding ") + e->getPath() +
                                      " has been put in toProcess queue");
        }
    }

    STRIGI_MUTEX_UNLOCK (&m_mutex);
}

unsigned int EventListenerQueue::size()
{
    unsigned int i = 0;

    if (STRIGI_MUTEX_TRY_LOCK (&m_mutex) == 0)
    {
        i = m_toProcess.size();
        STRIGI_MUTEX_UNLOCK (&m_mutex);
    }

    return i;
}

vector <Event*> EventListenerQueue::getEvents()
{
    vector <Event*> result;

    if (STRIGI_MUTEX_TRY_LOCK (&m_mutex))
    {
        for (map<string, Event*>::iterator iter = m_toProcess.begin();
             iter != m_toProcess.end(); iter++)
        {
            result.push_back (new Event (iter->second));

            // move event to processed queue
            putInProcessed (iter->second);
        }

        m_toProcess.clear();

        STRIGI_MUTEX_UNLOCK (&m_mutex);
    }

    return result;
}
<commit_msg>fix testing for success of the call to STRIGI_MUTEX_TRY_LOCK. It return 0 on success.<commit_after>/* This file is part of Strigi Desktop Search
 *
 * Copyright (C) 2006 Flavio Castelli <flavio.castelli@gmail.com>
 *
 * 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., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
*/
#include <stdio.h>

#include "eventlistenerqueue.h"
#include "event.h"
#include "strigi_thread.h"
#include "strigilogging.h"

#include <algorithm>
#include <iostream>

using namespace std;

EventListenerQueue::EventListenerQueue(const char* name)
    : StrigiThread (name)
{
    STRIGI_MUTEX_INIT (&m_mutex);
    m_toProcessOldCount = 0;
    m_processedOldCount = 0;
    m_waitingOldCount = 0;
}

EventListenerQueue::~EventListenerQueue()
{
    clear();

    STRIGI_MUTEX_DESTROY (&m_mutex);
}

void EventListenerQueue::clearEvents( map<string, Event*>& events)
{
    map < string, Event*>:: iterator iter;

    for (iter = events.begin(); iter != events.end(); iter++)
    {
        delete iter->second;
    }

    events.clear();
}

void EventListenerQueue::clear()
{
    STRIGI_MUTEX_LOCK (&m_mutex);

    clearEvents (m_toProcess);
    clearEvents (m_processed);
    clearEvents (m_waiting);

    STRIGI_MUTEX_UNLOCK (&m_mutex);
}

void* EventListenerQueue::run(void*)
{
    while (getState() != Stopping)
    {
        sleep (5);
        if (STRIGI_MUTEX_TRY_LOCK(&m_mutex) == 0)
        {

            if (m_waiting.size() > 0)
            {
                // search all wainting events that can be promoted to
                // "toProcess" status

                map<string,Event*>::iterator iter = m_waiting.begin();

                time_t now;
                time (&now);
                double delta = 60;

                while (iter != m_waiting.end())
                {
                    if (checkElapsedTime(iter->second, now, delta))
                    {
                        m_toProcess.insert(make_pair(iter->first,iter->second));
                        map<string,Event*>::iterator itRm = iter;
                        iter++;
                        m_waiting.erase(itRm);
                    }
                    else
                        iter++;
                }
            }

            if (m_processed.size() > 0)
                purgeProcessedEvents();

            // print stats
            char buff [50];

            if (m_processed.size() != m_processedOldCount) {
                snprintf (buff, 50*sizeof(char), "%lu", (unsigned long)m_processed.size());
                STRIGI_LOG_DEBUG ("strigi.EventListenerQueue.run",
                            string(buff) + " events in \"processed\" queue");
                m_processedOldCount = m_processed.size();
            }

            if (m_toProcess.size() != m_toProcessOldCount) {
                snprintf (buff, 50*sizeof(char), "%lu", (unsigned long)m_toProcess.size());
                STRIGI_LOG_DEBUG ("strigi.EventListenerQueue.run",
                            string(buff) + " events in \"to process\" queue");
                m_toProcessOldCount = m_toProcess.size();
            }

            if (m_waiting.size() != m_waitingOldCount) {
                snprintf (buff, 50*sizeof(char), "%lu", (unsigned long)m_waiting.size());
                STRIGI_LOG_DEBUG ("strigi.EventListenerQueue.run",
                                string(buff) + " events in \"waiting\" queue");
                m_waitingOldCount = m_waiting.size();
            }

            STRIGI_MUTEX_UNLOCK (&m_mutex);
        }

        if (getState() == Working)
            setState(Idling);
    }

    STRIGI_LOG_DEBUG ("strigi.EventListenerQueue.run",
                       string("exit state: ") + getStringState());
    return 0;
}

bool EventListenerQueue::checkElapsedTime (Event* event,time_t now,double delta)
{
    double diff = difftime (now, event->getTime());

    if (diff > delta)
        return true;

    return false;
}

void EventListenerQueue::purgeProcessedEvents()
{
    unsigned int counter = 0;
    time_t now;
    time (&now);

    double delta = 120;

    map <string, Event*>::iterator iter = m_processed.begin();

    while (iter != m_processed.end())
    {
        if (checkElapsedTime(iter->second, now, delta))
        {
            map <string, Event*>::iterator itRm = iter;
            iter++;

            // we remove this event forever, free-up some memory
            delete itRm->second;
            itRm->second = NULL;
            m_processed.erase (itRm);
            counter++;
        }
        else
            iter++;
    }

    if (counter > 0)
    {
        char buff [50];
        snprintf (buff, 50*sizeof (char), "%i", counter);

        STRIGI_LOG_DEBUG ("strigi.EventListenerQueue.purgeProcessedEvents",
                        string(buff) + " has been removed from processed " +
                        "events queue");
    }
}

Event* EventListenerQueue::searchInProcessed(Event* event)
{
    if (event == NULL)
        return NULL;

    map<string, Event*>::iterator iter;
    iter = m_processed.find(event->getPath());

    if (iter == m_processed.end())
        return NULL;
    else
        return iter->second;
}

Event* EventListenerQueue::searchInWaiting (Event* event)
{
    map<string, Event*>::iterator iter;
    iter = m_waiting.find(event->getPath());

    if (iter == m_waiting.end())
        return NULL;
    else
        return iter->second;
}

Event* EventListenerQueue::searchInToProcess (Event* event)
{
    map<string, Event*>::iterator iter;
    iter = m_toProcess.find(event->getPath());

    if (iter == m_toProcess.end())
        return NULL;
    else
        return iter->second;
}

void EventListenerQueue::putInWaiting (Event* event)
{
    Event* waitingEvent = searchInWaiting(event);

    if (waitingEvent)
    {
        // there's already an event regarding this file/dir
        // let's update the event type
        updateEventType(waitingEvent, event, m_waiting);

        // we don't need event anymore, free-up some memory
        delete event;
        event = NULL;

        STRIGI_LOG_DEBUG ("strigi.EventListenerQueue.addEvents",
                          "updated waiting event status");
    }
    else
    {
        // add the new event to the wainting queue
        m_waiting.insert (make_pair(event->getPath(), event));
        STRIGI_LOG_DEBUG ("strigi.EventListenerQueue.putInWaiting",
                          "new event added to waiting queue");
    }
}

void EventListenerQueue::putInProcessed (Event* event)
{
    Event* processedEvent = searchInProcessed(event);

    if (processedEvent)
    {
        // there's already an event regarding this file/dir
        // let's update this one
        processedEvent->setType(event->getType());
        processedEvent->setTime(event->getTime());

        // we don't need event anymore, free-up some memory
        delete event;
        event = NULL;

        STRIGI_LOG_DEBUG ("strigi.EventListenerQueue.putInProcessed",
                          "updated processed event");
    }
    else
    {
        // add the new event to the wainting queue
        m_processed.insert (make_pair(event->getPath(), event));
        STRIGI_LOG_DEBUG ("strigi.EventListenerQueue.putInProcessed",
                          "new event added to processed queue");
    }
}

void EventListenerQueue::updateEventType (Event* oldEvent, Event* newEvent,
                                          map <string, Event*>& eventMap)
{
    // simplification table
    // old event | new event |   result
    //     C     |     C     | IMPOSSIBLE
    //     C     |     U     |     C
    //     C     |     D     |   REMOVE
    //     U     |     U     |     U
    //     U     |     C     | IMPOSSIBLE
    //     U     |     D     |     D
    //     D     |     D     | IMPOSSIBLE
    //     D     |     U     | IMPOSSIBLE
    //     D     |     C     |     U

    switch (oldEvent->getType())
    {
        case Event::CREATED:
        {
            switch (newEvent->getType())
            {
                case Event::CREATED:
                    STRIGI_LOG_INFO("strigi.EventListenerQueue.updateEventType",
                                    "Maybe we've lost some filesystem event");

                    // put in update state, it's the safer solution because with
                    // update event we make a delete and a create
                    oldEvent->setType( Event::UPDATED);
                    break;
                case Event::UPDATED:
                    STRIGI_LOG_ERROR("strigi.EventListenerQueue.updateEventType",
                                     "CREATED --> UPDATED = leave CREATED");
                    // leave CREATED state
                    break;
                case Event::DELETED:
                    // remove the old event, the new one makes it useless
                    eventMap.erase(oldEvent->getPath());

                    // deallocate event
                    delete oldEvent;
                    oldEvent = NULL;
                    break;
            }
            break;
        }
        case Event::UPDATED:
        {
            switch (newEvent->getType())
            {
                case Event::CREATED:
                    STRIGI_LOG_INFO("strigi.EventListenerQueue.updateEventType",
                                    "Maybe we've lost some filesystem event");
                    // leave UPDATED state, it's the safer solution because with
                    // update event we make a delete and a create
                    break;
                case Event::UPDATED:
                    // leave UPDATED state
                    STRIGI_LOG_ERROR("strigi.EventListenerQueue.updateEventType",
                                     "UPDATED --> UPDATED = leave UPDATED");

                    break;
                case Event::DELETED:
                    oldEvent->setType( Event::DELETED);
                    STRIGI_LOG_ERROR("strigi.EventListenerQueue.updateEventType",
                                     "UPDATED --> DELETED = DELETED");
                    break;
            }
            break;
        }
        case Event::DELETED:
        {
            switch (newEvent->getType())
            {
                case Event::CREATED:
                    oldEvent->setType( Event::UPDATED);
                    STRIGI_LOG_ERROR("strigi.EventListenerQueue.updateEventType",
                                     "DELETED --> CREATED = UPDATED");
                    break;
                case Event::UPDATED:
                    STRIGI_LOG_INFO("strigi.EventListenerQueue.updateEventType",
                                     "Maybe we've lost some filesystem event");

                    // put in update state, it's the safer solution because with
                    // update event we make a delete and a create
                    oldEvent->setType( Event::UPDATED);
                    break;
                case Event::DELETED:
                    STRIGI_LOG_INFO("strigi.EventListenerQueue.updateEventType",
                                    "Maybe we've lost some filesystem event");
                    //leave DELETED state
                    break;
            }
            break;
        }
    }
}

void EventListenerQueue::addEvents (vector<Event*> events)
{
    vector<Event*>::iterator iter;

    STRIGI_MUTEX_LOCK (&m_mutex);

    Event* event = NULL;

    for (iter = events.begin(); iter != events.end(); iter++)
    {
        event = searchInProcessed(*iter);
        if (event)
        {
            // not to much time ago we have processed an event regarding
            // the same file/dir, we've to wait a little before processing this
            // new event
            putInWaiting (*iter);
            continue;
        }

        event = searchInWaiting(*iter);
        if (event)
        {
            // there's another event in the wainting queue that is related with
            // this file/dir. Let's update its status
            updateEventType (event, *iter, m_waiting);

            // we don't need this new event anymore, free-up some memory
            delete *iter;
            *iter = NULL;

            continue;
        }

        event = searchInToProcess(*iter);
        if (event)
        {
            updateEventType (event, *iter, m_toProcess);

            // we don't need this new event anymore, free-up some memory
            delete *iter;
            *iter = NULL;

            continue;
        }
        else
        {
            Event* e = *iter;
            string temp;

            // if we're arrived here this new event has to be processed
            m_toProcess.insert (make_pair (e->getPath(), e));
            STRIGI_LOG_DEBUG ("strigi.EventListenerQueue.addEvents",
                              string("event regarding ") + e->getPath() +
                                      " has been put in toProcess queue");
        }
    }

    STRIGI_MUTEX_UNLOCK (&m_mutex);
}

unsigned int EventListenerQueue::size()
{
    unsigned int i = 0;

    if (STRIGI_MUTEX_TRY_LOCK (&m_mutex) == 0)
    {
        i = m_toProcess.size();
        STRIGI_MUTEX_UNLOCK (&m_mutex);
    }

    return i;
}

vector <Event*> EventListenerQueue::getEvents()
{
    vector <Event*> result;

    if (STRIGI_MUTEX_TRY_LOCK (&m_mutex) == 0)
    {
        for (map<string, Event*>::iterator iter = m_toProcess.begin();
             iter != m_toProcess.end(); iter++)
        {
            result.push_back (new Event (iter->second));

            // move event to processed queue
            putInProcessed (iter->second);
        }

        m_toProcess.clear();

        STRIGI_MUTEX_UNLOCK (&m_mutex);
    }

    return result;
}
<|endoftext|>


<commit_before>#include <ruby.h>
#include <set>
#include <algorithm>

#include <boost/tuple/tuple.hpp>

using namespace boost;
using namespace std;

static VALUE cValueSet;
static ID id_new;
static ID id_to_value_set;

typedef std::set<VALUE> ValueSet;
static ValueSet& get_wrapped_set(VALUE self)
{
    void* object = 0;
    Data_Get_Struct(self, void, object);
    return *reinterpret_cast<ValueSet*>(object);
}
static void value_set_mark(ValueSet const* set)
{ std::for_each(set->begin(), set->end(), rb_gc_mark); }
static void value_set_free(ValueSet const* set)
{ delete set; }
static VALUE value_set_alloc(VALUE klass)
{
    ValueSet* cxx_set = new ValueSet;
    return Data_Wrap_Struct(klass, value_set_mark, value_set_free, cxx_set);
}
static VALUE value_set_each(VALUE self)
{
    ValueSet& set = get_wrapped_set(self);
    for_each(set.begin(), set.end(), rb_yield);
    return self;
}
static VALUE value_set_include_p(VALUE vself, VALUE vother)
{
    ValueSet const& self  = get_wrapped_set(vself);
    return self.find(vother) == self.end() ? Qfalse : Qtrue;
}
static VALUE value_set_to_value_set(VALUE self) { return self; }
static VALUE value_set_include_all_p(VALUE vself, VALUE vother)
{
    ValueSet const& self  = get_wrapped_set(vself);
    ValueSet const& other = get_wrapped_set(rb_funcall(vother, id_to_value_set, 0));
    return std::includes(self.begin(), self.end(), other.begin(), other.end()) ? Qtrue : Qfalse;
}

static VALUE value_set_union(VALUE vself, VALUE vother)
{
    ValueSet const& self  = get_wrapped_set(vself);
    ValueSet const& other = get_wrapped_set(vother);

    VALUE vresult = rb_funcall(cValueSet, id_new, 0);
    ValueSet& result = get_wrapped_set(vresult);
    std::set_union(self.begin(), self.end(), other.begin(), other.end(),
	    std::inserter(result, result.end()));
    return vresult;
}

/* call-seq:
 *  set.merge(other)		=> set
 *
 * Merges the elements of +other+ into +self+. If +other+ is a ValueSet, the operation is O(N + M)
 */
static VALUE value_set_merge(VALUE vself, VALUE vother)
{
    ValueSet& self  = get_wrapped_set(vself);
    ValueSet const& other = get_wrapped_set(rb_funcall(vother, id_to_value_set, 0));

    self.insert(other.begin(), other.end());
    return vself;
}

/* call-seq:
 *   set.intersection(other)	=> intersection_set
 *   set & other		=> intersection_set
 *
 * Computes the intersection of +set+ and +other+
 */
static VALUE value_set_intersection(VALUE vself, VALUE vother)
{
    ValueSet const& self  = get_wrapped_set(vself);
    ValueSet const& other = get_wrapped_set(rb_funcall(vother, id_to_value_set, 0));

    VALUE vresult = rb_funcall(cValueSet, id_new, 0);
    ValueSet& result = get_wrapped_set(vresult);
    std::set_intersection(self.begin(), self.end(), other.begin(), other.end(),
	    std::inserter(result, result.end()));
    return vresult;
}
static VALUE value_set_difference(VALUE vself, VALUE vother)
{
    ValueSet const& self  = get_wrapped_set(vself);
    ValueSet const& other = get_wrapped_set(rb_funcall(vother, id_to_value_set, 0));

    VALUE vresult = rb_funcall(cValueSet, id_new, 0);
    ValueSet& result = get_wrapped_set(vresult);
    std::set_difference(self.begin(), self.end(), other.begin(), other.end(),
	    std::inserter(result, result.end()));
    return vresult;
}

static VALUE value_set_insert(VALUE vself, VALUE v)
{
    ValueSet& self  = get_wrapped_set(vself);
    bool exists;
    tie(tuples::ignore, exists) = self.insert(v);
    return exists ? Qtrue : Qfalse;
}
static VALUE value_set_delete(VALUE vself, VALUE v)
{
    ValueSet& self  = get_wrapped_set(vself);
    size_t count = self.erase(v);
    return count > 0 ? Qtrue : Qfalse;
}

/* call-seq:
 *  set == other		=> true or false
 *
 * Equality
 */
static VALUE value_set_equal(VALUE vself, VALUE vother)
{
    ValueSet const& self  = get_wrapped_set(vself);
    ValueSet const& other = get_wrapped_set(rb_funcall(vother, id_to_value_set, 0));
    return (self == other) ? Qtrue : Qfalse;
}

static VALUE enumerable_to_value_set_i(VALUE i, VALUE* memo)
{
    ValueSet& result = *reinterpret_cast<ValueSet*>(memo);
    result.insert(i);
    return Qnil;
}
static VALUE enumerable_to_value_set(VALUE self)
{
    VALUE vresult = rb_funcall(cValueSet, id_new, 0);
    ValueSet& result = get_wrapped_set(vresult);

    rb_iterate(rb_each, self, RUBY_METHOD_FUNC(enumerable_to_value_set_i), reinterpret_cast<VALUE>(&result));
    return vresult;
}

static VALUE enumerable_each_uniq_i(VALUE i, VALUE* memo)
{
    set<VALUE>& seen = *reinterpret_cast< set<VALUE>* >(memo);
    if (seen.find(i) == seen.end())
    {
	seen.insert(i);
	return rb_yield(i);
    }
    else
	return Qnil;

}

static VALUE enumerable_each_uniq(VALUE self)
{
    set<VALUE> seen;
    rb_iterate(rb_each, self,
	    RUBY_METHOD_FUNC(enumerable_each_uniq_i), (VALUE)&seen);
    return self;
}

extern "C" void Init_faster()
{
    rb_define_method(rb_mEnumerable, "each_uniq", RUBY_METHOD_FUNC(enumerable_each_uniq), 0);
    rb_define_method(rb_mEnumerable, "to_value_set", RUBY_METHOD_FUNC(enumerable_to_value_set), 0);

    cValueSet = rb_define_class("ValueSet", rb_cObject);
    id_new = rb_intern("new");
    id_to_value_set = rb_intern("to_value_set");
    rb_define_alloc_func(cValueSet, value_set_alloc);
    rb_define_method(cValueSet, "each", RUBY_METHOD_FUNC(value_set_each), 0);
    rb_define_method(cValueSet, "include?", RUBY_METHOD_FUNC(value_set_include_p), 1);
    rb_define_method(cValueSet, "include_all?", RUBY_METHOD_FUNC(value_set_include_all_p), 1);
    rb_define_method(cValueSet, "union", RUBY_METHOD_FUNC(value_set_union), 1);
    rb_define_method(cValueSet, "intersection", RUBY_METHOD_FUNC(value_set_intersection), 1);
    rb_define_method(cValueSet, "difference", RUBY_METHOD_FUNC(value_set_difference), 1);
    rb_define_method(cValueSet, "insert", RUBY_METHOD_FUNC(value_set_insert), 1);
    rb_define_method(cValueSet, "merge", RUBY_METHOD_FUNC(value_set_merge), 1);
    rb_define_method(cValueSet, "delete", RUBY_METHOD_FUNC(value_set_delete), 1);
    rb_define_method(cValueSet, "==", RUBY_METHOD_FUNC(value_set_equal), 1);
    rb_define_method(cValueSet, "to_value_set", RUBY_METHOD_FUNC(value_set_to_value_set), 0);
}

<commit_msg>[value_set] documentation<commit_after>#include <ruby.h>
#include <set>
#include <algorithm>

#include <boost/tuple/tuple.hpp>

using namespace boost;
using namespace std;

static VALUE cValueSet;
static ID id_new;
static ID id_to_value_set;

typedef std::set<VALUE> ValueSet;
static ValueSet& get_wrapped_set(VALUE self)
{
    void* object = 0;
    Data_Get_Struct(self, void, object);
    return *reinterpret_cast<ValueSet*>(object);
}
static void value_set_mark(ValueSet const* set)
{ std::for_each(set->begin(), set->end(), rb_gc_mark); }
static void value_set_free(ValueSet const* set)
{ delete set; }
static VALUE value_set_alloc(VALUE klass)
{
    ValueSet* cxx_set = new ValueSet;
    return Data_Wrap_Struct(klass, value_set_mark, value_set_free, cxx_set);
}
/* call-seq:
 *  set.each { |obj| ... }	    => set
 */
static VALUE value_set_each(VALUE self)
{
    ValueSet& set = get_wrapped_set(self);
    for_each(set.begin(), set.end(), rb_yield);
    return self;
}
/* call-seq:
 *  set.include?(value)	    => true or false
 *
 * Checks if +value+ is in +set+
 */
static VALUE value_set_include_p(VALUE vself, VALUE vother)
{
    ValueSet const& self  = get_wrapped_set(vself);
    return self.find(vother) == self.end() ? Qfalse : Qtrue;
}

/* call-seq:
 *  set.to_value_set		    => set
 */
static VALUE value_set_to_value_set(VALUE self) { return self; }

/* call-seq:
 *  set.include_all?(other)		=> true or false
 *
 * Checks if all elements of +other+ are in +set+
 */
static VALUE value_set_include_all_p(VALUE vself, VALUE vother)
{
    ValueSet const& self  = get_wrapped_set(vself);
    ValueSet const& other = get_wrapped_set(rb_funcall(vother, id_to_value_set, 0));
    return std::includes(self.begin(), self.end(), other.begin(), other.end()) ? Qtrue : Qfalse;
}

/* call-seq:
 *  set.union(other)		=> union_set
 *  set | other			=> union_set
 *
 * Computes the union of +set+ and +other+
 */
static VALUE value_set_union(VALUE vself, VALUE vother)
{
    ValueSet const& self  = get_wrapped_set(vself);
    ValueSet const& other = get_wrapped_set(vother);

    VALUE vresult = rb_funcall(cValueSet, id_new, 0);
    ValueSet& result = get_wrapped_set(vresult);
    std::set_union(self.begin(), self.end(), other.begin(), other.end(),
	    std::inserter(result, result.end()));
    return vresult;
}

/* call-seq:
 *  set.merge(other)		=> set
 *
 * Merges the elements of +other+ into +self+. If +other+ is a ValueSet, the operation is O(N + M)
 */
static VALUE value_set_merge(VALUE vself, VALUE vother)
{
    ValueSet& self  = get_wrapped_set(vself);
    ValueSet const& other = get_wrapped_set(rb_funcall(vother, id_to_value_set, 0));

    self.insert(other.begin(), other.end());
    return vself;
}

/* call-seq:
 *   set.intersection(other)	=> intersection_set
 *   set & other		=> intersection_set
 *
 * Computes the intersection of +set+ and +other+
 */
static VALUE value_set_intersection(VALUE vself, VALUE vother)
{
    ValueSet const& self  = get_wrapped_set(vself);
    ValueSet const& other = get_wrapped_set(rb_funcall(vother, id_to_value_set, 0));

    VALUE vresult = rb_funcall(cValueSet, id_new, 0);
    ValueSet& result = get_wrapped_set(vresult);
    std::set_intersection(self.begin(), self.end(), other.begin(), other.end(),
	    std::inserter(result, result.end()));
    return vresult;
}
/* call-seq:
 *   set.difference(other)	=> intersection_set
 *   set - other		=> intersection_set
 *
 * Computes the set of all elements of +set+ not in +other+
 */
static VALUE value_set_difference(VALUE vself, VALUE vother)
{
    ValueSet const& self  = get_wrapped_set(vself);
    ValueSet const& other = get_wrapped_set(rb_funcall(vother, id_to_value_set, 0));

    VALUE vresult = rb_funcall(cValueSet, id_new, 0);
    ValueSet& result = get_wrapped_set(vresult);
    std::set_difference(self.begin(), self.end(), other.begin(), other.end(),
	    std::inserter(result, result.end()));
    return vresult;
}

/* call-seq:
 *  set.insert(value)		=> true or false
 *
 * Inserts +value+ into +set+. Returns true if the value did not exist
 * in the set yet (it has actually been inserted), and false otherwise.
 */
static VALUE value_set_insert(VALUE vself, VALUE v)
{
    ValueSet& self  = get_wrapped_set(vself);
    bool exists;
    tie(tuples::ignore, exists) = self.insert(v);
    return exists ? Qtrue : Qfalse;
}
/* call-seq:
 *  set.delete(value)		=> true or false
 *
 * Removes +value+ from +set+. Returns true if the value did exist
 * in the set yet (it has actually been removed), and false otherwise.
 */
static VALUE value_set_delete(VALUE vself, VALUE v)
{
    ValueSet& self  = get_wrapped_set(vself);
    size_t count = self.erase(v);
    return count > 0 ? Qtrue : Qfalse;
}

/* call-seq:
 *  set == other		=> true or false
 *
 * Equality
 */
static VALUE value_set_equal(VALUE vself, VALUE vother)
{
    ValueSet const& self  = get_wrapped_set(vself);
    ValueSet const& other = get_wrapped_set(rb_funcall(vother, id_to_value_set, 0));
    return (self == other) ? Qtrue : Qfalse;
}

static VALUE enumerable_to_value_set_i(VALUE i, VALUE* memo)
{
    ValueSet& result = *reinterpret_cast<ValueSet*>(memo);
    result.insert(i);
    return Qnil;
}
/* call-seq:
 *  enum.to_value_set		=> value_set
 *
 * Builds a value_set object from this enumerable
 */
static VALUE enumerable_to_value_set(VALUE self)
{
    VALUE vresult = rb_funcall(cValueSet, id_new, 0);
    ValueSet& result = get_wrapped_set(vresult);

    rb_iterate(rb_each, self, RUBY_METHOD_FUNC(enumerable_to_value_set_i), reinterpret_cast<VALUE>(&result));
    return vresult;
}

static VALUE enumerable_each_uniq_i(VALUE i, VALUE* memo)
{
    set<VALUE>& seen = *reinterpret_cast< set<VALUE>* >(memo);
    if (seen.find(i) == seen.end())
    {
	seen.insert(i);
	return rb_yield(i);
    }
    else
	return Qnil;

}

/* call-seq:
 *  enum.each_uniq { |obj| ... }
 *
 * Yields all unique values found in +enum+
 */
static VALUE enumerable_each_uniq(VALUE self)
{
    set<VALUE> seen;
    rb_iterate(rb_each, self,
	    RUBY_METHOD_FUNC(enumerable_each_uniq_i), (VALUE)&seen);
    return self;
}

extern "C" void Init_faster()
{
    rb_define_method(rb_mEnumerable, "each_uniq", RUBY_METHOD_FUNC(enumerable_each_uniq), 0);
    rb_define_method(rb_mEnumerable, "to_value_set", RUBY_METHOD_FUNC(enumerable_to_value_set), 0);

    cValueSet = rb_define_class("ValueSet", rb_cObject);
    id_new = rb_intern("new");
    id_to_value_set = rb_intern("to_value_set");
    rb_define_alloc_func(cValueSet, value_set_alloc);
    rb_define_method(cValueSet, "each", RUBY_METHOD_FUNC(value_set_each), 0);
    rb_define_method(cValueSet, "include?", RUBY_METHOD_FUNC(value_set_include_p), 1);
    rb_define_method(cValueSet, "include_all?", RUBY_METHOD_FUNC(value_set_include_all_p), 1);
    rb_define_method(cValueSet, "union", RUBY_METHOD_FUNC(value_set_union), 1);
    rb_define_method(cValueSet, "intersection", RUBY_METHOD_FUNC(value_set_intersection), 1);
    rb_define_method(cValueSet, "difference", RUBY_METHOD_FUNC(value_set_difference), 1);
    rb_define_method(cValueSet, "insert", RUBY_METHOD_FUNC(value_set_insert), 1);
    rb_define_method(cValueSet, "merge", RUBY_METHOD_FUNC(value_set_merge), 1);
    rb_define_method(cValueSet, "delete", RUBY_METHOD_FUNC(value_set_delete), 1);
    rb_define_method(cValueSet, "==", RUBY_METHOD_FUNC(value_set_equal), 1);
    rb_define_method(cValueSet, "to_value_set", RUBY_METHOD_FUNC(value_set_to_value_set), 0);
}

<|endoftext|>


<commit_before>// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
//
// 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 <limits>
namespace iox
{
namespace cxx
{
template <typename Source>
inline typename std::enable_if<!std::is_convertible<Source, std::string>::value, std::string>::type
convert::toString(const Source& t)
{
    std::stringstream ss;
    ss << t;
    return ss.str();
}

template <typename Source>
inline typename std::enable_if<std::is_convertible<Source, std::string>::value, std::string>::type
convert::toString(const Source& t)
{
    return t;
}

template <typename Destination>
inline typename std::enable_if<std::is_convertible<const char*, Destination>::value, bool>::type
fromString(const char* v, Destination& dest)
{
    dest = Destination(v);
    return true;
}

template <>
inline bool convert::fromString<std::string>(const char* v, std::string& dest)
{
    dest = std::string(v);
    return true;
}

template <>
inline bool convert::fromString<char>(const char* v, char& dest)
{
    if (strlen(v) != 1u)
    {
        std::cerr << v << " is not a char" << std::endl;
        return false;
    }
    dest = v[0];
    return true;
}

template <>
inline bool convert::fromString<string<100>>(const char* v, string<100>& dest)
{
    dest = string<100>(TruncateToCapacity, v);
    return true;
}

inline bool convert::stringIsNumber(const char* v, const NumberType type)
{
    if (v[0] == '\0')
        return false;

    bool hasDot = false;

    for (uint32_t i = 0u; v[i] != '\0'; ++i)
    {
        if (v[i] >= 48 && v[i] <= 57) // 48 == ascii 0, 57 == ascii 9
        {
            continue;
        }
        else if (type != NumberType::UNSIGNED_INTEGER && i == 0u
                 && (v[i] == 43 || v[i] == 45)) // 43 == ascii +, 45 == ascii -
        {
            continue;
        }
        else if (type == NumberType::FLOAT && !hasDot && v[i] == 46) // 46 == ascii .
        {
            hasDot = true;
        }
        else
        {
            return false;
        }
    }

    return true;
}

inline bool convert::stringIsNumberWithErrorMessage(const char* v, const NumberType type)
{
    if (!stringIsNumber(v, type))
    {
        std::cerr << v << " is not ";
        switch (type)
        {
        case NumberType::FLOAT:
        {
            std::cerr << "a float";
            break;
        }
        case NumberType::INTEGER:
        {
            std::cerr << "a signed integer";
            break;
        }
        case NumberType::UNSIGNED_INTEGER:
        {
            std::cerr << "an unsigned integer";
            break;
        }
        }
        std::cerr << std::endl;
        return false;
    }
    return true;
}

template <>
inline bool convert::fromString<float>(const char* v, float& dest)
{
    if (!stringIsNumberWithErrorMessage(v, NumberType::FLOAT))
    {
        return false;
    }

    auto call = makeSmartC(strtof, ReturnMode::PRE_DEFINED_ERROR_CODE, {HUGE_VALF, -HUGE_VALF}, {}, v, nullptr);

    if (call.hasErrors())
    {
        return false;
    }

    dest = call.getReturnValue();
    return true;
}

template <>
inline bool convert::fromString<double>(const char* v, double& dest)
{
    if (!stringIsNumberWithErrorMessage(v, NumberType::FLOAT))
    {
        return false;
    }

    auto call = makeSmartC(strtod, ReturnMode::PRE_DEFINED_ERROR_CODE, {HUGE_VAL, -HUGE_VAL}, {}, v, nullptr);

    if (call.hasErrors())
    {
        return false;
    }

    dest = call.getReturnValue();
    return true;
}

template <>
inline bool convert::fromString<long double>(const char* v, long double& dest)
{
    if (!stringIsNumberWithErrorMessage(v, NumberType::FLOAT))
    {
        return false;
    }

    auto call = makeSmartC(strtold, ReturnMode::PRE_DEFINED_ERROR_CODE, {HUGE_VALL, -HUGE_VALL}, {}, v, nullptr);

    if (call.hasErrors())
    {
        return false;
    }

    dest = call.getReturnValue();
    return true;
}

template <>
inline bool convert::fromString<uint64_t>(const char* v, uint64_t& dest)
{
    if (!stringIsNumberWithErrorMessage(v, NumberType::UNSIGNED_INTEGER))
    {
        return false;
    }

    auto call = makeSmartC(strtoull, ReturnMode::PRE_DEFINED_ERROR_CODE, {ULLONG_MAX}, {}, v, nullptr, 10u);
    if (call.hasErrors())
    {
        return false;
    }

    if (call.getReturnValue() > std::numeric_limits<uint64_t>::max())
    {
        std::cerr << call.getReturnValue() << " too large, uint64_t overflow" << std::endl;
        return false;
    }

    dest = static_cast<uint64_t>(call.getReturnValue());
    return true;
}

/// introduced for mac os since unsigned long is not uint64_t despite it has the same size
/// who knows why ¯\_(ツ)_/¯
template <>
inline bool convert::fromString<unsigned long>(const char* v, unsigned long& dest)
{
    uint64_t temp{0};
    bool retVal = fromString(v, temp);
    dest = temp;
    return retVal;
}

template <>
inline bool convert::fromString<uint32_t>(const char* v, uint32_t& dest)
{
    if (!stringIsNumberWithErrorMessage(v, NumberType::UNSIGNED_INTEGER))
    {
        return false;
    }

    auto call = makeSmartC(strtoull, ReturnMode::PRE_DEFINED_ERROR_CODE, {ULLONG_MAX}, {}, v, nullptr, 10u);
    if (call.hasErrors())
    {
        return false;
    }

    if (call.getReturnValue() > std::numeric_limits<uint32_t>::max())
    {
        std::cerr << call.getReturnValue() << " too large, uint32_t overflow" << std::endl;
        return false;
    }

    dest = static_cast<uint32_t>(call.getReturnValue());
    return true;
}

template <>
inline bool convert::fromString<uint16_t>(const char* v, uint16_t& dest)
{
    if (!stringIsNumberWithErrorMessage(v, NumberType::UNSIGNED_INTEGER))
    {
        return false;
    }

    auto call = makeSmartC(strtoul, ReturnMode::PRE_DEFINED_ERROR_CODE, {ULONG_MAX}, {}, v, nullptr, 10);
    if (call.hasErrors())
    {
        return false;
    }

    if (call.getReturnValue() > std::numeric_limits<uint16_t>::max())
    {
        std::cerr << call.getReturnValue() << " too large, uint16_t overflow" << std::endl;
        return false;
    }

    dest = static_cast<uint16_t>(call.getReturnValue());
    return true;
}

template <>
inline bool convert::fromString<uint8_t>(const char* v, uint8_t& dest)
{
    if (!stringIsNumberWithErrorMessage(v, NumberType::UNSIGNED_INTEGER))
    {
        return false;
    }

    auto call = makeSmartC(strtoul, ReturnMode::PRE_DEFINED_ERROR_CODE, {ULONG_MAX}, {}, v, nullptr, 10);
    if (call.hasErrors())
    {
        return false;
    }

    if (call.getReturnValue() > std::numeric_limits<uint8_t>::max())
    {
        std::cerr << call.getReturnValue() << " too large, uint8_t overflow" << std::endl;
        return false;
    }

    dest = static_cast<uint8_t>(call.getReturnValue());
    return true;
}

template <>
inline bool convert::fromString<int64_t>(const char* v, int64_t& dest)
{
    if (!stringIsNumberWithErrorMessage(v, NumberType::INTEGER))
    {
        return false;
    }

    auto call = makeSmartC(strtoll, ReturnMode::PRE_DEFINED_ERROR_CODE, {LLONG_MAX, LLONG_MIN}, {}, v, nullptr, 10);
    if (call.hasErrors())
    {
        return false;
    }

    if (call.getReturnValue() > std::numeric_limits<int64_t>::max()
        || call.getReturnValue() < std::numeric_limits<int64_t>::min())
    {
        std::cerr << call.getReturnValue() << " is out of range, int64_t overflow" << std::endl;
        return false;
    }

    dest = static_cast<int64_t>(call.getReturnValue());
    return true;
}

template <>
inline bool convert::fromString<int32_t>(const char* v, int32_t& dest)
{
    if (!stringIsNumberWithErrorMessage(v, NumberType::INTEGER))
    {
        return false;
    }

    auto call = makeSmartC(strtoll, ReturnMode::PRE_DEFINED_ERROR_CODE, {LLONG_MAX, LLONG_MIN}, {}, v, nullptr, 10);
    if (call.hasErrors())
    {
        return false;
    }

    if (call.getReturnValue() > std::numeric_limits<int32_t>::max()
        || call.getReturnValue() < std::numeric_limits<int32_t>::min())
    {
        std::cerr << call.getReturnValue() << " is out of range, int32_t overflow" << std::endl;
        return false;
    }

    dest = static_cast<int32_t>(call.getReturnValue());
    return true;
}

template <>
inline bool convert::fromString<int16_t>(const char* v, int16_t& dest)
{
    if (!stringIsNumberWithErrorMessage(v, NumberType::INTEGER))
    {
        return false;
    }

    auto call = makeSmartC(strtol, ReturnMode::PRE_DEFINED_ERROR_CODE, {LONG_MAX, LONG_MIN}, {}, v, nullptr, 10);
    if (call.hasErrors())
    {
        return false;
    }

    if (call.getReturnValue() > std::numeric_limits<int16_t>::max()
        || call.getReturnValue() < std::numeric_limits<int16_t>::min())
    {
        std::cerr << call.getReturnValue() << " is out of range, int16_t overflow" << std::endl;
        return false;
    }

    dest = static_cast<int16_t>(call.getReturnValue());
    return true;
}

template <>
inline bool convert::fromString<int8_t>(const char* v, int8_t& dest)
{
    if (!stringIsNumberWithErrorMessage(v, NumberType::INTEGER))
    {
        return false;
    }

    auto call = makeSmartC(strtol, ReturnMode::PRE_DEFINED_ERROR_CODE, {LONG_MAX, LONG_MIN}, {}, v, nullptr, 10);
    if (call.hasErrors())
    {
        return false;
    }

    if (call.getReturnValue() > std::numeric_limits<int8_t>::max()
        || call.getReturnValue() < std::numeric_limits<int8_t>::min())
    {
        std::cerr << call.getReturnValue() << " is out of range, int8_t overflow" << std::endl;
        return false;
    }

    dest = static_cast<int8_t>(call.getReturnValue());
    return true;
}

template <>
inline bool convert::fromString<bool>(const char* v, bool& dest)
{
    if (!stringIsNumberWithErrorMessage(v, NumberType::UNSIGNED_INTEGER))
    {
        return false;
    }

    auto call = makeSmartC(strtoul, ReturnMode::PRE_DEFINED_ERROR_CODE, {ULONG_MAX}, {}, v, nullptr, 10);
    if (call.hasErrors())
    {
        return false;
    }

    dest = static_cast<bool>(call.getReturnValue());
    return true;
}

} // namespace cxx
} // namespace iox
<commit_msg>iox-#32 overload for fromString conversion to unsigned long only for mac os<commit_after>// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
//
// 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 <limits>
namespace iox
{
namespace cxx
{
template <typename Source>
inline typename std::enable_if<!std::is_convertible<Source, std::string>::value, std::string>::type
convert::toString(const Source& t)
{
    std::stringstream ss;
    ss << t;
    return ss.str();
}

template <typename Source>
inline typename std::enable_if<std::is_convertible<Source, std::string>::value, std::string>::type
convert::toString(const Source& t)
{
    return t;
}

template <typename Destination>
inline typename std::enable_if<std::is_convertible<const char*, Destination>::value, bool>::type
fromString(const char* v, Destination& dest)
{
    dest = Destination(v);
    return true;
}

template <>
inline bool convert::fromString<std::string>(const char* v, std::string& dest)
{
    dest = std::string(v);
    return true;
}

template <>
inline bool convert::fromString<char>(const char* v, char& dest)
{
    if (strlen(v) != 1u)
    {
        std::cerr << v << " is not a char" << std::endl;
        return false;
    }
    dest = v[0];
    return true;
}

template <>
inline bool convert::fromString<string<100>>(const char* v, string<100>& dest)
{
    dest = string<100>(TruncateToCapacity, v);
    return true;
}

inline bool convert::stringIsNumber(const char* v, const NumberType type)
{
    if (v[0] == '\0')
        return false;

    bool hasDot = false;

    for (uint32_t i = 0u; v[i] != '\0'; ++i)
    {
        if (v[i] >= 48 && v[i] <= 57) // 48 == ascii 0, 57 == ascii 9
        {
            continue;
        }
        else if (type != NumberType::UNSIGNED_INTEGER && i == 0u
                 && (v[i] == 43 || v[i] == 45)) // 43 == ascii +, 45 == ascii -
        {
            continue;
        }
        else if (type == NumberType::FLOAT && !hasDot && v[i] == 46) // 46 == ascii .
        {
            hasDot = true;
        }
        else
        {
            return false;
        }
    }

    return true;
}

inline bool convert::stringIsNumberWithErrorMessage(const char* v, const NumberType type)
{
    if (!stringIsNumber(v, type))
    {
        std::cerr << v << " is not ";
        switch (type)
        {
        case NumberType::FLOAT:
        {
            std::cerr << "a float";
            break;
        }
        case NumberType::INTEGER:
        {
            std::cerr << "a signed integer";
            break;
        }
        case NumberType::UNSIGNED_INTEGER:
        {
            std::cerr << "an unsigned integer";
            break;
        }
        }
        std::cerr << std::endl;
        return false;
    }
    return true;
}

template <>
inline bool convert::fromString<float>(const char* v, float& dest)
{
    if (!stringIsNumberWithErrorMessage(v, NumberType::FLOAT))
    {
        return false;
    }

    auto call = makeSmartC(strtof, ReturnMode::PRE_DEFINED_ERROR_CODE, {HUGE_VALF, -HUGE_VALF}, {}, v, nullptr);

    if (call.hasErrors())
    {
        return false;
    }

    dest = call.getReturnValue();
    return true;
}

template <>
inline bool convert::fromString<double>(const char* v, double& dest)
{
    if (!stringIsNumberWithErrorMessage(v, NumberType::FLOAT))
    {
        return false;
    }

    auto call = makeSmartC(strtod, ReturnMode::PRE_DEFINED_ERROR_CODE, {HUGE_VAL, -HUGE_VAL}, {}, v, nullptr);

    if (call.hasErrors())
    {
        return false;
    }

    dest = call.getReturnValue();
    return true;
}

template <>
inline bool convert::fromString<long double>(const char* v, long double& dest)
{
    if (!stringIsNumberWithErrorMessage(v, NumberType::FLOAT))
    {
        return false;
    }

    auto call = makeSmartC(strtold, ReturnMode::PRE_DEFINED_ERROR_CODE, {HUGE_VALL, -HUGE_VALL}, {}, v, nullptr);

    if (call.hasErrors())
    {
        return false;
    }

    dest = call.getReturnValue();
    return true;
}

template <>
inline bool convert::fromString<uint64_t>(const char* v, uint64_t& dest)
{
    if (!stringIsNumberWithErrorMessage(v, NumberType::UNSIGNED_INTEGER))
    {
        return false;
    }

    auto call = makeSmartC(strtoull, ReturnMode::PRE_DEFINED_ERROR_CODE, {ULLONG_MAX}, {}, v, nullptr, 10u);
    if (call.hasErrors())
    {
        return false;
    }

    if (call.getReturnValue() > std::numeric_limits<uint64_t>::max())
    {
        std::cerr << call.getReturnValue() << " too large, uint64_t overflow" << std::endl;
        return false;
    }

    dest = static_cast<uint64_t>(call.getReturnValue());
    return true;
}

#ifdef __APPLE__
/// introduced for mac os since unsigned long is not uint64_t despite it has the same size
/// who knows why ¯\_(ツ)_/¯
template <>
inline bool convert::fromString<unsigned long>(const char* v, unsigned long& dest)
{
    uint64_t temp{0};
    bool retVal = fromString(v, temp);
    dest = temp;
    return retVal;
}
#endif

template <>
inline bool convert::fromString<uint32_t>(const char* v, uint32_t& dest)
{
    if (!stringIsNumberWithErrorMessage(v, NumberType::UNSIGNED_INTEGER))
    {
        return false;
    }

    auto call = makeSmartC(strtoull, ReturnMode::PRE_DEFINED_ERROR_CODE, {ULLONG_MAX}, {}, v, nullptr, 10u);
    if (call.hasErrors())
    {
        return false;
    }

    if (call.getReturnValue() > std::numeric_limits<uint32_t>::max())
    {
        std::cerr << call.getReturnValue() << " too large, uint32_t overflow" << std::endl;
        return false;
    }

    dest = static_cast<uint32_t>(call.getReturnValue());
    return true;
}

template <>
inline bool convert::fromString<uint16_t>(const char* v, uint16_t& dest)
{
    if (!stringIsNumberWithErrorMessage(v, NumberType::UNSIGNED_INTEGER))
    {
        return false;
    }

    auto call = makeSmartC(strtoul, ReturnMode::PRE_DEFINED_ERROR_CODE, {ULONG_MAX}, {}, v, nullptr, 10);
    if (call.hasErrors())
    {
        return false;
    }

    if (call.getReturnValue() > std::numeric_limits<uint16_t>::max())
    {
        std::cerr << call.getReturnValue() << " too large, uint16_t overflow" << std::endl;
        return false;
    }

    dest = static_cast<uint16_t>(call.getReturnValue());
    return true;
}

template <>
inline bool convert::fromString<uint8_t>(const char* v, uint8_t& dest)
{
    if (!stringIsNumberWithErrorMessage(v, NumberType::UNSIGNED_INTEGER))
    {
        return false;
    }

    auto call = makeSmartC(strtoul, ReturnMode::PRE_DEFINED_ERROR_CODE, {ULONG_MAX}, {}, v, nullptr, 10);
    if (call.hasErrors())
    {
        return false;
    }

    if (call.getReturnValue() > std::numeric_limits<uint8_t>::max())
    {
        std::cerr << call.getReturnValue() << " too large, uint8_t overflow" << std::endl;
        return false;
    }

    dest = static_cast<uint8_t>(call.getReturnValue());
    return true;
}

template <>
inline bool convert::fromString<int64_t>(const char* v, int64_t& dest)
{
    if (!stringIsNumberWithErrorMessage(v, NumberType::INTEGER))
    {
        return false;
    }

    auto call = makeSmartC(strtoll, ReturnMode::PRE_DEFINED_ERROR_CODE, {LLONG_MAX, LLONG_MIN}, {}, v, nullptr, 10);
    if (call.hasErrors())
    {
        return false;
    }

    if (call.getReturnValue() > std::numeric_limits<int64_t>::max()
        || call.getReturnValue() < std::numeric_limits<int64_t>::min())
    {
        std::cerr << call.getReturnValue() << " is out of range, int64_t overflow" << std::endl;
        return false;
    }

    dest = static_cast<int64_t>(call.getReturnValue());
    return true;
}

template <>
inline bool convert::fromString<int32_t>(const char* v, int32_t& dest)
{
    if (!stringIsNumberWithErrorMessage(v, NumberType::INTEGER))
    {
        return false;
    }

    auto call = makeSmartC(strtoll, ReturnMode::PRE_DEFINED_ERROR_CODE, {LLONG_MAX, LLONG_MIN}, {}, v, nullptr, 10);
    if (call.hasErrors())
    {
        return false;
    }

    if (call.getReturnValue() > std::numeric_limits<int32_t>::max()
        || call.getReturnValue() < std::numeric_limits<int32_t>::min())
    {
        std::cerr << call.getReturnValue() << " is out of range, int32_t overflow" << std::endl;
        return false;
    }

    dest = static_cast<int32_t>(call.getReturnValue());
    return true;
}

template <>
inline bool convert::fromString<int16_t>(const char* v, int16_t& dest)
{
    if (!stringIsNumberWithErrorMessage(v, NumberType::INTEGER))
    {
        return false;
    }

    auto call = makeSmartC(strtol, ReturnMode::PRE_DEFINED_ERROR_CODE, {LONG_MAX, LONG_MIN}, {}, v, nullptr, 10);
    if (call.hasErrors())
    {
        return false;
    }

    if (call.getReturnValue() > std::numeric_limits<int16_t>::max()
        || call.getReturnValue() < std::numeric_limits<int16_t>::min())
    {
        std::cerr << call.getReturnValue() << " is out of range, int16_t overflow" << std::endl;
        return false;
    }

    dest = static_cast<int16_t>(call.getReturnValue());
    return true;
}

template <>
inline bool convert::fromString<int8_t>(const char* v, int8_t& dest)
{
    if (!stringIsNumberWithErrorMessage(v, NumberType::INTEGER))
    {
        return false;
    }

    auto call = makeSmartC(strtol, ReturnMode::PRE_DEFINED_ERROR_CODE, {LONG_MAX, LONG_MIN}, {}, v, nullptr, 10);
    if (call.hasErrors())
    {
        return false;
    }

    if (call.getReturnValue() > std::numeric_limits<int8_t>::max()
        || call.getReturnValue() < std::numeric_limits<int8_t>::min())
    {
        std::cerr << call.getReturnValue() << " is out of range, int8_t overflow" << std::endl;
        return false;
    }

    dest = static_cast<int8_t>(call.getReturnValue());
    return true;
}

template <>
inline bool convert::fromString<bool>(const char* v, bool& dest)
{
    if (!stringIsNumberWithErrorMessage(v, NumberType::UNSIGNED_INTEGER))
    {
        return false;
    }

    auto call = makeSmartC(strtoul, ReturnMode::PRE_DEFINED_ERROR_CODE, {ULONG_MAX}, {}, v, nullptr, 10);
    if (call.hasErrors())
    {
        return false;
    }

    dest = static_cast<bool>(call.getReturnValue());
    return true;
}

} // namespace cxx
} // namespace iox
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: PresentationViewShell.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 05:12:15 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SD_PRESENTATION_VIEW_SHELL_HXX
#define SD_PRESENTATION_VIEW_SHELL_HXX

#ifndef SD_DRAW_VIEW_SHELL
#include "DrawViewShell.hxx"
#endif

namespace sd {

/** This view shell is responsible for showing the presentation of an
    Impress document.
*/
class PresentationViewShell
    : public DrawViewShell
{
public:
    TYPEINFO();

    SFX_DECL_VIEWFACTORY(PresViewShell);
    SFX_DECL_INTERFACE( SD_IF_SDPRESVIEWSHELL );

    PresentationViewShell (
        SfxViewFrame* pFrame,
        ViewShellBase& rViewShellBase,
        ::Window* pParentWindow,
        FrameView* pFrameView = NULL);
    static void     CreateFullScreenShow(ViewShell* pOriginShell, SfxRequest& rReq );

    /** This method is used by a simple class that passes some
        arguments from the creator of the new view shell to the new view
        shell object by waiting for its asynchronous creation.
        @param pFrameView
            The frame view that is typically used by the creating object and
            that shall be shared by the created view shell.
        @param rRequest
            A request from which some arguments are extracted by the
            FuSlideShow object.  It usually comes from an Execute() method
            that initiated the creation of the new presentation view shell.
        @param nPageNumber
            The number of the page at which to start the show.
    */
    void FinishInitialization (
        FrameView* pFrameView,
        SfxRequest& rRequest,
        USHORT nPageNumber);

protected:
    virtual SvxRuler* CreateHRuler(::sd::Window* pWin, BOOL bIsFirst);
    virtual SvxRuler* CreateVRuler(::sd::Window* pWin);

private:
    Rectangle       maOldVisArea;
    sal_Bool        mbShowStarted;

    PresentationViewShell (
        SfxViewFrame* pFrame,
        ::Window* pParentWindow,
        const DrawViewShell& rShell);
    virtual ~PresentationViewShell (void);

    virtual void Activate (BOOL bIsMDIActivate);
    virtual void Paint (const Rectangle& rRect, ::sd::Window* pWin);
};

} // end of namespace sd

#endif
<commit_msg>INTEGRATION: CWS sdwarningsbegone (1.5.314); FILE MERGED 2006/11/22 12:42:01 cl 1.5.314.1: #i69285# warning free code changes for unxlngi6.pro<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: PresentationViewShell.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: kz $ $Date: 2006-12-12 17:36:56 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SD_PRESENTATION_VIEW_SHELL_HXX
#define SD_PRESENTATION_VIEW_SHELL_HXX

#ifndef SD_DRAW_VIEW_SHELL
#include "DrawViewShell.hxx"
#endif

namespace sd {

/** This view shell is responsible for showing the presentation of an
    Impress document.
*/
class PresentationViewShell
    : public DrawViewShell
{
public:
    TYPEINFO();

    SFX_DECL_VIEWFACTORY(PresViewShell);
    SFX_DECL_INTERFACE( SD_IF_SDPRESVIEWSHELL )

    PresentationViewShell (
        SfxViewFrame* pFrame,
        ViewShellBase& rViewShellBase,
        ::Window* pParentWindow,
        FrameView* pFrameView = NULL);
    static void     CreateFullScreenShow(ViewShell* pOriginShell, SfxRequest& rReq );

    /** This method is used by a simple class that passes some
        arguments from the creator of the new view shell to the new view
        shell object by waiting for its asynchronous creation.
        @param pFrameView
            The frame view that is typically used by the creating object and
            that shall be shared by the created view shell.
        @param rRequest
            A request from which some arguments are extracted by the
            FuSlideShow object.  It usually comes from an Execute() method
            that initiated the creation of the new presentation view shell.
        @param nPageNumber
            The number of the page at which to start the show.
    */
    void FinishInitialization (
        FrameView* pFrameView,
        SfxRequest& rRequest,
        USHORT nPageNumber);

protected:
    virtual SvxRuler* CreateHRuler(::sd::Window* pWin, BOOL bIsFirst);
    virtual SvxRuler* CreateVRuler(::sd::Window* pWin);

private:
    Rectangle       maOldVisArea;
    sal_Bool        mbShowStarted;

    PresentationViewShell (
        SfxViewFrame* pFrame,
        ::Window* pParentWindow,
        const DrawViewShell& rShell);
    virtual ~PresentationViewShell (void);

    virtual void Activate (BOOL bIsMDIActivate);
    virtual void Paint (const Rectangle& rRect, ::sd::Window* pWin);
};

} // end of namespace sd

#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: GraphicViewShellBase.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: obo $ $Date: 2004-01-20 12:37:41 $
 *
 *  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 "GraphicViewShellBase.hxx"

#ifndef SD_RESID_HXX
#include "sdresid.hxx"
#endif
#ifndef SD_GRAPHIC_DOC_SHELL_HXX
#include "GraphicDocShell.hxx"
#endif
#include "strings.hrc"

namespace sd {

class DrawDocShell;

TYPEINIT1(GraphicViewShellBase, ViewShellBase);

SFX_IMPL_VIEWFACTORY(GraphicViewShellBase, SdResId(STR_DEFAULTVIEW))
{
    SFX_VIEW_REGISTRATION(GraphicDocShell);
}

GraphicViewShellBase::GraphicViewShellBase (
    SfxViewFrame* pFrame,
    SfxViewShell* pOldShell)
    : ViewShellBase (pFrame, pOldShell, ViewShell::ST_DRAW)
{
}

GraphicViewShellBase::~GraphicViewShellBase (void)
{
}

} // end of namespace sd

<commit_msg>INTEGRATION: CWS impress2 (1.2.26); FILE MERGED 2004/06/29 07:09:03 af 1.2.26.1: #i22705# Added LateInit() method where the ViewTabBar is deleted.<commit_after>/*************************************************************************
 *
 *  $RCSfile: GraphicViewShellBase.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2004-07-13 14:50:17 $
 *
 *  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 "GraphicViewShellBase.hxx"

#include "ViewTabBar.hxx"
#ifndef SD_RESID_HXX
#include "sdresid.hxx"
#endif
#ifndef SD_GRAPHIC_DOC_SHELL_HXX
#include "GraphicDocShell.hxx"
#endif
#include "strings.hrc"

namespace sd {

class DrawDocShell;

TYPEINIT1(GraphicViewShellBase, ViewShellBase);

// We have to expand the SFX_IMPL_VIEWFACTORY macro to call LateInit() after a
// new GraphicViewShellBase object has been constructed.

/*
SFX_IMPL_VIEWFACTORY(GraphicViewShellBase, SdResId(STR_DEFAULTVIEW))
{
    SFX_VIEW_REGISTRATION(GraphicDocShell);
}
*/
SfxViewFactory* GraphicViewShellBase::pFactory;
SfxViewShell* __EXPORT GraphicViewShellBase::CreateInstance (
    SfxViewFrame *pFrame, SfxViewShell *pOldView)
{
    GraphicViewShellBase* pBase = new GraphicViewShellBase(pFrame, pOldView);
    pBase->LateInit();
    return pBase;
}
void GraphicViewShellBase::RegisterFactory( USHORT nPrio )
{
    pFactory = new SfxViewFactory(
        &CreateInstance,&InitFactory,nPrio,SdResId(STR_DEFAULTVIEW));
    InitFactory();
}
void GraphicViewShellBase::InitFactory()
{
    SFX_VIEW_REGISTRATION(GraphicDocShell);
}

GraphicViewShellBase::GraphicViewShellBase (
    SfxViewFrame* pFrame,
    SfxViewShell* pOldShell)
    : ViewShellBase (pFrame, pOldShell, ViewShell::ST_DRAW)
{
}

void GraphicViewShellBase::LateInit (void)
{
    ViewShellBase::LateInit();
    // Turn the ViewTabBar off again.  It is not needed for Draw.
    mpViewTabBar.reset();
}

GraphicViewShellBase::~GraphicViewShellBase (void)
{
}

} // end of namespace sd

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2008-2011 The QXmpp developers
 *
 * Author:
 *  Jeremy Lainé
 *
 * Source:
 *  http://code.google.com/p/qxmpp
 *
 * This file is a part of QXmpp library.
 *
 * 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.
 *
 */

#include <cstdlib>
#include <iostream>

#include <QCoreApplication>
#include <QFile>
#include <QProcess>
#include <QRegExp>
#include <QTextStream>

#include "QXmppGlobal.h"

static void setField(QString &code, const QString &name, const QString &value)
{
    code.replace(
        QRegExp(QString("(%1\\s*=)[^\\r\\n]*").arg(name)),
        QString("\\1 %1").arg(value));
}

static void usage() {
    QTextStream output(stderr);
    output << "Usage:" << endl;
    output << "  doxyfilter              Generate documentation" << endl;
    output << "  doxyfilter -g           Generate Doxyfile" << endl;
    output << "  doxyfilter <sourcefile> Filter the given file's code" << endl;
}

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

    if (argc == 1)
        return QProcess::execute("doxygen");
    else if (argc != 2) {
        usage();
        return 1;
    }

    if (!strcmp(argv[1], "-g")) {
        // generate default Doxyfile
        QProcess process;
        process.start("doxygen", QStringList() << "-g" << "-");
        if (!process.waitForFinished()) {
            qWarning("Could not run doxygen");
            return 1;
        }
        QString code = QString::fromUtf8(process.readAll());

        // adjust Doxyfile
        setField(code, "ALPHABETICAL_INDEX", "NO");
        setField(code, "EXCLUDE_PATTERNS", "*/moc_*");
        setField(code, "FULL_PATH_NAMES", "NO");
        setField(code, "HIDE_UNDOC_CLASSES", "YES");
        setField(code, "GENERATE_LATEX", "NO");
        setField(code, "HTML_TIMESTAMP", "NO");
        setField(code, "INPUT", "../src");
        setField(code, "INPUT_FILTER", QString::fromLocal8Bit(argv[0]));
        setField(code, "PROJECT_NAME", "QXmpp");
        setField(code, "PROJECT_NUMBER", QString("%1.%2.%3").arg(
                QString::number((QXMPP_VERSION >> 16) & 0xff),
                QString::number((QXMPP_VERSION >> 8) & 0xff),
                QString::number(QXMPP_VERSION & 0xff)));

        // write doxyfile
        QFile output("Doxyfile");
        if (!output.open(QIODevice::WriteOnly)) {
            qWarning("Could not write to %s", qPrintable(output.fileName()));
            return 1;
        }
        output.write(code.toUtf8());
        output.close();

    } else if (!strcmp(argv[1], "-h")) {
        usage();
        return 0;
    } else {
        // read source code
        QFile source(QString::fromLocal8Bit(argv[1]));
        if (!source.open(QIODevice::ReadOnly)) {
            qWarning("Could not open %s", qPrintable(source.fileName()));
            return 1;
        }
        QString code = QString::fromUtf8(source.readAll());
        source.close();

        // add links for XEPs
        code.replace(QRegExp("(XEP-([0-9]{4}))"), "\\1");

        QTextStream output(stdout);
        output << code;
    }

    return 0;
}

<commit_msg>change format<commit_after>/*
 * Copyright (C) 2008-2011 The QXmpp developers
 *
 * Author:
 *  Jeremy Lainé
 *
 * Source:
 *  http://code.google.com/p/qxmpp
 *
 * This file is a part of QXmpp library.
 *
 * 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.
 *
 */

#include <cstdlib>
#include <iostream>

#include <QCoreApplication>
#include <QFile>
#include <QProcess>
#include <QRegExp>
#include <QTextStream>

#include "QXmppGlobal.h"

static void setField(QString &code, const QString &name, const QString &value)
{
    code.replace(
        QRegExp(QString("(%1\\s*=)[^\\r\\n]*").arg(name)),
        QString("\\1 %1").arg(value));
}

static void usage() {
    QTextStream output(stderr);
    output << "Usage:" << endl;
    output << "  doxyfilter              Generate documentation" << endl;
    output << "  doxyfilter -g           Generate Doxyfile" << endl;
    output << "  doxyfilter <sourcefile> Filter the given file's code" << endl;
}

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

    if (argc == 1)
        return QProcess::execute("doxygen");
    else if (argc != 2) {
        usage();
        return 1;
    }

    if (!strcmp(argv[1], "-g")) {
        // generate default Doxyfile
        QProcess process;
        process.start("doxygen", QStringList() << "-g" << "-");
        if (!process.waitForFinished()) {
            qWarning("Could not run doxygen");
            return 1;
        }
        QString code = QString::fromUtf8(process.readAll());

        // adjust Doxyfile
        setField(code, "ALPHABETICAL_INDEX", "NO");
        setField(code, "EXCLUDE_PATTERNS", "*/moc_*");
        setField(code, "FULL_PATH_NAMES", "NO");
        setField(code, "HIDE_UNDOC_CLASSES", "YES");
        setField(code, "GENERATE_LATEX", "NO");
        setField(code, "HTML_TIMESTAMP", "NO");
        setField(code, "INPUT", "../src");
        setField(code, "INPUT_FILTER", QString::fromLocal8Bit(argv[0]));
        setField(code, "PROJECT_NAME", "QXmpp");
        setField(code, "PROJECT_NUMBER", QString("Version: %1.%2.%3").arg(
                QString::number((QXMPP_VERSION >> 16) & 0xff),
                QString::number((QXMPP_VERSION >> 8) & 0xff),
                QString::number(QXMPP_VERSION & 0xff)));

        // write doxyfile
        QFile output("Doxyfile");
        if (!output.open(QIODevice::WriteOnly)) {
            qWarning("Could not write to %s", qPrintable(output.fileName()));
            return 1;
        }
        output.write(code.toUtf8());
        output.close();

    } else if (!strcmp(argv[1], "-h")) {
        usage();
        return 0;
    } else {
        // read source code
        QFile source(QString::fromLocal8Bit(argv[1]));
        if (!source.open(QIODevice::ReadOnly)) {
            qWarning("Could not open %s", qPrintable(source.fileName()));
            return 1;
        }
        QString code = QString::fromUtf8(source.readAll());
        source.close();

        // add links for XEPs
        code.replace(QRegExp("(XEP-([0-9]{4}))"), "\\1");

        QTextStream output(stdout);
        output << code;
    }

    return 0;
}

<|endoftext|>


<commit_before>/*
 * ======================================================================
 * Copyright (c) Microsoft Open Technologies, Inc.  All rights reserved.
 * Licensed under the MIT License.
 * See LICENSE.md in the project root for license information.
 * ======================================================================
 */

#ifdef QTFRAMEWORK
#include <QVariantMap>
#include <QMap>
#include <QJsonObject>
#include <QJsonDocument>

#include "JsonObjectQt.h"
#include "JsonArrayQt.h"
#include "JsonParserQt.h"

#include "../../ModernAPI/RMSExceptions.h"
#include "../Logger/Logger.h"

namespace rmscore {
namespace platform {
namespace json {
std::shared_ptr<IJsonObject>IJsonObject::Create()
{
  return std::make_shared<JsonObjectQt>();
}

bool JsonObjectQt::IsNull(const std::string& name)
{
  QJsonObject jo = this->impl_.toObject();

  return jo.contains(name.c_str())
         ? jo[name.c_str()].isNull()
         : throw exceptions::RMSInvalidArgumentException(
                 "JsonObjectQt::IsNull: Name doesn't exist");
}

std::shared_ptr<IJsonArray>JsonObjectQt::GetArray()
{
  if (!this->impl_.isArray())
  {
    throw exceptions::RMSInvalidArgumentException(
            "JsonObjectQt::GetArray: The object is not an array");
  }

  QJsonArray arr = this->impl_.toArray();

  return std::shared_ptr<IJsonArray>(new JsonArrayQt(arr));
}

bool JsonObjectQt::HasName(const std::string& name)
{
  QJsonObject jo = this->impl_.toObject();

  return jo.contains(name.c_str());
}

std::string JsonObjectQt::GetNamedString(const std::string& name,
                                         const std::string& defaultValue)
{
  QJsonObject jo = this->impl_.toObject();

  if (jo.contains(name.c_str()) && !jo[name.c_str()].isNull()) {
    auto obj = jo[name.c_str()];

    if (obj.isString()) {
      return obj.toString().toStdString();
    }

    throw exceptions::RMSInvalidArgumentException(
            "JsonObjectQt::GetNamedString: convertion error");
  }
  return defaultValue;
}

void JsonObjectQt::SetNamedString(const std::string& name,
                                  const std::string& value)
{
  QJsonObject jo = this->impl_.toObject();

  jo.insert(name.c_str(), QJsonValue(QString::fromStdString(value)));
  this->impl_ = QJsonValue(jo);
}

bool JsonObjectQt::GetNamedBool(const std::string& name, bool bDefaultValue)
{
  QJsonObject jo = this->impl_.toObject();

  return jo.contains(name.c_str())
         ? jo[name.c_str()].isBool()
         ? jo[name.c_str()].toBool()
         : throw exceptions::RMSInvalidArgumentException(
                 "JsonObjectQt::GetNamedBool: convertion error")
               : bDefaultValue;
}

void JsonObjectQt::SetNamedBool(const std::string& name, bool bValue)
{
  QJsonObject jo = this->impl_.toObject();

  jo.insert(name.c_str(), bValue);
  this->impl_ = QJsonValue(jo);
}

double JsonObjectQt::GetNamedNumber(const std::string& name, double fDefaultValue)
{
  QJsonObject jo = this->impl_.toObject();

  return jo.contains(name.c_str())
         ? jo[name.c_str()].isDouble()
         ? jo[name.c_str()].toDouble()
         : throw exceptions::RMSInvalidArgumentException(
                 "JsonObjectQt::GetNamedNumber: convertion error")
               : fDefaultValue;
}

void JsonObjectQt::SetNamedNumber(const std::string& name, double fValue)
{
  QJsonObject jo = this->impl_.toObject();

  jo.insert(name.c_str(), fValue);
  this->impl_ = QJsonValue(jo);
}

std::shared_ptr<IJsonObject>JsonObjectQt::GetNamedObject(const std::string& name)
{
  QJsonObject jo = this->impl_.toObject();

  if (!jo.contains(name.c_str()))
  {
    return nullptr;
  }

  QJsonValue val = jo.value(name.data());

  if (!val.isObject())
  {
    throw exceptions::RMSInvalidArgumentException(
            "JsonObjectQt::GetNamedObject: convertion error");
  }

  return std::make_shared<JsonObjectQt>(val);
}

void JsonObjectQt::SetNamedObject(const std::string& name,
                                  const IJsonObject& jsonObject)
{
  QJsonObject jo = this->impl_.toObject();
  auto other     = static_cast<const JsonObjectQt&>(jsonObject);

  jo.insert(name.c_str(), other.impl());
  this->impl_ = QJsonValue(jo);
}

std::shared_ptr<IJsonArray>JsonObjectQt::GetNamedArray(const std::string& name)
{
  QJsonObject jo = this->impl_.toObject();

  if (!jo.contains(name.c_str()))
  {
    return nullptr;
  }

  QJsonValue val = jo.value(name.data());

  if (!val.isArray())
  {
    throw exceptions::RMSInvalidArgumentException("the value is not an array");
  }

  return std::shared_ptr<JsonArrayQt>(new JsonArrayQt(val.toArray()));
}

void JsonObjectQt::SetNamedArray(const std::string& name,
                                 const IJsonArray & jsonArray)
{
  QJsonObject jo = this->impl_.toObject();
  auto other     = static_cast<const JsonArrayQt&>(jsonArray);

  jo.insert(name.c_str(), QJsonValue(other.impl()));
  this->impl_ = QJsonValue(jo);
}

void JsonObjectQt::SetNamedValue(const std::string      & name,
                                 const common::ByteArray& value) {
  QJsonObject jo = this->impl_.toObject();

  QVariant jsonVar(QByteArray(reinterpret_cast<const char *>(value.data()),
                              static_cast<int>(value.size())));

  jo.insert(name.c_str(), QJsonValue::fromVariant(jsonVar));
  this->impl_ = QJsonValue(jo);
}

common::ByteArray JsonObjectQt::GetNamedValue(const std::string& name)
{
  QJsonObject jo = this->impl_.toObject();
  auto nameStr   = name.c_str();
  auto ret       = jo.contains(nameStr)
                   ? jo[nameStr].isString()
                   ? jo[nameStr].toString().toUtf8()
                   : throw exceptions::RMSInvalidArgumentException(
                           "JsonObjectQt::GetNamedValue: convertion error")
                         : QByteArray();

  return common::ByteArray(ret.begin(), ret.end());
}

StringArray JsonObjectQt::GetNamedStringArray(const std::string& name)
{
  QJsonObject jo = this->impl_.toObject();

  if (!jo.contains(name.c_str()))
  {
    Logger::Warning(
      "JsonObjectQt::GetNamedStringArray: Can't find the key named '%s'",
      name.c_str());
    return std::vector<std::string>();
  }

  QJsonValue val = jo[name.c_str()];

  if (!val.isArray())
  {
    throw exceptions::RMSInvalidArgumentException("the value is not an array");
  }

  StringArray list;
  QJsonArray  arr = val.toArray();

  for (int i = 0; i < arr.size(); ++i)
  {
    QJsonValue val = arr[i];
    list.push_back(val.toString().toStdString());
  }

  return list;
}

modernapi::AppDataHashMap JsonObjectQt::ToStringDictionary()
{
  QVariantMap map =  this->impl_.toObject().toVariantMap();

  modernapi::AppDataHashMap result;

  for (QString& key : map.keys())
  {
    result.insert(std::make_pair(key.toStdString(),
                                 map[key].toString().toStdString()));
  }
  return result;
}

common::ByteArray JsonObjectQt::Stringify()
{
  QJsonDocument doc(this->impl_.toObject());

  auto res = doc.toJson(QJsonDocument::Compact);

  return common::ByteArray(res.begin(), res.end());
}
}
}
} // namespace rmscore { namespace platform { namespace json {
#endif // ifdef QTFRAMEWORK
<commit_msg>ERROR: UsageRestrictionsClient: Got an invalid json from the REST service. #35<commit_after>/*
 * ======================================================================
 * Copyright (c) Microsoft Open Technologies, Inc.  All rights reserved.
 * Licensed under the MIT License.
 * See LICENSE.md in the project root for license information.
 * ======================================================================
 */

#ifdef QTFRAMEWORK
#include <QVariantMap>
#include <QMap>
#include <QJsonObject>
#include <QJsonDocument>

#include "JsonObjectQt.h"
#include "JsonArrayQt.h"
#include "JsonParserQt.h"

#include "../../ModernAPI/RMSExceptions.h"
#include "../Logger/Logger.h"

namespace rmscore {
namespace platform {
namespace json {
std::shared_ptr<IJsonObject>IJsonObject::Create()
{
  return std::make_shared<JsonObjectQt>();
}

bool JsonObjectQt::IsNull(const std::string& name)
{
  QJsonObject jo = this->impl_.toObject();

  return jo.contains(name.c_str())
         ? jo[name.c_str()].isNull()
         : throw exceptions::RMSInvalidArgumentException(
                 "JsonObjectQt::IsNull: Name doesn't exist");
}

std::shared_ptr<IJsonArray>JsonObjectQt::GetArray()
{
  if (!this->impl_.isArray())
  {
    throw exceptions::RMSInvalidArgumentException(
            "JsonObjectQt::GetArray: The object is not an array");
  }

  QJsonArray arr = this->impl_.toArray();

  return std::shared_ptr<IJsonArray>(new JsonArrayQt(arr));
}

bool JsonObjectQt::HasName(const std::string& name)
{
  QJsonObject jo = this->impl_.toObject();

  return jo.contains(name.c_str());
}

std::string JsonObjectQt::GetNamedString(const std::string& name,
                                         const std::string& defaultValue)
{
  QJsonObject jo = this->impl_.toObject();

  if (jo.contains(name.c_str()) && !jo[name.c_str()].isNull()) {
    auto obj = jo[name.c_str()];

    if (obj.isString()) {
      return obj.toString().toStdString();
    }

    throw exceptions::RMSInvalidArgumentException(
            "JsonObjectQt::GetNamedString: convertion error");
  }
  return defaultValue;
}

void JsonObjectQt::SetNamedString(const std::string& name,
                                  const std::string& value)
{
  QJsonObject jo = this->impl_.toObject();

  jo.insert(name.c_str(), QJsonValue(QString::fromStdString(value)));
  this->impl_ = QJsonValue(jo);
}

bool JsonObjectQt::GetNamedBool(const std::string& name, bool bDefaultValue)
{
  QJsonObject jo = this->impl_.toObject();

  return jo.contains(name.c_str())
         ? jo[name.c_str()].isBool()
         ? jo[name.c_str()].toBool()
         : throw exceptions::RMSInvalidArgumentException(
                 "JsonObjectQt::GetNamedBool: convertion error")
               : bDefaultValue;
}

void JsonObjectQt::SetNamedBool(const std::string& name, bool bValue)
{
  QJsonObject jo = this->impl_.toObject();

  jo.insert(name.c_str(), bValue);
  this->impl_ = QJsonValue(jo);
}

double JsonObjectQt::GetNamedNumber(const std::string& name, double fDefaultValue)
{
  QJsonObject jo = this->impl_.toObject();

  if (jo.contains(name.c_str())) {
    auto joVal = jo[name.c_str()];

    if (!joVal.isNull()) {
      if (jo[name.c_str()].isDouble()) {
        return jo[name.c_str()].toDouble();
      } else {
        throw exceptions::RMSInvalidArgumentException(
                "JsonObjectQt::GetNamedNumber: convertion error");
      }
    }
  }
  return fDefaultValue;
}

void JsonObjectQt::SetNamedNumber(const std::string& name, double fValue)
{
  QJsonObject jo = this->impl_.toObject();

  jo.insert(name.c_str(), fValue);
  this->impl_ = QJsonValue(jo);
}

std::shared_ptr<IJsonObject>JsonObjectQt::GetNamedObject(const std::string& name)
{
  QJsonObject jo = this->impl_.toObject();

  if (!jo.contains(name.c_str()))
  {
    return nullptr;
  }

  QJsonValue val = jo.value(name.data());

  if (!val.isObject())
  {
    throw exceptions::RMSInvalidArgumentException(
            "JsonObjectQt::GetNamedObject: convertion error");
  }

  return std::make_shared<JsonObjectQt>(val);
}

void JsonObjectQt::SetNamedObject(const std::string& name,
                                  const IJsonObject& jsonObject)
{
  QJsonObject jo = this->impl_.toObject();
  auto other     = static_cast<const JsonObjectQt&>(jsonObject);

  jo.insert(name.c_str(), other.impl());
  this->impl_ = QJsonValue(jo);
}

std::shared_ptr<IJsonArray>JsonObjectQt::GetNamedArray(const std::string& name)
{
  QJsonObject jo = this->impl_.toObject();

  if (!jo.contains(name.c_str()))
  {
    return nullptr;
  }

  QJsonValue val = jo.value(name.data());

  if (!val.isArray())
  {
    throw exceptions::RMSInvalidArgumentException("the value is not an array");
  }

  return std::shared_ptr<JsonArrayQt>(new JsonArrayQt(val.toArray()));
}

void JsonObjectQt::SetNamedArray(const std::string& name,
                                 const IJsonArray & jsonArray)
{
  QJsonObject jo = this->impl_.toObject();
  auto other     = static_cast<const JsonArrayQt&>(jsonArray);

  jo.insert(name.c_str(), QJsonValue(other.impl()));
  this->impl_ = QJsonValue(jo);
}

void JsonObjectQt::SetNamedValue(const std::string      & name,
                                 const common::ByteArray& value) {
  QJsonObject jo = this->impl_.toObject();

  QVariant jsonVar(QByteArray(reinterpret_cast<const char *>(value.data()),
                              static_cast<int>(value.size())));

  jo.insert(name.c_str(), QJsonValue::fromVariant(jsonVar));
  this->impl_ = QJsonValue(jo);
}

common::ByteArray JsonObjectQt::GetNamedValue(const std::string& name)
{
  QJsonObject jo = this->impl_.toObject();
  auto nameStr   = name.c_str();
  auto ret       = jo.contains(nameStr)
                   ? jo[nameStr].isString()
                   ? jo[nameStr].toString().toUtf8()
                   : throw exceptions::RMSInvalidArgumentException(
                           "JsonObjectQt::GetNamedValue: convertion error")
                         : QByteArray();

  return common::ByteArray(ret.begin(), ret.end());
}

StringArray JsonObjectQt::GetNamedStringArray(const std::string& name)
{
  QJsonObject jo = this->impl_.toObject();

  if (!jo.contains(name.c_str()))
  {
    Logger::Warning(
      "JsonObjectQt::GetNamedStringArray: Can't find the key named '%s'",
      name.c_str());
    return std::vector<std::string>();
  }

  QJsonValue val = jo[name.c_str()];

  if (!val.isArray())
  {
    throw exceptions::RMSInvalidArgumentException("the value is not an array");
  }

  StringArray list;
  QJsonArray  arr = val.toArray();

  for (int i = 0; i < arr.size(); ++i)
  {
    QJsonValue val = arr[i];
    list.push_back(val.toString().toStdString());
  }

  return list;
}

modernapi::AppDataHashMap JsonObjectQt::ToStringDictionary()
{
  QVariantMap map =  this->impl_.toObject().toVariantMap();

  modernapi::AppDataHashMap result;

  for (QString& key : map.keys())
  {
    result.insert(std::make_pair(key.toStdString(),
                                 map[key].toString().toStdString()));
  }
  return result;
}

common::ByteArray JsonObjectQt::Stringify()
{
  QJsonDocument doc(this->impl_.toObject());

  auto res = doc.toJson(QJsonDocument::Compact);

  return common::ByteArray(res.begin(), res.end());
}
}
}
} // namespace rmscore { namespace platform { namespace json {
#endif // ifdef QTFRAMEWORK
<|endoftext|>


<commit_before><commit_msg>fix bug: texblends uninitialized value transported.<commit_after><|endoftext|>