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

#ifndef CONFIGMGR_API_SVCCOMPONENT_HXX_
#define CONFIGMGR_API_SVCCOMPONENT_HXX_

#ifndef CONFIGMGR_SERVICEINFOHELPER_HXX_
#include "serviceinfohelper.hxx"
#endif

#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif

#ifndef _CPPUHELPER_COMPBASE1_HXX_
#include <cppuhelper/compbase1.hxx>
#endif
#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
#include <cppuhelper/typeprovider.hxx>
#endif

#ifndef _OSL_MUTEX_HXX_
#include <osl/Mutex.hxx>
#endif
#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

namespace configmgr
{

//----------------------------------------------------------------------------
    namespace css   = ::com::sun::star;
    namespace uno   = css::uno;
    namespace lang  = css::lang;
    using ::rtl::OUString;

//----------------------------------------------------------------------------
    typedef ::cppu::WeakComponentImplHelper1< lang::XServiceInfo > ServiceImplBase;

//----------------------------------------------------------------------------
    class ServiceComponentImpl
        : public ServiceImplBase
    {
    protected:
        ServiceImplementationInfo const*const     m_info;
    public:
        ServiceComponentImpl(ServiceImplementationInfo const* aInfo);

        // XTypeProvider
        virtual uno::Sequence<sal_Int8> SAL_CALL getImplementationId(  ) throw(uno::RuntimeException);
        //virtual uno::Sequence<uno::Type> SAL_CALL getTypes(  ) throw(uno::RuntimeException) = 0;

        // XServiceInfo
        virtual OUString SAL_CALL getImplementationName(  ) throw(uno::RuntimeException);
        virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(uno::RuntimeException);
        virtual uno::Sequence< OUString > SAL_CALL getSupportedServiceNames(  ) throw(uno::RuntimeException);

        // Component Helper - force override
        virtual void SAL_CALL disposing() = 0;
        // Component Helper - check object state
        virtual void checkAlive() throw (uno::RuntimeException);
        void checkAlive(char const* message) throw (uno::RuntimeException)
            { checkAlive( OUString::createFromAscii(message) ); }
        void checkAlive(OUString const& message) throw (uno::RuntimeException);

        // Extra helpers
        static uno::Sequence<sal_Int8> getStaticImplementationId(ServiceImplementationInfo const* pServiceInfo) throw(uno::RuntimeException);

    private: // no implementation
        ServiceComponentImpl(ServiceComponentImpl&);
        void operator=(ServiceComponentImpl&);
    };
//----------------------------------------------------------------------------

} // namespace configmgr

#endif // CONFIGMGR_API_SVCCOMPONENT_HXX_

<commit_msg>INTEGRATION: CWS changefileheader (1.5.16); FILE MERGED 2008/04/01 15:06:43 thb 1.5.16.3: #i85898# Stripping all external header guards 2008/04/01 12:27:23 thb 1.5.16.2: #i85898# Stripping all external header guards 2008/03/31 12:22:43 rt 1.5.16.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: confsvccomponent.hxx,v $
 * $Revision: 1.6 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef CONFIGMGR_API_SVCCOMPONENT_HXX_
#define CONFIGMGR_API_SVCCOMPONENT_HXX_

#include "serviceinfohelper.hxx"
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <cppuhelper/compbase1.hxx>
#include <cppuhelper/typeprovider.hxx>

#ifndef _OSL_MUTEX_HXX_
#include <osl/Mutex.hxx>
#endif
#include <rtl/ustring.hxx>

namespace configmgr
{

//----------------------------------------------------------------------------
    namespace css   = ::com::sun::star;
    namespace uno   = css::uno;
    namespace lang  = css::lang;
    using ::rtl::OUString;

//----------------------------------------------------------------------------
    typedef ::cppu::WeakComponentImplHelper1< lang::XServiceInfo > ServiceImplBase;

//----------------------------------------------------------------------------
    class ServiceComponentImpl
        : public ServiceImplBase
    {
    protected:
        ServiceImplementationInfo const*const     m_info;
    public:
        ServiceComponentImpl(ServiceImplementationInfo const* aInfo);

        // XTypeProvider
        virtual uno::Sequence<sal_Int8> SAL_CALL getImplementationId(  ) throw(uno::RuntimeException);
        //virtual uno::Sequence<uno::Type> SAL_CALL getTypes(  ) throw(uno::RuntimeException) = 0;

        // XServiceInfo
        virtual OUString SAL_CALL getImplementationName(  ) throw(uno::RuntimeException);
        virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw(uno::RuntimeException);
        virtual uno::Sequence< OUString > SAL_CALL getSupportedServiceNames(  ) throw(uno::RuntimeException);

        // Component Helper - force override
        virtual void SAL_CALL disposing() = 0;
        // Component Helper - check object state
        virtual void checkAlive() throw (uno::RuntimeException);
        void checkAlive(char const* message) throw (uno::RuntimeException)
            { checkAlive( OUString::createFromAscii(message) ); }
        void checkAlive(OUString const& message) throw (uno::RuntimeException);

        // Extra helpers
        static uno::Sequence<sal_Int8> getStaticImplementationId(ServiceImplementationInfo const* pServiceInfo) throw(uno::RuntimeException);

    private: // no implementation
        ServiceComponentImpl(ServiceComponentImpl&);
        void operator=(ServiceComponentImpl&);
    };
//----------------------------------------------------------------------------

} // namespace configmgr

#endif // CONFIGMGR_API_SVCCOMPONENT_HXX_

<|endoftext|>


<commit_before>//---------------------------------------------------------- -*- Mode: C++ -*-
// $Id$
//
// Created 2012/08/22
// Author: Mike Ovsiannikov
//
// Copyright 2012,2016 Quantcast Corporation. All rights reserved.
//
// This file is part of Kosmos File System (KFS).
//
// 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.
//
//
// \file KfsAttr.cc
// \brief Kfs i-node attributes class.
//
//----------------------------------------------------------------------------

#include "KfsAttr.h"

#include <string.h>
#include <stdlib.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

namespace KFS {
namespace client {

void
FileAttr::ToStat(
    struct stat& outStat) const
{
    memset(&outStat, 0, sizeof(outStat));
    outStat.st_ino = fileId;
    // Directories are drwxrwxrwx, files are drw-rw-rw-
    if (isDirectory) {
        outStat.st_mode = S_IFDIR | (mode_t)((mode == kKfsModeUndef ?
            (kfsMode_t)0777 : mode) & 0777);
        outStat.st_size = 0;
    } else {
        outStat.st_mode = S_IFREG | (mode_t)((mode == kKfsModeUndef ?
            (kfsMode_t)0666 : mode) & 0777);
        outStat.st_size = fileSize;
    }
#ifdef S_ISVTX
    if (IsSticky()) {
        outStat.st_mode |= S_ISVTX;
    }
#endif
    outStat.st_blksize = CHUNKSIZE;
    outStat.st_blocks  = chunkCount();
    outStat.st_uid     = (uid_t)user;
    outStat.st_gid     = (gid_t)group;
#ifdef KFS_OS_NAME_DARWIN
    outStat.st_atimespec.tv_sec  = crtime.tv_sec;
    outStat.st_atimespec.tv_nsec = crtime.tv_usec * 1000;
    outStat.st_mtimespec.tv_sec  = mtime.tv_sec;
    outStat.st_mtimespec.tv_nsec = mtime.tv_usec * 1000;
    outStat.st_ctimespec.tv_sec  = ctime.tv_sec;
    outStat.st_ctimespec.tv_nsec = ctime.tv_usec * 1000;
#else
    outStat.st_atime = crtime.tv_sec;
    outStat.st_mtime = mtime.tv_sec;
    outStat.st_ctime = ctime.tv_sec;
#endif
}

}}

<commit_msg>Client library: take into the account replication in QFS attribute to stat conversions when reporting number of blocks.<commit_after>//---------------------------------------------------------- -*- Mode: C++ -*-
// $Id$
//
// Created 2012/08/22
// Author: Mike Ovsiannikov
//
// Copyright 2012,2016 Quantcast Corporation. All rights reserved.
//
// This file is part of Kosmos File System (KFS).
//
// 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.
//
//
// \file KfsAttr.cc
// \brief Kfs i-node attributes class.
//
//----------------------------------------------------------------------------

#include "KfsAttr.h"

#include <string.h>
#include <stdlib.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

namespace KFS {
namespace client {

void
FileAttr::ToStat(
    struct stat& outStat) const
{
    memset(&outStat, 0, sizeof(outStat));
    outStat.st_ino = fileId;
    // Directories are drwxrwxrwx, files are drw-rw-rw-
    if (isDirectory) {
        outStat.st_mode = S_IFDIR | (mode_t)((mode == kKfsModeUndef ?
            (kfsMode_t)0777 : mode) & 0777);
        outStat.st_size = 0;
    } else {
        outStat.st_mode = S_IFREG | (mode_t)((mode == kKfsModeUndef ?
            (kfsMode_t)0666 : mode) & 0777);
        outStat.st_size = fileSize;
    }
#ifdef S_ISVTX
    if (IsSticky()) {
        outStat.st_mode |= S_ISVTX;
    }
#endif
    outStat.st_blksize = CHUNKSIZE;
    outStat.st_blocks  = chunkCount();
    if (0 < numReplicas) {
    	outStat.st_blocks *= numReplicas;
    }
    outStat.st_uid     = (uid_t)user;
    outStat.st_gid     = (gid_t)group;
#ifdef KFS_OS_NAME_DARWIN
    outStat.st_atimespec.tv_sec  = crtime.tv_sec;
    outStat.st_atimespec.tv_nsec = crtime.tv_usec * 1000;
    outStat.st_mtimespec.tv_sec  = mtime.tv_sec;
    outStat.st_mtimespec.tv_nsec = mtime.tv_usec * 1000;
    outStat.st_ctimespec.tv_sec  = ctime.tv_sec;
    outStat.st_ctimespec.tv_nsec = ctime.tv_usec * 1000;
#else
    outStat.st_atime = crtime.tv_sec;
    outStat.st_mtime = mtime.tv_sec;
    outStat.st_ctime = ctime.tv_sec;
#endif
}

}}

<|endoftext|>


<commit_before>#include "auto-wrap.h"
#include "text-buffer.h"
#include <emscripten/bind.h>

using std::string;
using std::u16string;

static TextBuffer *construct(const std::string &text) {
  return new TextBuffer(u16string(text.begin(), text.end()));
}

static emscripten::val search_sync(TextBuffer &buffer, std::string js_pattern) {
  u16string pattern(js_pattern.begin(), js_pattern.end());
  u16string error_message;
  Regex regex(pattern, &error_message);
  if (!error_message.empty()) {
    return emscripten::val(string(error_message.begin(), error_message.end()));
  }

  auto result = buffer.search(regex);
  if (result) {
    return emscripten::val(*result);
  }

  return emscripten::val::null();
}

static emscripten::val line_ending_for_row(TextBuffer &buffer, uint32_t row) {
  auto line_ending = buffer.line_ending_for_row(row);
  if (line_ending) {
    string result;
    for (const uint16_t *character = line_ending; *character != 0; character++) {
      result += (char)*character;
    }
    return emscripten::val(result);
  }
  return emscripten::val::undefined();
}

static uint32_t character_index_for_position(TextBuffer &buffer, Point position) {
  return buffer.clip_position(position).offset;
}

static Point position_for_character_index(TextBuffer &buffer, long index) {
  return index < 0 ?
    Point{0, 0} :
    buffer.position_for_offset(static_cast<uint32_t>(index));
}

EMSCRIPTEN_BINDINGS(TextBuffer) {
  emscripten::class_<TextBuffer>("TextBuffer")
    .constructor<>()
    .constructor(construct, emscripten::allow_raw_pointers())
    .function("getText", WRAP(&TextBuffer::text))
    .function("setText", WRAP_OVERLOAD(&TextBuffer::set_text, void (TextBuffer::*)(Text::String &&)))
    .function("getTextInRange", WRAP(&TextBuffer::text_in_range))
    .function("setTextInRange", WRAP_OVERLOAD(&TextBuffer::set_text_in_range, void (TextBuffer::*)(Range, Text::String &&)))
    .function("getLength", &TextBuffer::size)
    .function("getExtent", &TextBuffer::extent)
    .function("reset", WRAP(&TextBuffer::reset))
    .function("lineLengthForRow", WRAP(&TextBuffer::line_length_for_row))
    .function("lineEndingForRow", line_ending_for_row)
    .function("lineForRow", WRAP(&TextBuffer::line_for_row))
    .function("characterIndexForPosition", character_index_for_position)
    .function("positionForCharacterIndex", position_for_character_index)
    .function("isModified", &TextBuffer::is_modified)
    .function("searchSync", search_sync);
}
<commit_msg>Specify overload in emscripten binding for isModified<commit_after>#include "auto-wrap.h"
#include "text-buffer.h"
#include <emscripten/bind.h>

using std::string;
using std::u16string;

static TextBuffer *construct(const std::string &text) {
  return new TextBuffer(u16string(text.begin(), text.end()));
}

static emscripten::val search_sync(TextBuffer &buffer, std::string js_pattern) {
  u16string pattern(js_pattern.begin(), js_pattern.end());
  u16string error_message;
  Regex regex(pattern, &error_message);
  if (!error_message.empty()) {
    return emscripten::val(string(error_message.begin(), error_message.end()));
  }

  auto result = buffer.search(regex);
  if (result) {
    return emscripten::val(*result);
  }

  return emscripten::val::null();
}

static emscripten::val line_ending_for_row(TextBuffer &buffer, uint32_t row) {
  auto line_ending = buffer.line_ending_for_row(row);
  if (line_ending) {
    string result;
    for (const uint16_t *character = line_ending; *character != 0; character++) {
      result += (char)*character;
    }
    return emscripten::val(result);
  }
  return emscripten::val::undefined();
}

static uint32_t character_index_for_position(TextBuffer &buffer, Point position) {
  return buffer.clip_position(position).offset;
}

static Point position_for_character_index(TextBuffer &buffer, long index) {
  return index < 0 ?
    Point{0, 0} :
    buffer.position_for_offset(static_cast<uint32_t>(index));
}

EMSCRIPTEN_BINDINGS(TextBuffer) {
  emscripten::class_<TextBuffer>("TextBuffer")
    .constructor<>()
    .constructor(construct, emscripten::allow_raw_pointers())
    .function("getText", WRAP(&TextBuffer::text))
    .function("setText", WRAP_OVERLOAD(&TextBuffer::set_text, void (TextBuffer::*)(Text::String &&)))
    .function("getTextInRange", WRAP(&TextBuffer::text_in_range))
    .function("setTextInRange", WRAP_OVERLOAD(&TextBuffer::set_text_in_range, void (TextBuffer::*)(Range, Text::String &&)))
    .function("getLength", &TextBuffer::size)
    .function("getExtent", &TextBuffer::extent)
    .function("reset", WRAP(&TextBuffer::reset))
    .function("lineLengthForRow", WRAP(&TextBuffer::line_length_for_row))
    .function("lineEndingForRow", line_ending_for_row)
    .function("lineForRow", WRAP(&TextBuffer::line_for_row))
    .function("characterIndexForPosition", character_index_for_position)
    .function("positionForCharacterIndex", position_for_character_index)
    .function("isModified", WRAP_OVERLOAD(&TextBuffer::is_modified, bool (TextBuffer::*)() const))
    .function("searchSync", search_sync);
}
<|endoftext|>


<commit_before>#pragma once

#include <mutex>

#include <boost/thread.hpp>

#include "blackhole/forwards.hpp"
#include "blackhole/logger.hpp"

namespace blackhole {

template<class Logger, class Mutex>
class synchronized {
public:
    typedef Logger logger_type;
    typedef Mutex mutex_type;

private:
    logger_type log;
    mutable mutex_type mutex;

    friend class scoped_attributes_t;

public:
    synchronized() {}

    explicit synchronized(logger_type&& logger) :
        log(std::move(logger))
    {}

    synchronized(synchronized&& other) {
        *this = std::move(other);
    }

    synchronized& operator=(synchronized&& other) {
        //! @compat GCC4.4
        //! GCC4.4 doesn't implement `std::lock` as like as `std::adopt_lock`.
        boost::lock(mutex, other.mutex);
        boost::lock_guard<mutex_type> lock(mutex, boost::adopt_lock);
        boost::lock_guard<mutex_type> other_lock(other.mutex, boost::adopt_lock);
        log = std::move(other.log);
        return *this;
    }

    bool enabled() const {
        std::lock_guard<mutex_type> lock(mutex);
        return log.enabled();
    }

    void enable() {
        std::lock_guard<mutex_type> lock(mutex);
        log.enable();
    }

    void disable() {
        std::lock_guard<mutex_type> lock(mutex);
        log.disable();
    }

    void set_filter(filter_t&& filter) {
        std::lock_guard<mutex_type> lock(mutex);
        log.set_filter(std::move(filter));
    }

    void add_attribute(const log::attribute_pair_t& attr) {
        std::lock_guard<mutex_type> lock(mutex);
        log.add_attribute(attr);
    }

    void add_frontend(std::unique_ptr<base_frontend_t> frontend) {
        std::lock_guard<mutex_type> lock(mutex);
        log.add_frontend(std::move(frontend));
    }

    void set_exception_handler(log::exception_handler_t&& handler) {
        std::lock_guard<mutex_type> lock(mutex);
        log.set_exception_handler(std::move(handler));
    }

    template<typename... Args>
    log::record_t open_record(Args&&... args) const {
        std::lock_guard<mutex_type> lock(mutex);
        return log.open_record(std::forward<Args>(args)...);
    }

    void push(log::record_t&& record) const {
        std::lock_guard<mutex_type> lock(mutex);
        log.push(std::move(record));
    }

    template<typename Level>
    typename std::enable_if<
        std::is_same<
            logger_type,
            verbose_logger_t<Level>
        >::value,
        Level
    >::type
    verbosity() const {
        std::lock_guard<mutex_type> lock(mutex);
        return log.verbosity();
    }

    template<typename Level>
    typename std::enable_if<
        std::is_same<
            logger_type,
            verbose_logger_t<Level>
        >::value
    >::type
    verbosity(Level level) {
        std::lock_guard<mutex_type> lock(mutex);
        return log.verbosity(level);
    }
};

} // namespace blackhole
<commit_msg>[API] Synchronized wrapper now provides reference to its underlying logger.<commit_after>#pragma once

#include <mutex>

#include <boost/thread.hpp>

#include "blackhole/forwards.hpp"
#include "blackhole/logger.hpp"

namespace blackhole {

template<class Logger, class Mutex>
class synchronized {
public:
    typedef Logger logger_type;
    typedef Mutex mutex_type;

private:
    logger_type log_;
    mutable mutex_type mutex;

    friend class scoped_attributes_t;

public:
    synchronized() {}

    explicit synchronized(logger_type&& logger) :
        log_(std::move(logger))
    {}

    synchronized(synchronized&& other) {
        *this = std::move(other);
    }

    synchronized& operator=(synchronized&& other) {
        //! @compat GCC4.4
        //! GCC4.4 doesn't implement `std::lock` as like as `std::adopt_lock`.
        boost::lock(mutex, other.mutex);
        boost::lock_guard<mutex_type> lock(mutex, boost::adopt_lock);
        boost::lock_guard<mutex_type> other_lock(other.mutex, boost::adopt_lock);
        log_ = std::move(other.log_);
        return *this;
    }

    logger_type& log() {
        return log_;
    }

    bool enabled() const {
        std::lock_guard<mutex_type> lock(mutex);
        return log_.enabled();
    }

    void enable() {
        std::lock_guard<mutex_type> lock(mutex);
        log_.enable();
    }

    void disable() {
        std::lock_guard<mutex_type> lock(mutex);
        log_.disable();
    }

    void set_filter(filter_t&& filter) {
        std::lock_guard<mutex_type> lock(mutex);
        log_.set_filter(std::move(filter));
    }

    void add_attribute(const log::attribute_pair_t& attr) {
        std::lock_guard<mutex_type> lock(mutex);
        log_.add_attribute(attr);
    }

    void add_frontend(std::unique_ptr<base_frontend_t> frontend) {
        std::lock_guard<mutex_type> lock(mutex);
        log_.add_frontend(std::move(frontend));
    }

    void set_exception_handler(log::exception_handler_t&& handler) {
        std::lock_guard<mutex_type> lock(mutex);
        log_.set_exception_handler(std::move(handler));
    }

    template<typename... Args>
    log::record_t open_record(Args&&... args) const {
        std::lock_guard<mutex_type> lock(mutex);
        return log_.open_record(std::forward<Args>(args)...);
    }

    void push(log::record_t&& record) const {
        std::lock_guard<mutex_type> lock(mutex);
        log_.push(std::move(record));
    }

    template<typename Level>
    typename std::enable_if<
        std::is_same<
            logger_type,
            verbose_logger_t<Level>
        >::value,
        Level
    >::type
    verbosity() const {
        std::lock_guard<mutex_type> lock(mutex);
        return log_.verbosity();
    }

    template<typename Level>
    typename std::enable_if<
        std::is_same<
            logger_type,
            verbose_logger_t<Level>
        >::value
    >::type
    verbosity(Level level) {
        std::lock_guard<mutex_type> lock(mutex);
        return log_.verbosity(level);
    }
};

} // namespace blackhole
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: AView.cxx,v $
 *
 *  $Revision: 1.16 $
 *
 *  last change: $Author: vg $ $Date: 2007-03-26 13:58:49 $
 *
 *  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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_connectivity.hxx"
#ifndef _CONNECTIVITY_ADO_VIEW_HXX_
#include "ado/AView.hxx"
#endif
#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
#include <com/sun/star/lang/DisposedException.hpp>
#endif
#ifndef _CONNECTIVITY_ADO_ADOIMP_HXX_
#include "ado/adoimp.hxx"
#endif
#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
#include <cppuhelper/typeprovider.hxx>
#endif
#ifndef _CONNECTIVITY_ADO_AWRAPADO_HXX_
#include "ado/Awrapado.hxx"
#endif
#ifndef _COMPHELPER_SEQUENCE_HXX_
#include <comphelper/sequence.hxx>
#endif
#ifndef _COMPHELPER_TYPES_HXX_
#include <comphelper/types.hxx>
#endif
#ifndef CONNECTIVITY_CONNECTION_HXX
#include "TConnection.hxx"
#endif

// -------------------------------------------------------------------------
using namespace comphelper;
using namespace connectivity::ado;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::beans;
using namespace com::sun::star::sdbc;

//  IMPLEMENT_SERVICE_INFO(OAdoView,"com.sun.star.sdbcx.AView","com.sun.star.sdbcx.View");
// -------------------------------------------------------------------------
OAdoView::OAdoView(sal_Bool _bCase,ADOView* _pView) : OView_ADO(_bCase,NULL)
,m_aView(_pView)
{
}
//--------------------------------------------------------------------------
Sequence< sal_Int8 > OAdoView::getUnoTunnelImplementationId()
{
    static ::cppu::OImplementationId * pId = 0;
    if (! pId)
    {
        ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
        if (! pId)
        {
            static ::cppu::OImplementationId aId;
            pId = &aId;
        }
    }
    return pId->getImplementationId();
}

// com::sun::star::lang::XUnoTunnel
//------------------------------------------------------------------
sal_Int64 OAdoView::getSomething( const Sequence< sal_Int8 > & rId ) throw (RuntimeException)
{
    return (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(),  rId.getConstArray(), 16 ) )
                ? reinterpret_cast< sal_Int64 >( this )
                : OView_ADO::getSomething(rId);
}

// -------------------------------------------------------------------------
void OAdoView::getFastPropertyValue(Any& rValue,sal_Int32 nHandle) const
{
    if(m_aView.IsValid())
    {
        switch(nHandle)
        {
            case PROPERTY_ID_NAME:
                rValue <<= m_aView.get_Name();
                break;
            case PROPERTY_ID_CATALOGNAME:
                break;
            case PROPERTY_ID_SCHEMANAME:
                //  rValue <<= m_aView.get_Type();
                break;
            case PROPERTY_ID_COMMAND:
                {
                    OLEVariant aVar;
                    m_aView.get_Command(aVar);
                    if(!aVar.isNull() && !aVar.isEmpty())
                    {
                        ADOCommand* pCom = (ADOCommand*)aVar.getIDispatch();
                        OLEString aBSTR;
                        pCom->get_CommandText(&aBSTR);
                        rValue <<= (::rtl::OUString) aBSTR;
                    }
                }
                break;
        }
    }
    else
        OView_ADO::getFastPropertyValue(rValue,nHandle);
}
// -----------------------------------------------------------------------------
void SAL_CALL OAdoView::acquire() throw()
{
    OView_ADO::acquire();
}
// -----------------------------------------------------------------------------
void SAL_CALL OAdoView::release() throw()
{
    OView_ADO::release();
}
// -----------------------------------------------------------------------------

<commit_msg>INTEGRATION: CWS changefileheader (1.16.144); FILE MERGED 2008/04/01 15:08:37 thb 1.16.144.3: #i85898# Stripping all external header guards 2008/04/01 10:52:50 thb 1.16.144.2: #i85898# Stripping all external header guards 2008/03/28 15:23:27 rt 1.16.144.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: AView.cxx,v $
 * $Revision: 1.17 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_connectivity.hxx"
#include "ado/AView.hxx"
#include <com/sun/star/lang/DisposedException.hpp>
#include "ado/adoimp.hxx"
#include <cppuhelper/typeprovider.hxx>
#include "ado/Awrapado.hxx"
#include <comphelper/sequence.hxx>
#include <comphelper/types.hxx>
#include "TConnection.hxx"

// -------------------------------------------------------------------------
using namespace comphelper;
using namespace connectivity::ado;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::beans;
using namespace com::sun::star::sdbc;

//  IMPLEMENT_SERVICE_INFO(OAdoView,"com.sun.star.sdbcx.AView","com.sun.star.sdbcx.View");
// -------------------------------------------------------------------------
OAdoView::OAdoView(sal_Bool _bCase,ADOView* _pView) : OView_ADO(_bCase,NULL)
,m_aView(_pView)
{
}
//--------------------------------------------------------------------------
Sequence< sal_Int8 > OAdoView::getUnoTunnelImplementationId()
{
    static ::cppu::OImplementationId * pId = 0;
    if (! pId)
    {
        ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
        if (! pId)
        {
            static ::cppu::OImplementationId aId;
            pId = &aId;
        }
    }
    return pId->getImplementationId();
}

// com::sun::star::lang::XUnoTunnel
//------------------------------------------------------------------
sal_Int64 OAdoView::getSomething( const Sequence< sal_Int8 > & rId ) throw (RuntimeException)
{
    return (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(),  rId.getConstArray(), 16 ) )
                ? reinterpret_cast< sal_Int64 >( this )
                : OView_ADO::getSomething(rId);
}

// -------------------------------------------------------------------------
void OAdoView::getFastPropertyValue(Any& rValue,sal_Int32 nHandle) const
{
    if(m_aView.IsValid())
    {
        switch(nHandle)
        {
            case PROPERTY_ID_NAME:
                rValue <<= m_aView.get_Name();
                break;
            case PROPERTY_ID_CATALOGNAME:
                break;
            case PROPERTY_ID_SCHEMANAME:
                //  rValue <<= m_aView.get_Type();
                break;
            case PROPERTY_ID_COMMAND:
                {
                    OLEVariant aVar;
                    m_aView.get_Command(aVar);
                    if(!aVar.isNull() && !aVar.isEmpty())
                    {
                        ADOCommand* pCom = (ADOCommand*)aVar.getIDispatch();
                        OLEString aBSTR;
                        pCom->get_CommandText(&aBSTR);
                        rValue <<= (::rtl::OUString) aBSTR;
                    }
                }
                break;
        }
    }
    else
        OView_ADO::getFastPropertyValue(rValue,nHandle);
}
// -----------------------------------------------------------------------------
void SAL_CALL OAdoView::acquire() throw()
{
    OView_ADO::acquire();
}
// -----------------------------------------------------------------------------
void SAL_CALL OAdoView::release() throw()
{
    OView_ADO::release();
}
// -----------------------------------------------------------------------------

<|endoftext|>


<commit_before>#include "meshoptimizer.h"

#include <cassert>

#include <vector>

namespace meshopt
{

static unsigned int findStripFirst(const unsigned int buffer[][3], unsigned int buffer_size, const unsigned int* valence)
{
	unsigned int index = 0;
	unsigned int iv = ~0u;

	for (unsigned int i = 0; i < buffer_size; ++i)
	{
		unsigned int va = valence[buffer[i][0]], vb = valence[buffer[i][1]], vc = valence[buffer[i][2]];
		unsigned int v = (va < vb && va < vc) ? va : (vb < vc) ? vb : vc;

		if (v < iv)
		{
			index = i;
			iv = v;
		}
	}

	return index;
}

static int findStripNext(const unsigned int buffer[][3], unsigned int buffer_size, unsigned int e0, unsigned int e1)
{
	for (unsigned int i = 0; i < buffer_size; ++i)
	{
		unsigned int a = buffer[i][0], b = buffer[i][1], c = buffer[i][2];

		if (e0 == a && e1 == b)
			return (i << 2) | 2;
		else if (e0 == b && e1 == c)
			return (i << 2) | 0;
		else if (e0 == c && e1 == a)
			return (i << 2) | 1;
	}

	return -1;
}

} // namespace meshopt

size_t meshopt_stripify(unsigned int* destination, const unsigned int* indices, size_t index_count, size_t vertex_count)
{
	assert(destination != indices);
	assert(index_count % 3 == 0);

	using namespace meshopt;

	const size_t buffer_capacity = 8;

	unsigned int buffer[buffer_capacity][3] = {};
	unsigned int buffer_size = 0;

	size_t index_offset = 0;

	unsigned int strip[2] = {};
	unsigned int parity = 0;

	size_t strip_size = 0;

	// compute vertex valence; this is used to prioritize starting triangle for strips
	std::vector<unsigned int> valence(vertex_count, 0);

	for (size_t i = 0; i < index_count; ++i)
	{
		unsigned int index = indices[i];
		assert(index < vertex_count);

		valence[index]++;
	}

	int next = -1;

	while (buffer_size > 0 || index_offset < index_count)
	{
		assert(next < 0 || (size_t(next >> 2) < buffer_size && (next & 3) < 3));

		// fill triangle buffer
		while (buffer_size < buffer_capacity && index_offset < index_count)
		{
			buffer[buffer_size][0] = indices[index_offset + 0];
			buffer[buffer_size][1] = indices[index_offset + 1];
			buffer[buffer_size][2] = indices[index_offset + 2];

			buffer_size++;
			index_offset += 3;
		}

		assert(buffer_size > 0);

		if (next >= 0)
		{
			unsigned int i = next >> 2;
			unsigned int a = buffer[i][0], b = buffer[i][1], c = buffer[i][2];
			unsigned int v = buffer[i][next & 3];

			// unordered removal from the buffer
			buffer[i][0] = buffer[buffer_size - 1][0];
			buffer[i][1] = buffer[buffer_size - 1][1];
			buffer[i][2] = buffer[buffer_size - 1][2];
			buffer_size--;

			// update vertex valences for strip start heuristic
			valence[a]--;
			valence[b]--;
			valence[c]--;

			// find next triangle (note that edge order flips on every iteration)
			// in some cases we need to perform a swap to pick a different outgoing triangle edge
			// for [a b c], the default strip edge is [b c], but we might want to use [a c]
			int cont = findStripNext(buffer, buffer_size, parity ? strip[1] : v, parity ? v : strip[1]);
			int swap = cont < 0 ? findStripNext(buffer, buffer_size, parity ? v : strip[0], parity ? strip[0] : v) : -1;

			if (cont < 0 && swap >= 0)
			{
				// [a b c] => [a b a c]
				destination[strip_size++] = strip[0];
				destination[strip_size++] = v;

				// next strip has same winding
				// ? a b => b a v
				strip[1] = v;

				next = swap;
			}
			else
			{
				// emit the next vertex in the strip
				destination[strip_size++] = v;

				// next strip has flipped winding
				strip[0] = strip[1];
				strip[1] = v;
				parity ^= 1;

				next = cont;
			}
		}
		else
		{
			// if we didn't find anything, we need to find the next new triangle
			// we use a heuristic to maximize the strip length
			unsigned int i = findStripFirst(buffer, buffer_size, &valence[0]);
			unsigned int a = buffer[i][0], b = buffer[i][1], c = buffer[i][2];

			// unordered removal from the buffer
			buffer[i][0] = buffer[buffer_size - 1][0];
			buffer[i][1] = buffer[buffer_size - 1][1];
			buffer[i][2] = buffer[buffer_size - 1][2];
			buffer_size--;

			// update vertex valences for strip start heuristic
			valence[a]--;
			valence[b]--;
			valence[c]--;

			// we need to pre-rotate the triangle so that we will find a match in the existing buffer on the next iteration
			int ea = findStripNext(buffer, buffer_size, c, b);
			int eb = ea < 0 ? findStripNext(buffer, buffer_size, a, c) : -1;
			int ec = eb < 0 ? findStripNext(buffer, buffer_size, b, a) : -1;

			if (ea >= 0)
			{
				// keep abc
				next = ea;
			}
			else if (eb >= 0)
			{
				// abc -> bca
				unsigned int t = a;
				a = b, b = c, c = t;

				next = eb;
			}
			else if (ec >= 0)
			{
				// abc -> cab
				unsigned int t = c;
				c = b, b = a, a = t;

				next = ec;
			}

			// emit the new strip; we use restart indices
			if (strip_size)
				destination[strip_size++] = ~0u;

			destination[strip_size++] = a;
			destination[strip_size++] = b;
			destination[strip_size++] = c;

			// new strip always starts with the same edge winding
			strip[0] = b;
			strip[1] = c;
			parity = 1;
		}
	}

	return strip_size;
}

size_t meshopt_unstripify(unsigned int* destination, const unsigned int* indices, size_t index_count)
{
	assert(destination != indices);

	size_t offset = 0;
	size_t start = 0;

	for (size_t i = 0; i < index_count; ++i)
	{
		if (indices[i] == ~0u)
		{
			start = i + 1;
		}
		else if (i - start >= 2)
		{
			unsigned int a = indices[i - 2], b = indices[i - 1], c = indices[i];

			if ((i - start) & 1)
			{
				unsigned int t = a;
				a = b, b = t;
			}

			if (a != b && a != c && b != c)
			{
				destination[offset + 0] = a;
				destination[offset + 1] = b;
				destination[offset + 2] = c;
				offset += 3;
			}
		}
	}

	return offset;
}
<commit_msg>stripify: Convert to meshopt_Buffer<T><commit_after>#include "meshoptimizer.h"

#include <assert.h>
#include <string.h>

namespace meshopt
{

static unsigned int findStripFirst(const unsigned int buffer[][3], unsigned int buffer_size, const unsigned int* valence)
{
	unsigned int index = 0;
	unsigned int iv = ~0u;

	for (unsigned int i = 0; i < buffer_size; ++i)
	{
		unsigned int va = valence[buffer[i][0]], vb = valence[buffer[i][1]], vc = valence[buffer[i][2]];
		unsigned int v = (va < vb && va < vc) ? va : (vb < vc) ? vb : vc;

		if (v < iv)
		{
			index = i;
			iv = v;
		}
	}

	return index;
}

static int findStripNext(const unsigned int buffer[][3], unsigned int buffer_size, unsigned int e0, unsigned int e1)
{
	for (unsigned int i = 0; i < buffer_size; ++i)
	{
		unsigned int a = buffer[i][0], b = buffer[i][1], c = buffer[i][2];

		if (e0 == a && e1 == b)
			return (i << 2) | 2;
		else if (e0 == b && e1 == c)
			return (i << 2) | 0;
		else if (e0 == c && e1 == a)
			return (i << 2) | 1;
	}

	return -1;
}

} // namespace meshopt

size_t meshopt_stripify(unsigned int* destination, const unsigned int* indices, size_t index_count, size_t vertex_count)
{
	assert(destination != indices);
	assert(index_count % 3 == 0);

	using namespace meshopt;

	const size_t buffer_capacity = 8;

	unsigned int buffer[buffer_capacity][3] = {};
	unsigned int buffer_size = 0;

	size_t index_offset = 0;

	unsigned int strip[2] = {};
	unsigned int parity = 0;

	size_t strip_size = 0;

	// compute vertex valence; this is used to prioritize starting triangle for strips
	meshopt_Buffer<unsigned int> valence(vertex_count);
	memset(valence.data, 0, vertex_count * sizeof(unsigned int));

	for (size_t i = 0; i < index_count; ++i)
	{
		unsigned int index = indices[i];
		assert(index < vertex_count);

		valence[index]++;
	}

	int next = -1;

	while (buffer_size > 0 || index_offset < index_count)
	{
		assert(next < 0 || (size_t(next >> 2) < buffer_size && (next & 3) < 3));

		// fill triangle buffer
		while (buffer_size < buffer_capacity && index_offset < index_count)
		{
			buffer[buffer_size][0] = indices[index_offset + 0];
			buffer[buffer_size][1] = indices[index_offset + 1];
			buffer[buffer_size][2] = indices[index_offset + 2];

			buffer_size++;
			index_offset += 3;
		}

		assert(buffer_size > 0);

		if (next >= 0)
		{
			unsigned int i = next >> 2;
			unsigned int a = buffer[i][0], b = buffer[i][1], c = buffer[i][2];
			unsigned int v = buffer[i][next & 3];

			// unordered removal from the buffer
			buffer[i][0] = buffer[buffer_size - 1][0];
			buffer[i][1] = buffer[buffer_size - 1][1];
			buffer[i][2] = buffer[buffer_size - 1][2];
			buffer_size--;

			// update vertex valences for strip start heuristic
			valence[a]--;
			valence[b]--;
			valence[c]--;

			// find next triangle (note that edge order flips on every iteration)
			// in some cases we need to perform a swap to pick a different outgoing triangle edge
			// for [a b c], the default strip edge is [b c], but we might want to use [a c]
			int cont = findStripNext(buffer, buffer_size, parity ? strip[1] : v, parity ? v : strip[1]);
			int swap = cont < 0 ? findStripNext(buffer, buffer_size, parity ? v : strip[0], parity ? strip[0] : v) : -1;

			if (cont < 0 && swap >= 0)
			{
				// [a b c] => [a b a c]
				destination[strip_size++] = strip[0];
				destination[strip_size++] = v;

				// next strip has same winding
				// ? a b => b a v
				strip[1] = v;

				next = swap;
			}
			else
			{
				// emit the next vertex in the strip
				destination[strip_size++] = v;

				// next strip has flipped winding
				strip[0] = strip[1];
				strip[1] = v;
				parity ^= 1;

				next = cont;
			}
		}
		else
		{
			// if we didn't find anything, we need to find the next new triangle
			// we use a heuristic to maximize the strip length
			unsigned int i = findStripFirst(buffer, buffer_size, &valence[0]);
			unsigned int a = buffer[i][0], b = buffer[i][1], c = buffer[i][2];

			// unordered removal from the buffer
			buffer[i][0] = buffer[buffer_size - 1][0];
			buffer[i][1] = buffer[buffer_size - 1][1];
			buffer[i][2] = buffer[buffer_size - 1][2];
			buffer_size--;

			// update vertex valences for strip start heuristic
			valence[a]--;
			valence[b]--;
			valence[c]--;

			// we need to pre-rotate the triangle so that we will find a match in the existing buffer on the next iteration
			int ea = findStripNext(buffer, buffer_size, c, b);
			int eb = ea < 0 ? findStripNext(buffer, buffer_size, a, c) : -1;
			int ec = eb < 0 ? findStripNext(buffer, buffer_size, b, a) : -1;

			if (ea >= 0)
			{
				// keep abc
				next = ea;
			}
			else if (eb >= 0)
			{
				// abc -> bca
				unsigned int t = a;
				a = b, b = c, c = t;

				next = eb;
			}
			else if (ec >= 0)
			{
				// abc -> cab
				unsigned int t = c;
				c = b, b = a, a = t;

				next = ec;
			}

			// emit the new strip; we use restart indices
			if (strip_size)
				destination[strip_size++] = ~0u;

			destination[strip_size++] = a;
			destination[strip_size++] = b;
			destination[strip_size++] = c;

			// new strip always starts with the same edge winding
			strip[0] = b;
			strip[1] = c;
			parity = 1;
		}
	}

	return strip_size;
}

size_t meshopt_unstripify(unsigned int* destination, const unsigned int* indices, size_t index_count)
{
	assert(destination != indices);

	size_t offset = 0;
	size_t start = 0;

	for (size_t i = 0; i < index_count; ++i)
	{
		if (indices[i] == ~0u)
		{
			start = i + 1;
		}
		else if (i - start >= 2)
		{
			unsigned int a = indices[i - 2], b = indices[i - 1], c = indices[i];

			if ((i - start) & 1)
			{
				unsigned int t = a;
				a = b, b = t;
			}

			if (a != b && a != c && b != c)
			{
				destination[offset + 0] = a;
				destination[offset + 1] = b;
				destination[offset + 2] = c;
				offset += 3;
			}
		}
	}

	return offset;
}
<|endoftext|>


<commit_before>#include "ruby.h"
#include <Rpc.h>
#pragma comment(lib, "Rpcrt4.lib")

VALUE method_generate(VALUE self) {
  UUID uuid = {0};
  char * uuid_string;

  ::UuidCreate(&uuid);

  RPC_CSTR szUuid = NULL;
  if (::UuidToStringA(&uuid, &szUuid) == RPC_S_OK)
  {
    uuid_string = (char*) szUuid;
    ::RpcStringFreeA(&szUuid);
  }

  return rb_str_new2(uuid_string);
}
<commit_msg>Remove pragma from win implementation.<commit_after>#include "ruby.h"
#include <Rpc.h>

VALUE method_generate(VALUE self) {
  UUID uuid = {0};
  char * uuid_string;

  ::UuidCreate(&uuid);

  RPC_CSTR szUuid = NULL;
  if (::UuidToStringA(&uuid, &szUuid) == RPC_S_OK)
  {
    uuid_string = (char*) szUuid;
    ::RpcStringFreeA(&szUuid);
  }

  return rb_str_new2(uuid_string);
}
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	Fixed FIFO (first in first out) テンプレート
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2017, 2018 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include <cstdint>

namespace utils {

    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
    /*!
        @brief  固定サイズ FIFO クラス
		@param[in]	UNIT	基本形
		@param[in]	SIZE	バッファサイズ
    */
    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class UNIT, uint32_t SIZE>
	class fixed_fifo {

		volatile uint32_t	get_;
		volatile uint32_t	put_;

		UNIT	buff_[SIZE];

	public:
        //-----------------------------------------------------------------//
        /*!
            @brief  コンストラクター
        */
        //-----------------------------------------------------------------//
		fixed_fifo() noexcept : get_(0), put_(0) { }

        //-----------------------------------------------------------------//
        /*!
            @brief  バッファのサイズを返す
			@return	バッファのサイズ
        */
        //-----------------------------------------------------------------//
		inline uint32_t size() const noexcept { return SIZE; }

        //-----------------------------------------------------------------//
        /*!
            @brief  長さを返す
			@return	長さ
        */
        //-----------------------------------------------------------------//
		uint32_t length() const noexcept {
			if(put_ >= get_) return (put_ - get_);
			else return (SIZE + put_ - get_);
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  クリア
        */
        //-----------------------------------------------------------------//
		inline void clear() noexcept { get_ = put_ = 0; }

        //-----------------------------------------------------------------//
        /*!
            @brief  値の格納参照を得る
			@param[in]	ofs	オフセット（格納領域を超えたオフセットは未定義）
			@return 値の格納参照
        */
        //-----------------------------------------------------------------//
		inline UNIT& put_at(uint32_t ofs = 0) noexcept {
			return buff_[(put_ + ofs) % SIZE];
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  値の格納ポイントの移動
        */
        //-----------------------------------------------------------------//
		inline void put_go() noexcept {
			volatile uint16_t put = put_;
			++put;
			if(put >= SIZE) {
				put = 0;
			}
			put_ = put;
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  値の格納
			@param[in]	v	値
        */
        //-----------------------------------------------------------------//
		void put(const UNIT& v) noexcept {
			buff_[put_] = v;
			put_go();
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  値の取得参照を得る
			@param[in]	ofs	オフセット（格納領域を超えたオフセットは未定義）
			@return	値の取得参照
        */
        //-----------------------------------------------------------------//
		inline const UNIT& get_at(uint32_t ofs = 0) const noexcept {
			return buff_[(get_ + ofs) % SIZE];
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  値の取得
        */
        //-----------------------------------------------------------------//
		inline void get_go() noexcept {
			volatile uint16_t get = get_;
			++get;
			if(get >= SIZE) {
				get = 0;
			}
			get_ = get;
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  値の取得
			@return	値
        */
        //-----------------------------------------------------------------//
		UNIT get() noexcept {
			UNIT v = buff_[get_];
			get_go();
			return v;
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  get 位置を返す
			@return	位置
        */
        //-----------------------------------------------------------------//
		inline uint16_t pos_get() const noexcept { return get_; }

        //-----------------------------------------------------------------//
        /*!
            @brief  put 位置を返す
			@return	位置
        */
        //-----------------------------------------------------------------//
		inline uint16_t pos_put() const noexcept { return put_; }
	};
}
<commit_msg>Update: cleanup<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	Fixed FIFO (first in first out) テンプレート
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2017, 2020 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/RX/blob/master/LICENSE
*/
//=====================================================================//
#include <cstdint>

namespace utils {

    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
    /*!
        @brief  固定サイズ FIFO クラス
		@param[in]	UNIT	基本形
		@param[in]	SIZE	バッファサイズ（最低２）
    */
    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class UNIT, uint32_t SIZE>
	class fixed_fifo {

		volatile uint32_t	get_;
		volatile uint32_t	put_;

		UNIT	buff_[SIZE];

	public:
        //-----------------------------------------------------------------//
        /*!
            @brief  コンストラクター
        */
        //-----------------------------------------------------------------//
		fixed_fifo() noexcept : get_(0), put_(0) { }

        //-----------------------------------------------------------------//
        /*!
            @brief  バッファのサイズを返す
			@return	バッファのサイズ
        */
        //-----------------------------------------------------------------//
		inline uint32_t size() const noexcept { return SIZE; }

        //-----------------------------------------------------------------//
        /*!
            @brief  長さを返す
			@return	長さ
        */
        //-----------------------------------------------------------------//
		uint32_t length() const noexcept {
			if(put_ >= get_) return (put_ - get_);
			else return (SIZE + put_ - get_);
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  クリア
        */
        //-----------------------------------------------------------------//
		inline void clear() noexcept { get_ = put_ = 0; }

        //-----------------------------------------------------------------//
        /*!
            @brief  値の格納参照を得る
			@param[in]	ofs	オフセット（格納領域を超えたオフセットは未定義）
			@return 値の格納参照
        */
        //-----------------------------------------------------------------//
		inline UNIT& put_at(uint32_t ofs = 0) noexcept {
			return buff_[(put_ + ofs) % SIZE];
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  値の格納ポイントの移動
        */
        //-----------------------------------------------------------------//
		inline void put_go() noexcept {
			volatile auto put = put_;
			++put;
			if(put >= SIZE) {
				put = 0;
			}
			put_ = put;
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  値の格納
			@param[in]	v	値
        */
        //-----------------------------------------------------------------//
		void put(const UNIT& v) noexcept {
			buff_[put_] = v;
			put_go();
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  値の取得参照を得る
			@param[in]	ofs	オフセット（格納領域を超えたオフセットは未定義）
			@return	値の取得参照
        */
        //-----------------------------------------------------------------//
		inline const UNIT& get_at(uint32_t ofs = 0) const noexcept {
			return buff_[(get_ + ofs) % SIZE];
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  値の取得
        */
        //-----------------------------------------------------------------//
		inline void get_go() noexcept {
			volatile auto get = get_;
			++get;
			if(get >= SIZE) {
				get = 0;
			}
			get_ = get;
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  値の取得
			@return	値
        */
        //-----------------------------------------------------------------//
		UNIT get() noexcept {
			UNIT v = buff_[get_];
			get_go();
			return v;
		}

        //-----------------------------------------------------------------//
        /*!
            @brief  get 位置を返す
			@return	位置
        */
        //-----------------------------------------------------------------//
		inline uint16_t pos_get() const noexcept { return get_; }

        //-----------------------------------------------------------------//
        /*!
            @brief  put 位置を返す
			@return	位置
        */
        //-----------------------------------------------------------------//
		inline uint16_t pos_put() const noexcept { return put_; }
	};
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014—2016 David Wicks, sansumbrella.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once
#include <vector>
#include "Phrase.hpp"
#include "UnitBezier.h"
#include "TimeType.h"

namespace choreograph
{

class Curve
{
public:
  enum Type {
    Bezier,
    Hold,
    Linear
  };
  float solve(float t) const;
  void  setType(Type type) { _type = type; }
  void  hold() { _type = Hold; }
  BezierInterpolant&       bezier() { _type = Bezier; return _bezier; }
private:
  Type              _type = Linear;
  BezierInterpolant _bezier;
};

float Curve::solve(float t) const
{
  switch (_type) {
    case Bezier:
      return _bezier.solve(t);
    break;
    case Hold:
      return 0.0f;
    break;
    case Linear:
      return t;
    break;
    default:
      return t;
    break;
  }
}

///
/// Simple channel concept with bezier interpolation between keys.
/// Goals:
/// - Easy serialization
/// - Easy to create graphical manipulation tools.
///   - Support direct manipulation of animation data.
///   - Avoid deeply nested information. Flat hierarchy.
/// - Flexible enough to create an AfterEffects-style timeline.
///
/// Good for animating single values, like floats or quaternions.
/// For vector types, use a channel per component (and maybe add a group type to associate them).
/// Grouping type could be a manipulator/animator type class that reads/writes multiple channels.
///
template <typename T>
class Channel
{
public:
  struct Key {
    Key(T value, Time time):
      value(value),
      time(time)
    {}
    T    value;
    Time time;
  };

  Channel() = default;

  /// Return the value of the channel at a given time.
  T value(Time at_time) const;
  /// Return the interpolated value between two keys.
  /// If you keep track of keys yourself, this is faster.
  T interpolatedValue(size_t curve_index, Time at_time) const;

  /// Returns the index of the starting key for the current time.
  /// The curve lies between two keys.
  size_t index(Time at_time) const;
  size_t lastIndex() const { return _keys.empty() ? 0 : _keys.size() - 1; }

  /// Append a key to the list of keys, positioned at \offset time after the previous key.
  Channel& appendKeyAfter(T value, Time offset) {
    if (! _keys.empty()) {
      _curves.emplace_back();
    }
    _keys.emplace_back(value, duration() + offset);
    return *this;
  }
  /// Insert a key at the given time.
  Channel& insertKey(T value, Time at_time);

  Time     duration() const { return _keys.empty() ? 0 : _keys.back().time; }
  const std::vector<Key>&   keys() const { return _keys; }
  const std::vector<Curve>& curves() const { return _curves; }

  std::vector<Key>&   mutableKeys() { return _keys; }
  std::vector<Curve>& mutableCurves() { return _curves; }

private:
  std::vector<Key>   _keys;
  // may make polymorphic in future (like phrases are). Basically just an ease fn.
  // Compare std::function<float (float)> for max flexibility against custom class.
  std::vector<Curve> _curves;
};

#pragma mark - Channel Template Implementation

template <typename T>
size_t Channel<T>::index(Time at_time) const {

  if( at_time <= 0 ) {
    return 0;
  }
  else if ( at_time >= this->duration() ) {
    return lastIndex();
  }

  for (auto i = 0; i < _keys.size() - 1; i += 1) {
    auto &a = _keys[i], &b = _keys[i + 1];
    if (a.time <= at_time && b.time >= at_time) {
      return i;
    }
  }
  return lastIndex();
}

template <typename T>
T Channel<T>::value(Time at_time) const {
  if (at_time >= duration()) {
    return _keys.back().value;
  }
  else if (at_time <= 0.0) {
    return _keys.front().value;
  }

  return interpolatedValue(index(at_time), at_time);
}

template <typename T>
T Channel<T>::interpolatedValue(size_t curve_index, Time at_time) const {
  auto &a = _keys[curve_index];
  auto &b = _keys[curve_index + 1];
  auto &c = _curves[curve_index];

  auto x = (at_time - a.time) / (b.time - a.time);
  auto t = c.solve(x);
  return lerpT(a.value, b.value, t);
}

template <typename T>
Channel<T>& Channel<T>::insertKey(T value, Time at_time) {
  if (_keys.empty()) {
    _keys.emplace_back(value, at_time);
    return *this;
  }

  auto i = index(at_time);
  if (_curves.empty()) {
    _curves.emplace_back();
  }
  else {
    _curves.insert(_curves.begin() + i, {});
  }
  _keys.insert(_keys.begin() + i + 1, {value, at_time});

  return *this;
}

} // namepsace choreograph
<commit_msg>Properly construct curve for insertion.<commit_after>/*
 * Copyright (c) 2014—2016 David Wicks, sansumbrella.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once
#include <vector>
#include "Phrase.hpp"
#include "UnitBezier.h"
#include "TimeType.h"

namespace choreograph
{

class Curve
{
public:
  enum Type {
    Bezier,
    Hold,
    Linear
  };

  Curve() = default;
  explicit Curve(Type t):
    _type(t)
  {}
  explicit Curve(const BezierInterpolant &bezier):
    _type(Bezier),
    _bezier(bezier)
  {}

  float solve(float t) const;
  void  setType(Type type) { _type = type; }
  void  hold() { _type = Hold; }
  BezierInterpolant&       bezier() { _type = Bezier; return _bezier; }
private:
  Type              _type = Linear;
  BezierInterpolant _bezier;
};

float Curve::solve(float t) const
{
  switch (_type) {
    case Bezier:
      return _bezier.solve(t);
    break;
    case Hold:
      return 0.0f;
    break;
    case Linear:
      return t;
    break;
    default:
      return t;
    break;
  }
}

///
/// Simple channel concept with bezier interpolation between keys.
/// Goals:
/// - Easy serialization
/// - Easy to create graphical manipulation tools.
///   - Support direct manipulation of animation data.
///   - Avoid deeply nested information. Flat hierarchy.
/// - Flexible enough to create an AfterEffects-style timeline.
///   - Separate motion path with bezier interpolation for full effect.
///   - Get time along section with channel, calculate value using path.
///   - Channel for timing, with key values corresponding to control points on spatial curve.
///
/// Good for animating single values, like floats or quaternions.
/// For vector types, use a channel per component (and maybe add a group type to associate them).
/// Grouping type could be a manipulator/animator type class that reads/writes multiple channels.
///
template <typename T>
class Channel
{
public:
  struct Key {
    Key(T value, Time time):
      value(value),
      time(time)
    {}
    T    value;
    Time time;
  };

  Channel() = default;

  /// Return the value of the channel at a given time.
  T value(Time at_time) const;
  /// Return the interpolated value between two keys.
  /// If you keep track of keys yourself, this is faster.
  T interpolatedValue(size_t curve_index, Time at_time) const;

  /// Returns the index of the starting key for the current time.
  /// The curve lies between two keys.
  size_t index(Time at_time) const;
  size_t lastIndex() const { return _keys.empty() ? 0 : _keys.size() - 1; }

  /// Append a key to the list of keys, positioned at \offset time after the previous key.
  Channel& appendKeyAfter(T value, Time offset) {
    if (! _keys.empty()) {
      _curves.emplace_back();
    }
    _keys.emplace_back(value, duration() + offset);
    return *this;
  }
  /// Insert a key at the given time.
  Channel& insertKey(T value, Time at_time);

  Time     duration() const { return _keys.empty() ? 0 : _keys.back().time; }
  const std::vector<Key>&   keys() const { return _keys; }
  const std::vector<Curve>& curves() const { return _curves; }

  std::vector<Key>&   mutableKeys() { return _keys; }
  std::vector<Curve>& mutableCurves() { return _curves; }

private:
  std::vector<Key>   _keys;
  // may make polymorphic in future (like phrases are). Basically just an ease fn.
  // Compare std::function<float (float)> for max flexibility against custom class.
  std::vector<Curve> _curves;
};

#pragma mark - Channel Template Implementation

template <typename T>
size_t Channel<T>::index(Time at_time) const {

  if( at_time <= 0 ) {
    return 0;
  }
  else if ( at_time >= this->duration() ) {
    return lastIndex();
  }

  for (auto i = 0; i < _keys.size() - 1; i += 1) {
    auto &a = _keys[i], &b = _keys[i + 1];
    if (a.time <= at_time && b.time >= at_time) {
      return i;
    }
  }
  return lastIndex();
}

template <typename T>
T Channel<T>::value(Time at_time) const {
  if (at_time >= duration()) {
    return _keys.back().value;
  }
  else if (at_time <= 0.0) {
    return _keys.front().value;
  }

  return interpolatedValue(index(at_time), at_time);
}

template <typename T>
T Channel<T>::interpolatedValue(size_t curve_index, Time at_time) const {
  auto &a = _keys[curve_index];
  auto &b = _keys[curve_index + 1];
  auto &c = _curves[curve_index];

  auto x = (at_time - a.time) / (b.time - a.time);
  auto t = c.solve(x);
  return lerpT(a.value, b.value, t);
}

template <typename T>
Channel<T>& Channel<T>::insertKey(T value, Time at_time) {
  if (_keys.empty()) {
    _keys.emplace_back(value, at_time);
    return *this;
  }

  auto i = index(at_time);
  if (_curves.empty()) {
    _curves.emplace_back(Curve::Linear);
  }
  else {
    _curves.insert(_curves.begin() + i, Curve(Curve::Linear));
  }
  _keys.insert(_keys.begin() + i + 1, {value, at_time});

  return *this;
}

} // namepsace choreograph
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** If you have questions regarding the use of this file, please
** contact Nokia at http://www.qtsoftware.com/contact.
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qcontactmanager.h"

#include "qcontact_p.h"
#include "qcontactgroup_p.h"
#include "qcontactdetaildefinition.h"
#include "qcontactmanager_p.h"
#include "qcontactmanagerengine.h"

#include "qcontactmemorybackend_p.h"

#include <QUuid>
#include <QSharedData>

/*!
 * \class QContactMemoryEngine
 * \brief This class provides an in-memory implementation of a contacts backend.
 *
 * It may be used as a reference implementation, or when persistent storage is not required.
 *
 * During construction, it will load the in-memory data associated with the memory store
 * identified by the "id" parameter from the given parameters if it exists, or a new,
 * anonymous store if it does not.
 *
 * Data stored in this engine is only available in the current process.
 *
 * This engine supports sharing, so an internal reference count is increased
 * whenever a manager uses this backend, and is decreased when the manager
 * no longer requires this engine.
 */

/* static data for manager class */
QMap<QString, QContactMemoryEngine*> QContactMemoryEngine::engines;

/*!
 * Factory function for creating a new in-memory backend, based
 * on the given \a parameters.
 *
 * The same engine will be returned for multiple calls with the
 * same value for the "id" parameter, while one of them is in scope.
 */
QContactMemoryEngine* QContactMemoryEngine::createMemoryEngine(const QMap<QString, QString>& parameters)
{
    QString idValue = parameters.value(QLatin1String("id"));
    if (idValue.isNull() || idValue.isEmpty()) {
        // no store given?  new, anonymous store.
        idValue = QUuid::createUuid().toString();
    }

    if (engines.contains(idValue)) {
        QContactMemoryEngine *engine = engines.value(idValue);
        engine->d->m_refCount.ref();
        return engine;
    } else {
        QContactMemoryEngine *engine = new QContactMemoryEngine(parameters);
        engine->d->m_id = idValue;
        engines.insert(idValue, engine);
        return engine;
    }
}

/*!
 * Constructs a new in-memory backend.
 *
 * Loads the in-memory data associated with the memory store identified by the "id" parameter
 * from the given \a parameters if it exists, or a new, anonymous store if it does not.
 */
QContactMemoryEngine::QContactMemoryEngine(const QMap<QString, QString>& parameters)
    : d(new QContactMemoryEngineData)
{
    Q_UNUSED(parameters);
}

/*! \reimp */
void QContactMemoryEngine::deref()
{
    if (!d->m_refCount.deref()) {
        engines.remove(d->m_id);
        delete d;
        delete this;
    }
}

/*! \reimp */
QList<QUniqueId> QContactMemoryEngine::contacts(const QContactSortOrder& sortOrder, QContactManager::Error& error) const
{
    error = QContactManager::NoError;
    if (!sortOrder.isValid())
        return d->m_contactIds;

    // TODO: this needs to be done properly...
    QList<QUniqueId> sortedIds;
    QList<QContact> sortedContacts;
    for (int i = 0; i < d->m_contacts.size(); i++)
        QContactManagerEngine::addSorted(&sortedContacts, d->m_contacts.at(i), sortOrder);
    for (int i = 0; i < sortedContacts.size(); i++)
        sortedIds.append(sortedContacts.at(i).id());
    return sortedIds;
}

/*! \reimp */
QContact QContactMemoryEngine::contact(const QUniqueId& contactId, QContactManager::Error& error) const
{
    int index = d->m_contactIds.indexOf(contactId);
    if (index != -1) {
        error = QContactManager::NoError;
        QContact retn = d->m_contacts.at(index);
        QContactDisplayLabel dl = retn.detail(QLatin1String(QContactDisplayLabel::DefinitionName));
        if (dl.label().isEmpty()) {
            QContactManager::Error synthError;
            dl.setLabel(synthesiseDisplayLabel(retn, synthError));
            dl.setSynthesised(true);
            retn.saveDetail(&dl);
        }

        return retn;
    }

    error = QContactManager::DoesNotExistError;
    return QContact();
}

/*! \reimp */
bool QContactMemoryEngine::saveContact(QContact* contact, bool batch, QContactManager::Error& error)
{
    // ensure that the contact's details conform to their definitions
    if (!validateContact(*contact, error)) {
        error = QContactManager::InvalidDetailError;
        return false;
    }

    // check to see if this contact already exists
    int index = d->m_contactIds.indexOf(contact->id());
    if (index != -1) {
        /* We also need to check that there are no modified create only details */
        QContact oldContact = d->m_contacts.at(index);

        QSetIterator<QString> it(d->m_createOnlyIds);
        while (it.hasNext()) {
            const QString& id = it.next();
            QList<QContactDetail> details = oldContact.details(id);
            QList<QContactDetail> newDetails = contact->details(id);

            /* Any entries in old should still be in new */
            if (newDetails.count() < details.count()) {
                error = QContactManager::DetailAccessError;
                return false;
            }

            /* Now do a more detailed check */
            for (int i=0; i < details.count(); i++) {
                if (!newDetails.contains(details.at(i))) {
                    error = QContactManager::DetailAccessError;
                    return false;
                }
            }
        }

        // Looks ok, so continue
        d->m_contacts.replace(index, *contact);
        error = QContactManager::NoError;
        if (!batch) {
            QList<QUniqueId> emitList;
            emitList.append(contact->id());
            emit contactsChanged(emitList);
        }
        return true;
    }

    /* We ignore read only details here - we may have provided some */

    // update the contact item - set its ID
    contact->setId(++d->m_nextContactId);

    // finally, add the contact to our internal lists and return
    d->m_contacts.append(*contact);             // add contact to list
    d->m_contactIds.append(contact->id());      // track the contact id.

    error = QContactManager::NoError;     // successful.

    // if we need to emit signals (ie, this isn't part of a batch operation)
    // then emit the correct one.
    if (!batch) {
        QList<QUniqueId> emitList;
        emitList.append(contact->id());
        emit contactsAdded(emitList);
    }

    return true;
}

/*! \reimp */
bool QContactMemoryEngine::removeContact(const QUniqueId& contactId, bool batch, QContactManager::Error& error)
{
    int index = d->m_contactIds.indexOf(contactId);

    if (index == -1) {
        error = QContactManager::DoesNotExistError;
        return false;
    }

    // remove the contact from the lists.
    d->m_contacts.removeAt(index);
    d->m_contactIds.removeAt(index);
    error = QContactManager::NoError;

    // also remove it from any groups that we have
    QMutableMapIterator<QUniqueId, QContactGroup> it(d->m_groups);
    while (it.hasNext()) {
        it.next();
        it.value().removeMember(contactId);
    }

    // if we need to emit signals (ie, this isn't part of a batch operation)
    // then emit the correct one.
    if (!batch) {
        QList<QUniqueId> emitList;
        emitList.append(contactId);
        emit contactsRemoved(emitList);
    }

    return true;
}

/*! \reimp */
QList<QUniqueId> QContactMemoryEngine::groups(QContactManager::Error& error) const
{
    error = QContactManager::NoError;
    return d->m_groups.keys();
}

/*! \reimp */
QContactGroup QContactMemoryEngine::group(const QUniqueId& groupId, QContactManager::Error& error) const
{
    error = QContactManager::NoError;
    if (!d->m_groups.contains(groupId))
        error = QContactManager::DoesNotExistError;

    return d->m_groups.value(groupId);
}

/*! \reimp */
bool QContactMemoryEngine::saveGroup(QContactGroup* group, QContactManager::Error& error)
{
    if (!group) {
        error = QContactManager::BadArgumentError;
        return false;
    }

    if (group->name().isEmpty()) {
        error = QContactManager::BadArgumentError;
        return false;
    }

    // if the group does not exist, generate a new group id for it.
    if (!d->m_groups.contains(group->id())) {
        group->setId(++d->m_nextGroupId);
    }

    // save it in the database
    d->m_groups.insert(group->id(), *group);
    error = QContactManager::NoError;
    return true;
}

/*! \reimp */
bool QContactMemoryEngine::removeGroup(const QUniqueId& groupId, QContactManager::Error& error)
{
    if (!d->m_groups.contains(groupId)) {
        error = QContactManager::DoesNotExistError;
        return false;
    }

    d->m_groups.remove(groupId);
    error = QContactManager::NoError;
    return true;
}

/*! \reimp */
QMap<QString, QContactDetailDefinition> QContactMemoryEngine::detailDefinitions(QContactManager::Error& error) const
{
    // lazy initialisation of schema definitions.
    if (d->m_definitions.isEmpty()) {
        d->m_definitions = QContactManagerEngine::schemaDefinitions();

        // Extract create only definitions
        QMapIterator<QString, QContactDetailDefinition> it(d->m_definitions);
        while (it.hasNext()) {
            it.next();
            if (it.value().accessConstraint() == QContactDetailDefinition::CreateOnly)
                d->m_createOnlyIds.insert(it.key());
        }
    }

    error = QContactManager::NoError;
    return d->m_definitions;
}

/*! \reimp */
bool QContactMemoryEngine::saveDetailDefinition(const QContactDetailDefinition& def, QContactManager::Error& error)
{
    if (!validateDefinition(def, error)) {
        return false;
    }
    detailDefinitions(error); // just to populate the definitions if we haven't already.
    d->m_definitions.insert(def.id(), def);
    if (def.accessConstraint() == QContactDetailDefinition::CreateOnly)
        d->m_createOnlyIds.insert(def.id());
    error = QContactManager::NoError;
    return true;
}

/*! \reimp */
bool QContactMemoryEngine::removeDetailDefinition(const QString& definitionId, QContactManager::Error& error)
{
    if (definitionId.isEmpty()) {
        error = QContactManager::BadArgumentError;
        return false;
    }

    detailDefinitions(error); // just to populate the definitions if we haven't already.
    bool success = d->m_definitions.remove(definitionId);
    d->m_createOnlyIds.remove(definitionId);
    if (success)
        error = QContactManager::NoError;
    else
        error = QContactManager::DoesNotExistError;
    return success;
}

/*!
 * \reimp
 */
bool QContactMemoryEngine::hasFeature(QContactManagerInfo::ManagerFeature feature) const
{
    switch (feature) {
        case QContactManagerInfo::Groups:
        case QContactManagerInfo::Batch:
        case QContactManagerInfo::ActionPreferences:
        case QContactManagerInfo::ReadOnlyDetails:
        case QContactManagerInfo::CreateOnlyDetails:
        case QContactManagerInfo::MutableDefinitions:
        case QContactManagerInfo::Synchronous:
            return true;
        default:
            return false;
    }
}

/*!
 * \reimp
 */
QList<QVariant::Type> QContactMemoryEngine::supportedDataTypes() const
{
    QList<QVariant::Type> st;
    st.append(QVariant::String);
    st.append(QVariant::Date);
    st.append(QVariant::DateTime);
    st.append(QVariant::Time);
    st.append(QVariant::Int);
    st.append(QVariant::UInt);
    st.append(QVariant::LongLong);
    st.append(QVariant::ULongLong);

    return st;
}

/*!
 * \reimp
 */
bool QContactMemoryEngine::filterSupported(const QContactFilter& filter) const
{
    Q_UNUSED(filter);
    // Until we add hashes for common stuff, fall back to slow code
    return false;
}

<commit_msg>Add double support to memory engine.<commit_after>/****************************************************************************
**
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** If you have questions regarding the use of this file, please
** contact Nokia at http://www.qtsoftware.com/contact.
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qcontactmanager.h"

#include "qcontact_p.h"
#include "qcontactgroup_p.h"
#include "qcontactdetaildefinition.h"
#include "qcontactmanager_p.h"
#include "qcontactmanagerengine.h"

#include "qcontactmemorybackend_p.h"

#include <QUuid>
#include <QSharedData>

/*!
 * \class QContactMemoryEngine
 * \brief This class provides an in-memory implementation of a contacts backend.
 *
 * It may be used as a reference implementation, or when persistent storage is not required.
 *
 * During construction, it will load the in-memory data associated with the memory store
 * identified by the "id" parameter from the given parameters if it exists, or a new,
 * anonymous store if it does not.
 *
 * Data stored in this engine is only available in the current process.
 *
 * This engine supports sharing, so an internal reference count is increased
 * whenever a manager uses this backend, and is decreased when the manager
 * no longer requires this engine.
 */

/* static data for manager class */
QMap<QString, QContactMemoryEngine*> QContactMemoryEngine::engines;

/*!
 * Factory function for creating a new in-memory backend, based
 * on the given \a parameters.
 *
 * The same engine will be returned for multiple calls with the
 * same value for the "id" parameter, while one of them is in scope.
 */
QContactMemoryEngine* QContactMemoryEngine::createMemoryEngine(const QMap<QString, QString>& parameters)
{
    QString idValue = parameters.value(QLatin1String("id"));
    if (idValue.isNull() || idValue.isEmpty()) {
        // no store given?  new, anonymous store.
        idValue = QUuid::createUuid().toString();
    }

    if (engines.contains(idValue)) {
        QContactMemoryEngine *engine = engines.value(idValue);
        engine->d->m_refCount.ref();
        return engine;
    } else {
        QContactMemoryEngine *engine = new QContactMemoryEngine(parameters);
        engine->d->m_id = idValue;
        engines.insert(idValue, engine);
        return engine;
    }
}

/*!
 * Constructs a new in-memory backend.
 *
 * Loads the in-memory data associated with the memory store identified by the "id" parameter
 * from the given \a parameters if it exists, or a new, anonymous store if it does not.
 */
QContactMemoryEngine::QContactMemoryEngine(const QMap<QString, QString>& parameters)
    : d(new QContactMemoryEngineData)
{
    Q_UNUSED(parameters);
}

/*! \reimp */
void QContactMemoryEngine::deref()
{
    if (!d->m_refCount.deref()) {
        engines.remove(d->m_id);
        delete d;
        delete this;
    }
}

/*! \reimp */
QList<QUniqueId> QContactMemoryEngine::contacts(const QContactSortOrder& sortOrder, QContactManager::Error& error) const
{
    error = QContactManager::NoError;
    if (!sortOrder.isValid())
        return d->m_contactIds;

    // TODO: this needs to be done properly...
    QList<QUniqueId> sortedIds;
    QList<QContact> sortedContacts;
    for (int i = 0; i < d->m_contacts.size(); i++)
        QContactManagerEngine::addSorted(&sortedContacts, d->m_contacts.at(i), sortOrder);
    for (int i = 0; i < sortedContacts.size(); i++)
        sortedIds.append(sortedContacts.at(i).id());
    return sortedIds;
}

/*! \reimp */
QContact QContactMemoryEngine::contact(const QUniqueId& contactId, QContactManager::Error& error) const
{
    int index = d->m_contactIds.indexOf(contactId);
    if (index != -1) {
        error = QContactManager::NoError;
        QContact retn = d->m_contacts.at(index);
        QContactDisplayLabel dl = retn.detail(QLatin1String(QContactDisplayLabel::DefinitionName));
        if (dl.label().isEmpty()) {
            QContactManager::Error synthError;
            dl.setLabel(synthesiseDisplayLabel(retn, synthError));
            dl.setSynthesised(true);
            retn.saveDetail(&dl);
        }

        return retn;
    }

    error = QContactManager::DoesNotExistError;
    return QContact();
}

/*! \reimp */
bool QContactMemoryEngine::saveContact(QContact* contact, bool batch, QContactManager::Error& error)
{
    // ensure that the contact's details conform to their definitions
    if (!validateContact(*contact, error)) {
        error = QContactManager::InvalidDetailError;
        return false;
    }

    // check to see if this contact already exists
    int index = d->m_contactIds.indexOf(contact->id());
    if (index != -1) {
        /* We also need to check that there are no modified create only details */
        QContact oldContact = d->m_contacts.at(index);

        QSetIterator<QString> it(d->m_createOnlyIds);
        while (it.hasNext()) {
            const QString& id = it.next();
            QList<QContactDetail> details = oldContact.details(id);
            QList<QContactDetail> newDetails = contact->details(id);

            /* Any entries in old should still be in new */
            if (newDetails.count() < details.count()) {
                error = QContactManager::DetailAccessError;
                return false;
            }

            /* Now do a more detailed check */
            for (int i=0; i < details.count(); i++) {
                if (!newDetails.contains(details.at(i))) {
                    error = QContactManager::DetailAccessError;
                    return false;
                }
            }
        }

        // Looks ok, so continue
        d->m_contacts.replace(index, *contact);
        error = QContactManager::NoError;
        if (!batch) {
            QList<QUniqueId> emitList;
            emitList.append(contact->id());
            emit contactsChanged(emitList);
        }
        return true;
    }

    /* We ignore read only details here - we may have provided some */

    // update the contact item - set its ID
    contact->setId(++d->m_nextContactId);

    // finally, add the contact to our internal lists and return
    d->m_contacts.append(*contact);             // add contact to list
    d->m_contactIds.append(contact->id());      // track the contact id.

    error = QContactManager::NoError;     // successful.

    // if we need to emit signals (ie, this isn't part of a batch operation)
    // then emit the correct one.
    if (!batch) {
        QList<QUniqueId> emitList;
        emitList.append(contact->id());
        emit contactsAdded(emitList);
    }

    return true;
}

/*! \reimp */
bool QContactMemoryEngine::removeContact(const QUniqueId& contactId, bool batch, QContactManager::Error& error)
{
    int index = d->m_contactIds.indexOf(contactId);

    if (index == -1) {
        error = QContactManager::DoesNotExistError;
        return false;
    }

    // remove the contact from the lists.
    d->m_contacts.removeAt(index);
    d->m_contactIds.removeAt(index);
    error = QContactManager::NoError;

    // also remove it from any groups that we have
    QMutableMapIterator<QUniqueId, QContactGroup> it(d->m_groups);
    while (it.hasNext()) {
        it.next();
        it.value().removeMember(contactId);
    }

    // if we need to emit signals (ie, this isn't part of a batch operation)
    // then emit the correct one.
    if (!batch) {
        QList<QUniqueId> emitList;
        emitList.append(contactId);
        emit contactsRemoved(emitList);
    }

    return true;
}

/*! \reimp */
QList<QUniqueId> QContactMemoryEngine::groups(QContactManager::Error& error) const
{
    error = QContactManager::NoError;
    return d->m_groups.keys();
}

/*! \reimp */
QContactGroup QContactMemoryEngine::group(const QUniqueId& groupId, QContactManager::Error& error) const
{
    error = QContactManager::NoError;
    if (!d->m_groups.contains(groupId))
        error = QContactManager::DoesNotExistError;

    return d->m_groups.value(groupId);
}

/*! \reimp */
bool QContactMemoryEngine::saveGroup(QContactGroup* group, QContactManager::Error& error)
{
    if (!group) {
        error = QContactManager::BadArgumentError;
        return false;
    }

    if (group->name().isEmpty()) {
        error = QContactManager::BadArgumentError;
        return false;
    }

    // if the group does not exist, generate a new group id for it.
    if (!d->m_groups.contains(group->id())) {
        group->setId(++d->m_nextGroupId);
    }

    // save it in the database
    d->m_groups.insert(group->id(), *group);
    error = QContactManager::NoError;
    return true;
}

/*! \reimp */
bool QContactMemoryEngine::removeGroup(const QUniqueId& groupId, QContactManager::Error& error)
{
    if (!d->m_groups.contains(groupId)) {
        error = QContactManager::DoesNotExistError;
        return false;
    }

    d->m_groups.remove(groupId);
    error = QContactManager::NoError;
    return true;
}

/*! \reimp */
QMap<QString, QContactDetailDefinition> QContactMemoryEngine::detailDefinitions(QContactManager::Error& error) const
{
    // lazy initialisation of schema definitions.
    if (d->m_definitions.isEmpty()) {
        d->m_definitions = QContactManagerEngine::schemaDefinitions();

        // Extract create only definitions
        QMapIterator<QString, QContactDetailDefinition> it(d->m_definitions);
        while (it.hasNext()) {
            it.next();
            if (it.value().accessConstraint() == QContactDetailDefinition::CreateOnly)
                d->m_createOnlyIds.insert(it.key());
        }
    }

    error = QContactManager::NoError;
    return d->m_definitions;
}

/*! \reimp */
bool QContactMemoryEngine::saveDetailDefinition(const QContactDetailDefinition& def, QContactManager::Error& error)
{
    if (!validateDefinition(def, error)) {
        return false;
    }
    detailDefinitions(error); // just to populate the definitions if we haven't already.
    d->m_definitions.insert(def.id(), def);
    if (def.accessConstraint() == QContactDetailDefinition::CreateOnly)
        d->m_createOnlyIds.insert(def.id());
    error = QContactManager::NoError;
    return true;
}

/*! \reimp */
bool QContactMemoryEngine::removeDetailDefinition(const QString& definitionId, QContactManager::Error& error)
{
    if (definitionId.isEmpty()) {
        error = QContactManager::BadArgumentError;
        return false;
    }

    detailDefinitions(error); // just to populate the definitions if we haven't already.
    bool success = d->m_definitions.remove(definitionId);
    d->m_createOnlyIds.remove(definitionId);
    if (success)
        error = QContactManager::NoError;
    else
        error = QContactManager::DoesNotExistError;
    return success;
}

/*!
 * \reimp
 */
bool QContactMemoryEngine::hasFeature(QContactManagerInfo::ManagerFeature feature) const
{
    switch (feature) {
        case QContactManagerInfo::Groups:
        case QContactManagerInfo::Batch:
        case QContactManagerInfo::ActionPreferences:
        case QContactManagerInfo::ReadOnlyDetails:
        case QContactManagerInfo::CreateOnlyDetails:
        case QContactManagerInfo::MutableDefinitions:
        case QContactManagerInfo::Synchronous:
            return true;
        default:
            return false;
    }
}

/*!
 * \reimp
 */
QList<QVariant::Type> QContactMemoryEngine::supportedDataTypes() const
{
    QList<QVariant::Type> st;
    st.append(QVariant::String);
    st.append(QVariant::Date);
    st.append(QVariant::DateTime);
    st.append(QVariant::Time);
    st.append(QVariant::Int);
    st.append(QVariant::UInt);
    st.append(QVariant::LongLong);
    st.append(QVariant::ULongLong);
    st.append(QVariant::Double);

    return st;
}

/*!
 * \reimp
 */
bool QContactMemoryEngine::filterSupported(const QContactFilter& filter) const
{
    Q_UNUSED(filter);
    // Until we add hashes for common stuff, fall back to slow code
    return false;
}

<|endoftext|>