<commit_before>/*****************************************************************************
 * qt4.cpp : QT4 interface
 ****************************************************************************
 * Copyright (C) 2006-2007 the VideoLAN team
 * $Id$
 *
 * Authors: Clément Stenac <zorglub@videolan.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#include <QApplication>

#include "qt4.hpp"
#include "dialogs_provider.hpp"
#include "input_manager.hpp"
#include "main_interface.hpp"

#include "../../../share/vlc32x32.xpm"

/*****************************************************************************
 * Local prototypes.
 *****************************************************************************/
static int  Open         ( vlc_object_t * );
static void Close        ( vlc_object_t * );
static int  OpenDialogs  ( vlc_object_t * );
static void Run          ( intf_thread_t * );
static void Init         ( intf_thread_t * );
static void ShowDialog   ( intf_thread_t *, int, int, intf_dialog_args_t * );

/*****************************************************************************
 * Module descriptor
 *****************************************************************************/
#define ALWAYS_VIDEO_TEXT N_("Always show a video screen, with a cone " \
                                "when there is audio only.")
#define ALWAYS_VIDEO_LONGTEXT N_("Start VLC with a cone image, and display it" \
                                   " when there is no video track. " \
                                    "Visualisations are enabled." )

#define ADVANCED_PREFS_TEXT N_("Show advanced prefs over simple")
#define ADVANCED_PREFS_LONGTEXT N_("Show advanced preferences and not simple" \
                                   "preferences when opening the preferences " \
                                   "dialog.")

#define SYSTRAY_TEXT N_("Show a systray icon to control VLC")
#define SYSTRAY_LONGTEXT N_("Show in the taskbar, a systray icon" \
                            "in order to control VLC media player" \
                            "for basic actions")

#define MINIMIZED_TEXT N_("Start VLC only with a systray icon")
#define MINIMIZED_LONGTEXT N_("When you launch VLC with that option" \
                            "VLC will start just with an icon in" \
                            "your taskbar")

#define TITLE_TEXT N_("Show playing item name in window title")
#define TITLE_LONGTEXT N_("Show the name of the song or video in the " \
                          "controler window title")

#define FILEDIALOG_PATH_TEXT N_("Path to use in file dialog")
#define FILEDIALOG_PATH_LONGTEXT N_("Path to use in file dialog")

#define NOTIFICATION_TEXT N_("Show notification popup on track change")
#define NOTIFICATION_LONGTEXT N_( \
    "Show a notification popup with the artist and track name when " \
    "the current playlist item changes." )

#define ADVANCED_OPTIONS_TEXT N_("Advanced options")
#define ADVANCED_OPTIONS_LONGTEXT N_("Activate by default all the" \
                                     "advanced options for geeks")

#define OPACITY_TEXT N_("Windows opacity between 0.1 and 1.")
#define OPACITY_LONGTEXT N_("Sets the windows opacity between 0.1 and 1 " \
                            "for main interface, playlist and extended panel." \
                            "This options only works with Windows and " \
                            "X11 with composite extensions.")

#define SHOWFLAGS_TEXT N_("Define what columns to show in playlist window")
#define SHOWFLAGS_LONGTEXT N_("Enter the sum of the options that you want: \n" \
            "Title: 1; Duration: 2; Artist: 4; Genre: 8; " \
            "Copyright: 16; Collection/album: 32; Rating: 256." )

vlc_module_begin();
    set_shortname( (char *)"Qt" );
    set_description( (char*)_("Qt interface") );
    set_category( CAT_INTERFACE ) ;
    set_subcategory( SUBCAT_INTERFACE_MAIN );
    set_capability( "interface", 151 );
    set_callbacks( Open, Close );

    set_program( "qvlc" );
    add_shortcut("qt");

    add_submodule();
        set_description( "Dialogs provider" );
        set_capability( "dialogs provider", 51 );
        add_bool( "qt-always-video", VLC_FALSE, NULL, ALWAYS_VIDEO_TEXT,
                ALWAYS_VIDEO_LONGTEXT, VLC_TRUE );
        add_bool( "qt-advanced-pref", VLC_FALSE, NULL, ADVANCED_PREFS_TEXT,
                ADVANCED_PREFS_LONGTEXT, VLC_FALSE );
        add_bool( "qt-system-tray", VLC_TRUE, NULL, SYSTRAY_TEXT,
                SYSTRAY_LONGTEXT, VLC_FALSE);
        add_bool( "qt-start-minimized", VLC_FALSE, NULL, MINIMIZED_TEXT,
                MINIMIZED_LONGTEXT, VLC_TRUE);
        add_bool( "qt-name-in-title", VLC_TRUE, NULL, TITLE_TEXT,
                  TITLE_LONGTEXT, VLC_FALSE );
        add_string( "qt-filedialog-path", NULL, NULL, FILEDIALOG_PATH_TEXT,
                FILEDIALOG_PATH_LONGTEXT, VLC_TRUE);
            change_autosave();
            change_internal();
        add_bool( "qt-notification", VLC_TRUE, NULL, NOTIFICATION_TEXT,
                  NOTIFICATION_LONGTEXT, VLC_FALSE );
        add_float_with_range( "qt-opacity", 1., 0.1, 1., NULL, OPACITY_TEXT,
                  OPACITY_LONGTEXT, VLC_FALSE );
        add_bool( "qt-adv-options", VLC_FALSE, NULL, ADVANCED_OPTIONS_TEXT,
                  ADVANCED_OPTIONS_LONGTEXT, VLC_TRUE );
        add_integer( "qt-pl-showflags",
                VLC_META_ENGINE_ARTIST|VLC_META_ENGINE_TITLE|
                VLC_META_ENGINE_DURATION|VLC_META_ENGINE_COLLECTION,
                NULL, SHOWFLAGS_TEXT,
                SHOWFLAGS_LONGTEXT, VLC_TRUE );
        set_callbacks( OpenDialogs, Close );
vlc_module_end();

/*****************************************************************************
 * Module callbacks
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    intf_thread_t *p_intf = (intf_thread_t *)p_this;
    p_intf->pf_run = Run;
#if defined HAVE_GETENV && defined Q_WS_X11
    if( !getenv( "DISPLAY" ) )
    {
        msg_Err(p_intf, "no X server");
        return VLC_EGENERIC;
    }
#endif
    p_intf->p_sys = (intf_sys_t *)malloc(sizeof( intf_sys_t ) );
    if( !p_intf->p_sys )
    {
        msg_Err(p_intf, "Out of memory");
        return VLC_ENOMEM;
    }
    memset( p_intf->p_sys, 0, sizeof( intf_sys_t ) );

    p_intf->p_sys->p_playlist = pl_Yield( p_intf );
    p_intf->p_sys->p_sub = msg_Subscribe( p_intf, MSG_QUEUE_NORMAL );

    p_intf->b_play = VLC_TRUE;

    return VLC_SUCCESS;
}

static int OpenDialogs( vlc_object_t *p_this )
{
    intf_thread_t *p_intf = (intf_thread_t *)p_this;
    int val = Open( p_this );
    if( val )
        return val;

    p_intf->pf_show_dialog = ShowDialog;
    return VLC_SUCCESS;
}

static void Close( vlc_object_t *p_this )
{
    intf_thread_t *p_intf = (intf_thread_t *)p_this;
    vlc_mutex_lock( &p_intf->object_lock );
    p_intf->b_dead = VLC_TRUE;
    vlc_mutex_unlock( &p_intf->object_lock );

    vlc_object_release( p_intf->p_sys->p_playlist );
    msg_Unsubscribe( p_intf, p_intf->p_sys->p_sub );
    free( p_intf->p_sys );
}

/*****************************************************************************
 * Initialize the interface or the dialogs provider
 *****************************************************************************/
static void Run( intf_thread_t *p_intf )
{
    if( p_intf->pf_show_dialog )
    {
        if( vlc_thread_create( p_intf, "Qt dialogs", Init, 0, VLC_TRUE ) )
            msg_Err( p_intf, "failed to create Qt dialogs thread" );
    }
    else
        Init( p_intf );
}

static void Init( intf_thread_t *p_intf )
{
    char dummy[] = "";
    char *argv[] = { dummy };
    int argc = 1;

    Q_INIT_RESOURCE( vlc );
    QApplication *app = new QApplication( argc, argv , true );
    app->setWindowIcon( QIcon( QPixmap(vlc_xpm) ) );
    p_intf->p_sys->p_app = app;

#ifndef WIN32
    /* kludge:
     * forces plastique style as cleanlooks bugs on gnome */
    QPlastiqueStyle *plastique = new QPlastiqueStyle;
    app->setStyle( plastique );
#endif

    // Initialize timers
    DialogsProvider::getInstance( p_intf );

    // Normal interface
    if( !p_intf->pf_show_dialog )
    {
        MainInterface *p_mi = new MainInterface( p_intf );
        p_intf->p_sys->p_mi = p_mi;
        p_mi->show();
    }

    if( p_intf->pf_show_dialog )
        vlc_thread_ready( p_intf );

    /* Start playing if needed */
    if( !p_intf->pf_show_dialog && p_intf->b_play )
    {
        playlist_Control( THEPL, PLAYLIST_AUTOPLAY, VLC_FALSE );
    }

    p_intf->pf_show_dialog = ShowDialog;

    app->setQuitOnLastWindowClosed( false );
    app->exec();
    MainInputManager::killInstance();
    DialogsProvider::killInstance();
    delete p_intf->p_sys->p_mi;
}

/*****************************************************************************
 * Callback to show a dialog
 *****************************************************************************/
static void ShowDialog( intf_thread_t *p_intf, int i_dialog_event, int i_arg,
                        intf_dialog_args_t *p_arg )
{
    DialogEvent *event = new DialogEvent( i_dialog_event, i_arg, p_arg );
    QApplication::postEvent( THEDP, static_cast<QEvent*>(event) );
}

/*****************************************************************************
 * PopupMenuCB: callback to show the popupmenu.
 *  We don't show the menu directly here because we don't want the
 *  caller to block for a too long time.
 *****************************************************************************/
static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
                        vlc_value_t old_val, vlc_value_t new_val, void *param )
{
    intf_thread_t *p_intf = (intf_thread_t *)param;
    ShowDialog( p_intf, INTF_DIALOG_POPUPMENU, new_val.b_bool, 0 );
    return VLC_SUCCESS;
}
<commit_msg>Fix use of qcleanlooks style<commit_after>/*****************************************************************************
 * qt4.cpp : QT4 interface
 ****************************************************************************
 * Copyright (C) 2006-2007 the VideoLAN team
 * $Id$
 *
 * Authors: Clément Stenac <zorglub@videolan.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#include <QApplication>

#include "qt4.hpp"
#include "dialogs_provider.hpp"
#include "input_manager.hpp"
#include "main_interface.hpp"

#include "../../../share/vlc32x32.xpm"

/*****************************************************************************
 * Local prototypes.
 *****************************************************************************/
static int  Open         ( vlc_object_t * );
static void Close        ( vlc_object_t * );
static int  OpenDialogs  ( vlc_object_t * );
static void Run          ( intf_thread_t * );
static void Init         ( intf_thread_t * );
static void ShowDialog   ( intf_thread_t *, int, int, intf_dialog_args_t * );

/*****************************************************************************
 * Module descriptor
 *****************************************************************************/
#define ALWAYS_VIDEO_TEXT N_("Always show a video screen, with a cone " \
                                "when there is audio only.")
#define ALWAYS_VIDEO_LONGTEXT N_("Start VLC with a cone image, and display it" \
                                   " when there is no video track. " \
                                    "Visualisations are enabled." )

#define ADVANCED_PREFS_TEXT N_("Show advanced prefs over simple")
#define ADVANCED_PREFS_LONGTEXT N_("Show advanced preferences and not simple" \
                                   "preferences when opening the preferences " \
                                   "dialog.")

#define SYSTRAY_TEXT N_("Show a systray icon to control VLC")
#define SYSTRAY_LONGTEXT N_("Show in the taskbar, a systray icon" \
                            "in order to control VLC media player" \
                            "for basic actions")

#define MINIMIZED_TEXT N_("Start VLC only with a systray icon")
#define MINIMIZED_LONGTEXT N_("When you launch VLC with that option" \
                            "VLC will start just with an icon in" \
                            "your taskbar")

#define TITLE_TEXT N_("Show playing item name in window title")
#define TITLE_LONGTEXT N_("Show the name of the song or video in the " \
                          "controler window title")

#define FILEDIALOG_PATH_TEXT N_("Path to use in file dialog")
#define FILEDIALOG_PATH_LONGTEXT N_("Path to use in file dialog")

#define NOTIFICATION_TEXT N_("Show notification popup on track change")
#define NOTIFICATION_LONGTEXT N_( \
    "Show a notification popup with the artist and track name when " \
    "the current playlist item changes." )

#define ADVANCED_OPTIONS_TEXT N_("Advanced options")
#define ADVANCED_OPTIONS_LONGTEXT N_("Activate by default all the" \
                                     "advanced options for geeks")

#define OPACITY_TEXT N_("Windows opacity between 0.1 and 1.")
#define OPACITY_LONGTEXT N_("Sets the windows opacity between 0.1 and 1 " \
                            "for main interface, playlist and extended panel." \
                            "This options only works with Windows and " \
                            "X11 with composite extensions.")

#define SHOWFLAGS_TEXT N_("Define what columns to show in playlist window")
#define SHOWFLAGS_LONGTEXT N_("Enter the sum of the options that you want: \n" \
            "Title: 1; Duration: 2; Artist: 4; Genre: 8; " \
            "Copyright: 16; Collection/album: 32; Rating: 256." )

vlc_module_begin();
    set_shortname( (char *)"Qt" );
    set_description( (char*)_("Qt interface") );
    set_category( CAT_INTERFACE ) ;
    set_subcategory( SUBCAT_INTERFACE_MAIN );
    set_capability( "interface", 151 );
    set_callbacks( Open, Close );

    set_program( "qvlc" );
    add_shortcut("qt");

    add_submodule();
        set_description( "Dialogs provider" );
        set_capability( "dialogs provider", 51 );
        add_bool( "qt-always-video", VLC_FALSE, NULL, ALWAYS_VIDEO_TEXT,
                ALWAYS_VIDEO_LONGTEXT, VLC_TRUE );
        add_bool( "qt-advanced-pref", VLC_FALSE, NULL, ADVANCED_PREFS_TEXT,
                ADVANCED_PREFS_LONGTEXT, VLC_FALSE );
        add_bool( "qt-system-tray", VLC_TRUE, NULL, SYSTRAY_TEXT,
                SYSTRAY_LONGTEXT, VLC_FALSE);
        add_bool( "qt-start-minimized", VLC_FALSE, NULL, MINIMIZED_TEXT,
                MINIMIZED_LONGTEXT, VLC_TRUE);
        add_bool( "qt-name-in-title", VLC_TRUE, NULL, TITLE_TEXT,
                  TITLE_LONGTEXT, VLC_FALSE );
        add_string( "qt-filedialog-path", NULL, NULL, FILEDIALOG_PATH_TEXT,
                FILEDIALOG_PATH_LONGTEXT, VLC_TRUE);
            change_autosave();
            change_internal();
        add_bool( "qt-notification", VLC_TRUE, NULL, NOTIFICATION_TEXT,
                  NOTIFICATION_LONGTEXT, VLC_FALSE );
        add_float_with_range( "qt-opacity", 1., 0.1, 1., NULL, OPACITY_TEXT,
                  OPACITY_LONGTEXT, VLC_FALSE );
        add_bool( "qt-adv-options", VLC_FALSE, NULL, ADVANCED_OPTIONS_TEXT,
                  ADVANCED_OPTIONS_LONGTEXT, VLC_TRUE );
        add_integer( "qt-pl-showflags",
                VLC_META_ENGINE_ARTIST|VLC_META_ENGINE_TITLE|
                VLC_META_ENGINE_DURATION|VLC_META_ENGINE_COLLECTION,
                NULL, SHOWFLAGS_TEXT,
                SHOWFLAGS_LONGTEXT, VLC_TRUE );
        set_callbacks( OpenDialogs, Close );
vlc_module_end();

/*****************************************************************************
 * Module callbacks
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    intf_thread_t *p_intf = (intf_thread_t *)p_this;
    p_intf->pf_run = Run;
#if defined HAVE_GETENV && defined Q_WS_X11
    if( !getenv( "DISPLAY" ) )
    {
        msg_Err(p_intf, "no X server");
        return VLC_EGENERIC;
    }
#endif
    p_intf->p_sys = (intf_sys_t *)malloc(sizeof( intf_sys_t ) );
    if( !p_intf->p_sys )
    {
        msg_Err(p_intf, "Out of memory");
        return VLC_ENOMEM;
    }
    memset( p_intf->p_sys, 0, sizeof( intf_sys_t ) );

    p_intf->p_sys->p_playlist = pl_Yield( p_intf );
    p_intf->p_sys->p_sub = msg_Subscribe( p_intf, MSG_QUEUE_NORMAL );

    p_intf->b_play = VLC_TRUE;

    return VLC_SUCCESS;
}

static int OpenDialogs( vlc_object_t *p_this )
{
    intf_thread_t *p_intf = (intf_thread_t *)p_this;
    int val = Open( p_this );
    if( val )
        return val;

    p_intf->pf_show_dialog = ShowDialog;
    return VLC_SUCCESS;
}

static void Close( vlc_object_t *p_this )
{
    intf_thread_t *p_intf = (intf_thread_t *)p_this;
    vlc_mutex_lock( &p_intf->object_lock );
    p_intf->b_dead = VLC_TRUE;
    vlc_mutex_unlock( &p_intf->object_lock );

    vlc_object_release( p_intf->p_sys->p_playlist );
    msg_Unsubscribe( p_intf, p_intf->p_sys->p_sub );
    free( p_intf->p_sys );
}

/*****************************************************************************
 * Initialize the interface or the dialogs provider
 *****************************************************************************/
static void Run( intf_thread_t *p_intf )
{
    if( p_intf->pf_show_dialog )
    {
        if( vlc_thread_create( p_intf, "Qt dialogs", Init, 0, VLC_TRUE ) )
            msg_Err( p_intf, "failed to create Qt dialogs thread" );
    }
    else
        Init( p_intf );
}

static void Init( intf_thread_t *p_intf )
{
    char dummy[] = "";
    char *argv[] = { dummy };
    int argc = 1;

    Q_INIT_RESOURCE( vlc );
#ifndef WIN32
    /* KLUDGE:
     * disables icon theme use because that makes cleanlook style bug
     * see commits 21610 21622 21654 for reference */
    QApplication::setDesktopSettingsAware(false);
#endif
    QApplication *app = new QApplication( argc, argv , true );
    app->setWindowIcon( QIcon( QPixmap(vlc_xpm) ) );
    p_intf->p_sys->p_app = app;

    // Initialize timers
    DialogsProvider::getInstance( p_intf );

    // Normal interface
    if( !p_intf->pf_show_dialog )
    {
        MainInterface *p_mi = new MainInterface( p_intf );
        p_intf->p_sys->p_mi = p_mi;
        p_mi->show();
    }

    if( p_intf->pf_show_dialog )
        vlc_thread_ready( p_intf );

    /* Start playing if needed */
    if( !p_intf->pf_show_dialog && p_intf->b_play )
    {
        playlist_Control( THEPL, PLAYLIST_AUTOPLAY, VLC_FALSE );
    }

    p_intf->pf_show_dialog = ShowDialog;

    app->setQuitOnLastWindowClosed( false );
    app->exec();
    MainInputManager::killInstance();
    DialogsProvider::killInstance();
    delete p_intf->p_sys->p_mi;
}

/*****************************************************************************
 * Callback to show a dialog
 *****************************************************************************/
static void ShowDialog( intf_thread_t *p_intf, int i_dialog_event, int i_arg,
                        intf_dialog_args_t *p_arg )
{
    DialogEvent *event = new DialogEvent( i_dialog_event, i_arg, p_arg );
    QApplication::postEvent( THEDP, static_cast<QEvent*>(event) );
}

/*****************************************************************************
 * PopupMenuCB: callback to show the popupmenu.
 *  We don't show the menu directly here because we don't want the
 *  caller to block for a too long time.
 *****************************************************************************/
static int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,
                        vlc_value_t old_val, vlc_value_t new_val, void *param )
{
    intf_thread_t *p_intf = (intf_thread_t *)param;
    ShowDialog( p_intf, INTF_DIALOG_POPUPMENU, new_val.b_bool, 0 );
    return VLC_SUCCESS;
}
<|endoftext|>


<commit_before>// vim: set sts=2 sw=2 et:
// encoding: utf-8
//
// Copyleft 2011 RIME Developers
// License: GPLv3
//
// 2011-07-10 GONG Chen <chen.sst@gmail.com>
//
#include <boost/algorithm/string.hpp>
#include <boost/foreach.hpp>
#include <rime/candidate.h>
#include <rime/config.h>
#include <rime/context.h>
#include <rime/engine.h>
#include <rime/schema.h>
#include <rime/segmentation.h>
#include <rime/translation.h>
#include <rime/dict/dictionary.h>
#include <rime/impl/table_translator.h>
#include <rime/impl/translator_commons.h>

namespace rime {

class LazyTableTranslation : public TableTranslation {
 public:
  static const size_t kInitialSearchLimit = 10;
  static const size_t kExpandingFactor = 10;

  LazyTableTranslation(const std::string &input,
                       size_t start, size_t end,
                       const std::string &preedit,
                       Projection *comment_formatter,
                       Dictionary *dict);
  virtual bool Next();

 private:
  Dictionary *dict_;
  size_t limit_;
};

LazyTableTranslation::LazyTableTranslation(const std::string &input,
                                           size_t start, size_t end,
                                           const std::string &preedit,
                                           Projection *comment_formatter,
                                           Dictionary *dict)
    : TableTranslation(input, start, end, preedit, comment_formatter),
      dict_(dict), limit_(kInitialSearchLimit) {
  dict->LookupWords(&iter_, input, true, kInitialSearchLimit);
  set_exhausted(iter_.exhausted());
}

bool LazyTableTranslation::Next() {
  if (exhausted())
    return false;
  iter_.Next();
  if (limit_ > 0 && iter_.exhausted()) {
    limit_ *= kExpandingFactor;
    size_t previous_entry_count = iter_.entry_count();
    EZDBGONLYLOGGERPRINT("fetching more entries: limit = %d, count = %d.",
                         limit_, previous_entry_count);
    DictEntryIterator more;
    if (dict_ && dict_->LookupWords(&more, input_, true, limit_) < limit_) {
      EZDBGONLYLOGGERPRINT("all entries obtained.");
      limit_ = 0;  // no more try
    }
    if (more.entry_count() > previous_entry_count) {
      more.Skip(previous_entry_count);
      iter_ = more;
    }
  }
  set_exhausted(iter_.exhausted());
  return true;
}

TableTranslator::TableTranslator(Engine *engine)
    : Translator(engine),
      enable_completion_(true),
      enable_charset_filter_(false) {
  if (!engine) return;

  Config *config = engine->schema()->config();
  if (config) {
    config->GetString("speller/delimiter", &delimiters_);
    config->GetBool("translator/enable_completion", &enable_completion_);
    config->GetBool("translator/enable_charset_filter",
                    &enable_charset_filter_);
    preedit_formatter_.Load(config->GetList("translator/preedit_format"));
    comment_formatter_.Load(config->GetList("translator/comment_format"));
  }
  if (delimiters_.empty()) {
    delimiters_ = " ";
  }

  Dictionary::Component *component = Dictionary::Require("dictionary");
  if (!component) return;
  dict_.reset(component->Create(engine->schema()));
  if (dict_)
    dict_->Load();
}

TableTranslator::~TableTranslator() {
}

shared_ptr<Translation> TableTranslator::Query(const std::string &input,
                                               const Segment &segment,
                                               std::string* prompt) {
  if (!dict_ || !dict_->loaded())
    return shared_ptr<Translation>();
  if (!segment.HasTag("abc"))
    return shared_ptr<Translation>();
  EZDBGONLYLOGGERPRINT("input = '%s', [%d, %d)",
                       input.c_str(), segment.start, segment.end);

  std::string preedit(input);
  preedit_formatter_.Apply(&preedit);

  std::string code(input);
  boost::trim_right_if(code, boost::is_any_of(delimiters_));

  shared_ptr<Translation> translation;
  if (enable_completion_) {
    translation = boost::make_shared<LazyTableTranslation>(
        code,
        segment.start,
        segment.start + input.length(),
        preedit,
        &comment_formatter_,
        dict_.get());
  }
  else {
    DictEntryIterator iter;
    dict_->LookupWords(&iter, code, false);
    if (!iter.exhausted())
      translation = boost::make_shared<TableTranslation>(
          iter,
          code,
          segment.start,
          segment.start + input.length(),
          preedit,
          &comment_formatter_);
  }

  if (translation) {
    bool filter_by_charset = enable_charset_filter_ &&
        !engine_->context()->get_option("extended_charset");
    if (filter_by_charset) {
      translation = make_shared<CharsetFilter>(translation);
    }
  }
  if (!translation || translation->exhausted()) {
    translation = MakeSentence(input, segment.start);
  }
  return translation;
}

class SentenceTranslation : public Translation {
 public:
  SentenceTranslation(shared_ptr<Sentence> sentence,
                      DictEntryCollector collector,
                      const std::string& input,
                      const std::string& delimiters,
                      size_t start,
                      Projection* preedit_formatter)
      : input_(input), start_(start),
        preedit_formatter_(preedit_formatter) {
    sentence_.swap(sentence);
    collector_.swap(collector);
    PrepareSentence(delimiters);
    set_exhausted(!sentence_ && collector_.empty());
  }

  bool Next() {
    if (sentence_) {
      sentence_.reset();
    }
    else if (!collector_.empty()) {
      DictEntryCollector::reverse_iterator r(collector_.rbegin());
      if (!r->second.Next()) {
        collector_.erase(r->first);
      }
    }
    set_exhausted(!sentence_ && collector_.empty());
    return !exhausted();
  }

  shared_ptr<Candidate> Peek() {
    if (sentence_) {
      return sentence_;
    }
    if (collector_.empty()) {
      return shared_ptr<Candidate>();
    }
    DictEntryCollector::reverse_iterator r(collector_.rbegin());
    shared_ptr<DictEntry> entry(r->second.Peek());
    shared_ptr<ZhCandidate> result = boost::make_shared<ZhCandidate>(
        start_,
        start_ + r->first,
        entry);
    if (preedit_formatter_) {
      std::string preedit(input_.substr(0, r->first));
      preedit_formatter_->Apply(&preedit);
      result->set_preedit(preedit);
    }
    return result;
  }

 protected:
  void PrepareSentence(const std::string& delimiters);

  shared_ptr<Sentence> sentence_;
  DictEntryCollector collector_;
  std::string input_;
  size_t start_;
  Projection* preedit_formatter_;
};

void SentenceTranslation::PrepareSentence(const std::string& delimiters) {
  if (!sentence_) return;
  sentence_->Offset(start_);
  std::string preedit(input_);
  // split syllables
  size_t pos = 0;
  BOOST_FOREACH(int len, sentence_->syllable_lengths()) {
    if (pos > 0 &&
        delimiters.find(input_[pos - 1]) == std::string::npos) {
      preedit.insert(pos, 1, ' ');
      ++pos;
    }
    pos += len;
  }
  if (preedit_formatter_) {
    preedit_formatter_->Apply(&preedit);
  }
  sentence_->set_preedit(preedit);
}

shared_ptr<Translation> TableTranslator::MakeSentence(const std::string& input,
                                                      size_t start) {
  bool filter_by_charset = enable_charset_filter_ &&
      !engine_->context()->get_option("extended_charset");
  DictEntryCollector collector;
  std::map<int, shared_ptr<Sentence> > sentences;
  sentences[0] = make_shared<Sentence>();
  for (size_t start_pos = 0; start_pos < input.length(); ++start_pos) {
    if (sentences.find(start_pos) == sentences.end())
      continue;
    std::vector<Prism::Match> matches;
    dict_->prism()->CommonPrefixSearch(input.substr(start_pos), &matches);
    if (matches.empty()) continue;
    BOOST_REVERSE_FOREACH(const Prism::Match &m, matches) {
      if (m.length == 0) continue;
      DictEntryIterator iter;
      dict_->LookupWords(&iter, input.substr(start_pos, m.length), false);
      if (iter.exhausted()) continue;
      size_t end_pos = start_pos + m.length;
      // consume trailing delimiters
      while (end_pos < input.length() &&
             delimiters_.find(input[end_pos]) != std::string::npos)
        ++end_pos;
      shared_ptr<Sentence> new_sentence =
          make_shared<Sentence>(*sentences[start_pos]);
      // extend the sentence with the first suitable entry
      shared_ptr<DictEntry> entry = iter.Peek();
      if (filter_by_charset) {
        while (!CharsetFilter::Passed(entry->text) &&
               iter.Next()) {
          entry = iter.Peek();
        }
        if (iter.exhausted()) continue;
      }
      new_sentence->Extend(*entry, end_pos);
      // compare and update sentences
      if (sentences.find(end_pos) == sentences.end() ||
          sentences[end_pos]->weight() <= new_sentence->weight()) {
        sentences[end_pos] = new_sentence;
      }
      // also provide words for manual composition
      if (start_pos == 0) {
        collector[end_pos] = iter;
      }
    }
  }
  shared_ptr<Translation> result;
  if (sentences.find(input.length()) != sentences.end()) {
    result = boost::make_shared<SentenceTranslation>(sentences[input.length()],
                                                     collector,
                                                     input,
                                                     delimiters_,
                                                     start,
                                                     &preedit_formatter_);
    if (result && filter_by_charset) {
      result = make_shared<CharsetFilter>(result);
    }
  }
  return result;
}

}  // namespace rime
<commit_msg>Show Unity symbol.<commit_after>// vim: set sts=2 sw=2 et:
// encoding: utf-8
//
// Copyleft 2011 RIME Developers
// License: GPLv3
//
// 2011-07-10 GONG Chen <chen.sst@gmail.com>
//
#include <boost/algorithm/string.hpp>
#include <boost/foreach.hpp>
#include <rime/candidate.h>
#include <rime/config.h>
#include <rime/context.h>
#include <rime/engine.h>
#include <rime/schema.h>
#include <rime/segmentation.h>
#include <rime/translation.h>
#include <rime/dict/dictionary.h>
#include <rime/impl/table_translator.h>
#include <rime/impl/translator_commons.h>

static const char* kUnityTableEncoder = " \xe2\x98\xaf ";

namespace rime {

class LazyTableTranslation : public TableTranslation {
 public:
  static const size_t kInitialSearchLimit = 10;
  static const size_t kExpandingFactor = 10;

  LazyTableTranslation(const std::string &input,
                       size_t start, size_t end,
                       const std::string &preedit,
                       Projection *comment_formatter,
                       Dictionary *dict);
  virtual bool Next();

 private:
  Dictionary *dict_;
  size_t limit_;
};

LazyTableTranslation::LazyTableTranslation(const std::string &input,
                                           size_t start, size_t end,
                                           const std::string &preedit,
                                           Projection *comment_formatter,
                                           Dictionary *dict)
    : TableTranslation(input, start, end, preedit, comment_formatter),
      dict_(dict), limit_(kInitialSearchLimit) {
  dict->LookupWords(&iter_, input, true, kInitialSearchLimit);
  set_exhausted(iter_.exhausted());
}

bool LazyTableTranslation::Next() {
  if (exhausted())
    return false;
  iter_.Next();
  if (limit_ > 0 && iter_.exhausted()) {
    limit_ *= kExpandingFactor;
    size_t previous_entry_count = iter_.entry_count();
    EZDBGONLYLOGGERPRINT("fetching more entries: limit = %d, count = %d.",
                         limit_, previous_entry_count);
    DictEntryIterator more;
    if (dict_ && dict_->LookupWords(&more, input_, true, limit_) < limit_) {
      EZDBGONLYLOGGERPRINT("all entries obtained.");
      limit_ = 0;  // no more try
    }
    if (more.entry_count() > previous_entry_count) {
      more.Skip(previous_entry_count);
      iter_ = more;
    }
  }
  set_exhausted(iter_.exhausted());
  return true;
}

TableTranslator::TableTranslator(Engine *engine)
    : Translator(engine),
      enable_completion_(true),
      enable_charset_filter_(false) {
  if (!engine) return;

  Config *config = engine->schema()->config();
  if (config) {
    config->GetString("speller/delimiter", &delimiters_);
    config->GetBool("translator/enable_completion", &enable_completion_);
    config->GetBool("translator/enable_charset_filter",
                    &enable_charset_filter_);
    preedit_formatter_.Load(config->GetList("translator/preedit_format"));
    comment_formatter_.Load(config->GetList("translator/comment_format"));
  }
  if (delimiters_.empty()) {
    delimiters_ = " ";
  }

  Dictionary::Component *component = Dictionary::Require("dictionary");
  if (!component) return;
  dict_.reset(component->Create(engine->schema()));
  if (dict_)
    dict_->Load();
}

TableTranslator::~TableTranslator() {
}

shared_ptr<Translation> TableTranslator::Query(const std::string &input,
                                               const Segment &segment,
                                               std::string* prompt) {
  if (!dict_ || !dict_->loaded())
    return shared_ptr<Translation>();
  if (!segment.HasTag("abc"))
    return shared_ptr<Translation>();
  EZDBGONLYLOGGERPRINT("input = '%s', [%d, %d)",
                       input.c_str(), segment.start, segment.end);

  std::string preedit(input);
  preedit_formatter_.Apply(&preedit);

  std::string code(input);
  boost::trim_right_if(code, boost::is_any_of(delimiters_));

  shared_ptr<Translation> translation;
  if (enable_completion_) {
    translation = boost::make_shared<LazyTableTranslation>(
        code,
        segment.start,
        segment.start + input.length(),
        preedit,
        &comment_formatter_,
        dict_.get());
  }
  else {
    DictEntryIterator iter;
    dict_->LookupWords(&iter, code, false);
    if (!iter.exhausted())
      translation = boost::make_shared<TableTranslation>(
          iter,
          code,
          segment.start,
          segment.start + input.length(),
          preedit,
          &comment_formatter_);
  }

  if (translation) {
    bool filter_by_charset = enable_charset_filter_ &&
        !engine_->context()->get_option("extended_charset");
    if (filter_by_charset) {
      translation = make_shared<CharsetFilter>(translation);
    }
  }
  if (!translation || translation->exhausted()) {
    translation = MakeSentence(input, segment.start);
  }
  return translation;
}

class SentenceTranslation : public Translation {
 public:
  SentenceTranslation(shared_ptr<Sentence> sentence,
                      DictEntryCollector collector,
                      const std::string& input,
                      const std::string& delimiters,
                      size_t start,
                      Projection* preedit_formatter)
      : input_(input), start_(start),
        preedit_formatter_(preedit_formatter) {
    sentence_.swap(sentence);
    collector_.swap(collector);
    PrepareSentence(delimiters);
    set_exhausted(!sentence_ && collector_.empty());
  }

  bool Next() {
    if (sentence_) {
      sentence_.reset();
    }
    else if (!collector_.empty()) {
      DictEntryCollector::reverse_iterator r(collector_.rbegin());
      if (!r->second.Next()) {
        collector_.erase(r->first);
      }
    }
    set_exhausted(!sentence_ && collector_.empty());
    return !exhausted();
  }

  shared_ptr<Candidate> Peek() {
    if (sentence_) {
      return sentence_;
    }
    if (collector_.empty()) {
      return shared_ptr<Candidate>();
    }
    DictEntryCollector::reverse_iterator r(collector_.rbegin());
    shared_ptr<DictEntry> entry(r->second.Peek());
    shared_ptr<ZhCandidate> result = boost::make_shared<ZhCandidate>(
        start_,
        start_ + r->first,
        entry);
    if (preedit_formatter_) {
      std::string preedit(input_.substr(0, r->first));
      preedit_formatter_->Apply(&preedit);
      result->set_preedit(preedit);
    }
    return result;
  }

 protected:
  void PrepareSentence(const std::string& delimiters);

  shared_ptr<Sentence> sentence_;
  DictEntryCollector collector_;
  std::string input_;
  size_t start_;
  Projection* preedit_formatter_;
};

void SentenceTranslation::PrepareSentence(const std::string& delimiters) {
  if (!sentence_) return;
  sentence_->Offset(start_);
  std::string preedit(input_);
  // split syllables
  size_t pos = 0;
  BOOST_FOREACH(int len, sentence_->syllable_lengths()) {
    if (pos > 0 &&
        delimiters.find(input_[pos - 1]) == std::string::npos) {
      preedit.insert(pos, 1, ' ');
      ++pos;
    }
    pos += len;
  }
  if (preedit_formatter_) {
    preedit_formatter_->Apply(&preedit);
  }
  sentence_->set_preedit(preedit);
  sentence_->set_comment(kUnityTableEncoder);
}

shared_ptr<Translation> TableTranslator::MakeSentence(const std::string& input,
                                                      size_t start) {
  bool filter_by_charset = enable_charset_filter_ &&
      !engine_->context()->get_option("extended_charset");
  DictEntryCollector collector;
  std::map<int, shared_ptr<Sentence> > sentences;
  sentences[0] = make_shared<Sentence>();
  for (size_t start_pos = 0; start_pos < input.length(); ++start_pos) {
    if (sentences.find(start_pos) == sentences.end())
      continue;
    std::vector<Prism::Match> matches;
    dict_->prism()->CommonPrefixSearch(input.substr(start_pos), &matches);
    if (matches.empty()) continue;
    BOOST_REVERSE_FOREACH(const Prism::Match &m, matches) {
      if (m.length == 0) continue;
      DictEntryIterator iter;
      dict_->LookupWords(&iter, input.substr(start_pos, m.length), false);
      if (iter.exhausted()) continue;
      size_t end_pos = start_pos + m.length;
      // consume trailing delimiters
      while (end_pos < input.length() &&
             delimiters_.find(input[end_pos]) != std::string::npos)
        ++end_pos;
      shared_ptr<Sentence> new_sentence =
          make_shared<Sentence>(*sentences[start_pos]);
      // extend the sentence with the first suitable entry
      shared_ptr<DictEntry> entry = iter.Peek();
      if (filter_by_charset) {
        while (!CharsetFilter::Passed(entry->text) &&
               iter.Next()) {
          entry = iter.Peek();
        }
        if (iter.exhausted()) continue;
      }
      new_sentence->Extend(*entry, end_pos);
      // compare and update sentences
      if (sentences.find(end_pos) == sentences.end() ||
          sentences[end_pos]->weight() <= new_sentence->weight()) {
        sentences[end_pos] = new_sentence;
      }
      // also provide words for manual composition
      if (start_pos == 0) {
        collector[end_pos] = iter;
      }
    }
  }
  shared_ptr<Translation> result;
  if (sentences.find(input.length()) != sentences.end()) {
    result = boost::make_shared<SentenceTranslation>(sentences[input.length()],
                                                     collector,
                                                     input,
                                                     delimiters_,
                                                     start,
                                                     &preedit_formatter_);
    if (result && filter_by_charset) {
      result = make_shared<CharsetFilter>(result);
    }
  }
  return result;
}

}  // namespace rime
<|endoftext|>


<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
*                (c) 2006-2011 INRIA, USTL, UJF, CNRS, MGH                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                              SOFA :: Framework                              *
*                                                                             *
* Authors: The SOFA Team (see Authors.txt)                                    *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#define SOFA_CORE_OBJECTMODEL_DATA_CPP

#include <sofa/core/objectmodel/Data.h>
#include <string>

namespace sofa
{

namespace core
{

namespace objectmodel
{

/// Specialization for reading strings
template<>
inline
bool SOFA_CORE_API TData<std::string>::read( const std::string& str )
{
    virtualSetValue(str);
    return true;
}

/// Specialization for reading booleans
template<>
inline
bool SOFA_CORE_API TData<bool>::read( const std::string& str )
{
    if (str.empty())
        return false;
    bool val;
    if (str[0] == 'T' || str[0] == 't')
        val = true;
    else if (str[0] == 'F' || str[0] == 'f')
        val = false;
    else if ((str[0] >= '0' && str[0] <= '9') || str[0] == '-')
        val = (atoi(str.c_str()) != 0);
    else
        return false;
    virtualSetValue(val);
    return true;
}

#if defined(SOFA_EXTERN_TEMPLATE)
template class SOFA_CORE_API TData< std::string >;
template class SOFA_CORE_API Data< std::string >;
template class SOFA_CORE_API TData< sofa::helper::vector<std::string> >;
template class SOFA_CORE_API Data< sofa::helper::vector<std::string> >;
template class SOFA_CORE_API TData< bool >;
template class SOFA_CORE_API Data< bool >;
#endif

} // objectmodel

} // core

} // sofa

<commit_msg>r10863/sofa : push daecc9e..42fc070<commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
*                (c) 2006-2011 INRIA, USTL, UJF, CNRS, MGH                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                              SOFA :: Framework                              *
*                                                                             *
* Authors: The SOFA Team (see Authors.txt)                                    *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#define SOFA_CORE_OBJECTMODEL_DATA_CPP

#include <sofa/core/objectmodel/Data.h>
#include <string>

namespace sofa
{

namespace core
{

namespace objectmodel
{

/// Specialization for reading strings
template<>
inline
bool SOFA_CORE_API TData<std::string>::read( const std::string& str )
{
    virtualSetValue(str);
    return true;
}

/// Specialization for reading booleans
template<>
inline
bool SOFA_CORE_API TData<bool>::read( const std::string& str )
{
    if (str.empty())
        return false;
    bool val;
    if (str[0] == 'T' || str[0] == 't')
        val = true;
    else if (str[0] == 'F' || str[0] == 'f')
        val = false;
    else if ((str[0] >= '0' && str[0] <= '9') || str[0] == '-')
        val = (atoi(str.c_str()) != 0);
    else
        return false;
    virtualSetValue(val);
    return true;
}

template class SOFA_CORE_API TData< std::string >;
template class SOFA_CORE_API Data< std::string >;
template class SOFA_CORE_API TData< sofa::helper::vector<std::string> >;
template class SOFA_CORE_API Data< sofa::helper::vector<std::string> >;
template class SOFA_CORE_API TData< bool >;
template class SOFA_CORE_API Data< bool >;

} // objectmodel

} // core

} // sofa

<|endoftext|>


<commit_before><commit_msg>specify c13 abundance as a perentage<commit_after><|endoftext|>


<commit_before>/******************************************************************************
 * $Id: OGRMongoLayer.cpp 23367 2011-11-12 22:46:13Z rouault $
 *
 * Project:  OpenGIS Simple Features Reference Implementation
 * Purpose:  Implementation of OGRMongoLayer class (OGR GeoJSON Driver).
 * Author:   Mateusz Loskot, mateusz@loskot.net
 *
 ******************************************************************************
 * Copyright (c) 2007, Mateusz Loskot
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 ****************************************************************************/
#define OGR_Mongo_H_INCLUDED
#ifdef OGR_Mongo_H_INCLUDED
#include "ogr_mongo.h"
#include "ogrgeojsonwriter.h"
#include "jsonc/json.h" // JSON-C
#include <algorithm> // for_each, find_if

/* Remove annoying warnings Microsoft Visual C++ */
#if defined(_MSC_VER)
#  pragma warning(disable:4512)
#endif

/************************************************************************/
/*                       STATIC MEMBERS DEFINITION                      */
/************************************************************************/

const char* const OGRMongoLayer::DefaultName = "OGRGeoJSON";
const char* const OGRMongoLayer::DefaultFIDColumn = "id";
const OGRwkbGeometryType OGRMongoLayer::DefaultGeometryType = wkbUnknown;

/************************************************************************/
/*                           OGRMongoLayer                            */
/************************************************************************/

OGRMongoLayer::OGRMongoLayer( const char* pszName,
                                  OGRSpatialReference* poSRSIn,
                                  OGRwkbGeometryType eGType,
                                  char** papszOptions,
                                  OGRMongoDataSource* poDS )
    : iterCurrent_( seqFeatures_.end() ), poDS_( poDS ), poFeatureDefn_(new OGRFeatureDefn( pszName ) ), poSRS_( NULL ), nOutCounter_( 0 )
{
    bWriteBBOX = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "WRITE_BBOX", "FALSE"));
    bBBOX3D = FALSE;

    CPLAssert( NULL != poDS_ );
    CPLAssert( NULL != poFeatureDefn_ );

    poFeatureDefn_->Reference();
    poFeatureDefn_->SetGeomType( eGType );

    if( NULL != poSRSIn )
    {
        SetSpatialRef( poSRSIn );
    }

    nCoordPrecision = atoi(CSLFetchNameValueDef(papszOptions, "COORDINATE_PRECISION", "-1"));
}

//OGRMongoLayer::OGRMongoLayer( OGRGeoJSONLayer *GeoJSONLayer)
//	: iterCurrent_( seqFeatures_.end() ), poDS_( poDS ), poFeatureDefn_(new OGRFeatureDefn( pszName ) ), poSRS_( NULL ), nOutCounter_( 0 )
//{
//	typedef std::vector<OGRFeature*> FeaturesSeq;
//	FeaturesSeq seqFeatures_;
//	FeaturesSeq::iterator iterCurrent_;
//
//	OGRMongoDataSource* poDS_;
//	OGRFeatureDefn* poFeatureDefn_;
//	OGRSpatialReference* poSRS_;
//	CPLString sFIDColumn_;
//	int nOutCounter_;
//
//	int bWriteBBOX;
//	int bBBOX3D;
//	OGREnvelope3D sEnvelopeLayer;
//
//	int nCoordPrecision;
//
//	bWriteBBOX = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "WRITE_BBOX", "FALSE"));
//	bBBOX3D = FALSE;
//
//	CPLAssert( NULL != poDS_ );
//	CPLAssert( NULL != poFeatureDefn_ );
//
//	poFeatureDefn_->Reference();
//	poFeatureDefn_->SetGeomType( eGType );
//
//	if( NULL != poSRSIn )
//	{
//		SetSpatialRef( poSRSIn );
//	}
//
//	nCoordPrecision = atoi(CSLFetchNameValueDef(papszOptions, "COORDINATE_PRECISION", "-1"));
//}

/************************************************************************/
/*                          ~OGRMongoLayer                            */
/************************************************************************/

OGRMongoLayer::~OGRMongoLayer()
{
	/*VSILFILE* fp = poDS_->GetOutputFile();
	if( NULL != fp )
	{
	VSIFPrintfL( fp, "\n]" );

	if( bWriteBBOX && sEnvelopeLayer.IsInit() )
	{
	json_object* poObjBBOX = json_object_new_array();
	json_object_array_add(poObjBBOX,
	json_object_new_double_with_precision(sEnvelopeLayer.MinX, nCoordPrecision));
	json_object_array_add(poObjBBOX,
	json_object_new_double_with_precision(sEnvelopeLayer.MinY, nCoordPrecision));
	if( bBBOX3D )
	json_object_array_add(poObjBBOX,
	json_object_new_double_with_precision(sEnvelopeLayer.MinZ, nCoordPrecision));
	json_object_array_add(poObjBBOX,
	json_object_new_double_with_precision(sEnvelopeLayer.MaxX, nCoordPrecision));
	json_object_array_add(poObjBBOX,
	json_object_new_double_with_precision(sEnvelopeLayer.MaxY, nCoordPrecision));
	if( bBBOX3D )
	json_object_array_add(poObjBBOX,
	json_object_new_double_with_precision(sEnvelopeLayer.MaxZ, nCoordPrecision));

	const char* pszBBOX = json_object_to_json_string( poObjBBOX );
	if( poDS_->GetFpOutputIsSeekable() )
	{
	VSIFSeekL(fp, poDS_->GetBBOXInsertLocation(), SEEK_SET);
	if (strlen(pszBBOX) + 9 < SPACE_FOR_BBOX)
	VSIFPrintfL( fp, "\"bbox\": %s,", pszBBOX );
	VSIFSeekL(fp, 0, SEEK_END);
	}
	else
	{
	VSIFPrintfL( fp, ",\n\"bbox\": %s", pszBBOX );
	}

	json_object_put( poObjBBOX );
	}

	VSIFPrintfL( fp, "\n}\n" );
	}*/

    std::for_each(seqFeatures_.begin(), seqFeatures_.end(),
                  OGRFeature::DestroyFeature);

    if( NULL != poFeatureDefn_ )
    {
        poFeatureDefn_->Release();
    }

    if( NULL != poSRS_ )
    {
        poSRS_->Release();
    }
}

/************************************************************************/
/*                           GetLayerDefn                               */
/************************************************************************/

OGRFeatureDefn* OGRMongoLayer::GetLayerDefn()
{
    return poFeatureDefn_;
}

/************************************************************************/
/*                           GetSpatialRef                              */
/************************************************************************/

OGRSpatialReference* OGRMongoLayer::GetSpatialRef()
{
    return poSRS_;
}

void OGRMongoLayer::SetSpatialRef( OGRSpatialReference* poSRSIn )
{
    if( NULL == poSRSIn )
    {
        poSRS_ = NULL;
        // poSRS_ = new OGRSpatialReference();
        // if( OGRERR_NONE != poSRS_->importFromEPSG( 4326 ) )
        // {
        //     delete poSRS_;
        //     poSRS_ = NULL;
        // }
    }
    else
    {
        poSRS_ = poSRSIn->Clone();
    }
}

/************************************************************************/
/*                           GetFeatureCount                            */
/************************************************************************/

int OGRMongoLayer::GetFeatureCount( int bForce )
{
    if (m_poFilterGeom == NULL && m_poAttrQuery == NULL)
        return static_cast<int>( seqFeatures_.size() );
    else
        return OGRLayer::GetFeatureCount(bForce);
}

/************************************************************************/
/*                           ResetReading                               */
/************************************************************************/

void OGRMongoLayer::ResetReading()
{
    iterCurrent_ = seqFeatures_.begin();
}

/************************************************************************/
/*                           GetNextFeature                             */
/************************************************************************/

OGRFeature* OGRMongoLayer::GetNextFeature()
{
    while ( iterCurrent_ != seqFeatures_.end() )
    {
        OGRFeature* poFeature = (*iterCurrent_);
        CPLAssert( NULL != poFeature );
        ++iterCurrent_;

        if((m_poFilterGeom == NULL
            || FilterGeometry( poFeature->GetGeometryRef() ) )
        && (m_poAttrQuery == NULL
            || m_poAttrQuery->Evaluate( poFeature )) )
        {
            OGRFeature* poFeatureCopy = poFeature->Clone();
            CPLAssert( NULL != poFeatureCopy );

            if (poFeatureCopy->GetGeometryRef() != NULL && poSRS_ != NULL)
            {
                poFeatureCopy->GetGeometryRef()->assignSpatialReference( poSRS_ );
            }

            return poFeatureCopy;
        }
    }

    return NULL;
}

/************************************************************************/
/*                           GetFeature                             */
/************************************************************************/

OGRFeature* OGRMongoLayer::GetFeature( long nFID )
{
	OGRFeature* poFeature = NULL;
	poFeature = OGRLayer::GetFeature( nFID );

	return poFeature;
}

/************************************************************************/
/*                           CreateFeature                              */
/************************************************************************/

OGRErr OGRMongoLayer::CreateFeature( OGRFeature* poFeature )
{
    //VSILFILE* fp = poDS_->GetOutputFile();
	//mongo::DBClientConnection * Conn;
	mongo::DBClientConnection Conn;
	std::string	errmsg;
	Conn.connect( poDS_->GetMongoConnString().c_str() , errmsg ) ;

    if( Conn.isFailed() )
    {
        CPLDebug( "GeoJSON", "Target datasource file is invalid." );
        return CE_Failure;
    }

    if( NULL == poFeature )
    {
        CPLDebug( "GeoJSON", "Feature is null" );
        return OGRERR_INVALID_HANDLE;
    }

    json_object* poObj = OGRGeoJSONWriteFeature( poFeature, bWriteBBOX, nCoordPrecision );
    CPLAssert( NULL != poObj );

	const char * strObj=json_object_to_json_string( poObj );
	mongo::BSONObj p = mongo::fromjson(strObj);

	std::string db=poDS_->GetName();
	std::string coll=this->GetName();
	std::string dbcoll=db+"."+coll;
	Conn.insert(dbcoll,p);

    json_object_put( poObj );

    ++nOutCounter_;

    OGRGeometry* poGeometry = poFeature->GetGeometryRef();
    if ( bWriteBBOX && !poGeometry->IsEmpty() )
    {
        OGREnvelope3D sEnvelope;
        poGeometry->getEnvelope(&sEnvelope);

        if( poGeometry->getCoordinateDimension() == 3 )
            bBBOX3D = TRUE;

        sEnvelopeLayer.Merge(sEnvelope);
    }
	//Conn.~DBClientConnection();
    return OGRERR_NONE;
}

OGRErr OGRMongoLayer::CreateField(OGRFieldDefn* poField, int bApproxOK)
{
    UNREFERENCED_PARAM(bApproxOK);

    for( int i = 0; i < poFeatureDefn_->GetFieldCount(); ++i )
    {
        OGRFieldDefn* poDefn = poFeatureDefn_->GetFieldDefn(i);
        CPLAssert( NULL != poDefn );

        if( EQUAL( poDefn->GetNameRef(), poField->GetNameRef() ) )
        {
            CPLDebug( "GeoJSON", "Field '%s' already present in schema",
                      poField->GetNameRef() );

            // TODO - mloskot: Is this return code correct?
            return OGRERR_NONE;
        }
    }

    poFeatureDefn_->AddFieldDefn( poField );

    return OGRERR_NONE;
}

/************************************************************************/
/*                           TestCapability                             */
/************************************************************************/

int OGRMongoLayer::TestCapability( const char* pszCap )
{
    UNREFERENCED_PARAM(pszCap);

    return FALSE;
}

/************************************************************************/
/*                           GetFIDColumn                               */
/************************************************************************/

const char* OGRMongoLayer::GetFIDColumn()
{
	return sFIDColumn_.c_str();
}

/************************************************************************/
/*                           SetFIDColumn                               */
/************************************************************************/

void OGRMongoLayer::SetFIDColumn( const char* pszFIDColumn )
{
	sFIDColumn_ = pszFIDColumn;
}

/************************************************************************/
/*                           AddFeature                                 */
/************************************************************************/

void OGRMongoLayer::AddFeature( OGRFeature* poFeature )
{
    CPLAssert( NULL != poFeature );

    // NOTE - mloskot:
    // Features may not be sorted according to FID values.

    // TODO: Should we check if feature already exists?
    // TODO: Think about sync operation, upload, etc.

    OGRFeature* poNewFeature = NULL;
    poNewFeature = poFeature->Clone();

    if( -1 == poNewFeature->GetFID() )
    {
        int nFID = static_cast<int>(seqFeatures_.size());
        poNewFeature->SetFID( nFID );

        // TODO - mlokot: We need to redesign creation of FID column
        int nField = poNewFeature->GetFieldIndex( DefaultFIDColumn );
        if( -1 != nField )
        {
            poNewFeature->SetField( nField, nFID );
        }
    }

    seqFeatures_.push_back( poNewFeature );
}

/************************************************************************/
/*                           DetectGeometryType                         */
/************************************************************************/

void OGRMongoLayer::DetectGeometryType()
{
    if (poFeatureDefn_->GetGeomType() != wkbUnknown)
        return;

    OGRwkbGeometryType featType = wkbUnknown;
    OGRGeometry* poGeometry = NULL;
    FeaturesSeq::const_iterator it = seqFeatures_.begin();
    FeaturesSeq::const_iterator end = seqFeatures_.end();

    if( it != end )
    {
        poGeometry = (*it)->GetGeometryRef();
        if( NULL != poGeometry )
        {
            featType = poGeometry->getGeometryType();
            if( featType != poFeatureDefn_->GetGeomType() )
            {
                poFeatureDefn_->SetGeomType( featType );
            }
        }
        ++it;
    }

    while( it != end )
    {
        poGeometry = (*it)->GetGeometryRef();
        if( NULL != poGeometry )
        {
            featType = poGeometry->getGeometryType();
            if( featType != poFeatureDefn_->GetGeomType() )
            {
                CPLDebug( "GeoJSON",
                    "Detected layer of mixed-geometry type features." );
                poFeatureDefn_->SetGeomType( DefaultGeometryType );
                break;
            }
        }
        ++it;
    }
}
#endif<commit_msg>Update ogrmongolayer.cpp<commit_after>/******************************************************************************
 * $Id: OGRMongoLayer.cpp 23367 2011-11-12 22:46:13Z rouault $
 *
 * Project:  GDAL Vector spatial data MongoDB Driver
 * Purpose:  Implementation of OGRMongoLayer class.
 * Author:   shuai zhang, zhangshuai.nju@gmail.com
 *
 ******************************************************************************
 * Copyright (c) 2014, shuai zhang
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 ****************************************************************************/
#define OGR_Mongo_H_INCLUDED
#ifdef OGR_Mongo_H_INCLUDED
#include "ogr_mongo.h"
#include "ogrgeojsonwriter.h"
#include "jsonc/json.h" // JSON-C
#include <algorithm> // for_each, find_if

/* Remove annoying warnings Microsoft Visual C++ */
#if defined(_MSC_VER)
#  pragma warning(disable:4512)
#endif

/************************************************************************/
/*                       STATIC MEMBERS DEFINITION                      */
/************************************************************************/

const char* const OGRMongoLayer::DefaultName = "OGRGeoJSON";
const char* const OGRMongoLayer::DefaultFIDColumn = "id";
const OGRwkbGeometryType OGRMongoLayer::DefaultGeometryType = wkbUnknown;

/************************************************************************/
/*                           OGRMongoLayer                            */
/************************************************************************/

OGRMongoLayer::OGRMongoLayer( const char* pszName,
                                  OGRSpatialReference* poSRSIn,
                                  OGRwkbGeometryType eGType,
                                  char** papszOptions,
                                  OGRMongoDataSource* poDS )
    : iterCurrent_( seqFeatures_.end() ), poDS_( poDS ), poFeatureDefn_(new OGRFeatureDefn( pszName ) ), poSRS_( NULL ), nOutCounter_( 0 )
{
    bWriteBBOX = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "WRITE_BBOX", "FALSE"));
    bBBOX3D = FALSE;

    CPLAssert( NULL != poDS_ );
    CPLAssert( NULL != poFeatureDefn_ );

    poFeatureDefn_->Reference();
    poFeatureDefn_->SetGeomType( eGType );

    if( NULL != poSRSIn )
    {
        SetSpatialRef( poSRSIn );
    }

    nCoordPrecision = atoi(CSLFetchNameValueDef(papszOptions, "COORDINATE_PRECISION", "-1"));
}

//OGRMongoLayer::OGRMongoLayer( OGRGeoJSONLayer *GeoJSONLayer)
//	: iterCurrent_( seqFeatures_.end() ), poDS_( poDS ), poFeatureDefn_(new OGRFeatureDefn( pszName ) ), poSRS_( NULL ), nOutCounter_( 0 )
//{
//	typedef std::vector<OGRFeature*> FeaturesSeq;
//	FeaturesSeq seqFeatures_;
//	FeaturesSeq::iterator iterCurrent_;
//
//	OGRMongoDataSource* poDS_;
//	OGRFeatureDefn* poFeatureDefn_;
//	OGRSpatialReference* poSRS_;
//	CPLString sFIDColumn_;
//	int nOutCounter_;
//
//	int bWriteBBOX;
//	int bBBOX3D;
//	OGREnvelope3D sEnvelopeLayer;
//
//	int nCoordPrecision;
//
//	bWriteBBOX = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "WRITE_BBOX", "FALSE"));
//	bBBOX3D = FALSE;
//
//	CPLAssert( NULL != poDS_ );
//	CPLAssert( NULL != poFeatureDefn_ );
//
//	poFeatureDefn_->Reference();
//	poFeatureDefn_->SetGeomType( eGType );
//
//	if( NULL != poSRSIn )
//	{
//		SetSpatialRef( poSRSIn );
//	}
//
//	nCoordPrecision = atoi(CSLFetchNameValueDef(papszOptions, "COORDINATE_PRECISION", "-1"));
//}

/************************************************************************/
/*                          ~OGRMongoLayer                            */
/************************************************************************/

OGRMongoLayer::~OGRMongoLayer()
{
	/*VSILFILE* fp = poDS_->GetOutputFile();
	if( NULL != fp )
	{
	VSIFPrintfL( fp, "\n]" );

	if( bWriteBBOX && sEnvelopeLayer.IsInit() )
	{
	json_object* poObjBBOX = json_object_new_array();
	json_object_array_add(poObjBBOX,
	json_object_new_double_with_precision(sEnvelopeLayer.MinX, nCoordPrecision));
	json_object_array_add(poObjBBOX,
	json_object_new_double_with_precision(sEnvelopeLayer.MinY, nCoordPrecision));
	if( bBBOX3D )
	json_object_array_add(poObjBBOX,
	json_object_new_double_with_precision(sEnvelopeLayer.MinZ, nCoordPrecision));
	json_object_array_add(poObjBBOX,
	json_object_new_double_with_precision(sEnvelopeLayer.MaxX, nCoordPrecision));
	json_object_array_add(poObjBBOX,
	json_object_new_double_with_precision(sEnvelopeLayer.MaxY, nCoordPrecision));
	if( bBBOX3D )
	json_object_array_add(poObjBBOX,
	json_object_new_double_with_precision(sEnvelopeLayer.MaxZ, nCoordPrecision));

	const char* pszBBOX = json_object_to_json_string( poObjBBOX );
	if( poDS_->GetFpOutputIsSeekable() )
	{
	VSIFSeekL(fp, poDS_->GetBBOXInsertLocation(), SEEK_SET);
	if (strlen(pszBBOX) + 9 < SPACE_FOR_BBOX)
	VSIFPrintfL( fp, "\"bbox\": %s,", pszBBOX );
	VSIFSeekL(fp, 0, SEEK_END);
	}
	else
	{
	VSIFPrintfL( fp, ",\n\"bbox\": %s", pszBBOX );
	}

	json_object_put( poObjBBOX );
	}

	VSIFPrintfL( fp, "\n}\n" );
	}*/

    std::for_each(seqFeatures_.begin(), seqFeatures_.end(),
                  OGRFeature::DestroyFeature);

    if( NULL != poFeatureDefn_ )
    {
        poFeatureDefn_->Release();
    }

    if( NULL != poSRS_ )
    {
        poSRS_->Release();
    }
}

/************************************************************************/
/*                           GetLayerDefn                               */
/************************************************************************/

OGRFeatureDefn* OGRMongoLayer::GetLayerDefn()
{
    return poFeatureDefn_;
}

/************************************************************************/
/*                           GetSpatialRef                              */
/************************************************************************/

OGRSpatialReference* OGRMongoLayer::GetSpatialRef()
{
    return poSRS_;
}

void OGRMongoLayer::SetSpatialRef( OGRSpatialReference* poSRSIn )
{
    if( NULL == poSRSIn )
    {
        poSRS_ = NULL;
        // poSRS_ = new OGRSpatialReference();
        // if( OGRERR_NONE != poSRS_->importFromEPSG( 4326 ) )
        // {
        //     delete poSRS_;
        //     poSRS_ = NULL;
        // }
    }
    else
    {
        poSRS_ = poSRSIn->Clone();
    }
}

/************************************************************************/
/*                           GetFeatureCount                            */
/************************************************************************/

int OGRMongoLayer::GetFeatureCount( int bForce )
{
    if (m_poFilterGeom == NULL && m_poAttrQuery == NULL)
        return static_cast<int>( seqFeatures_.size() );
    else
        return OGRLayer::GetFeatureCount(bForce);
}

/************************************************************************/
/*                           ResetReading                               */
/************************************************************************/

void OGRMongoLayer::ResetReading()
{
    iterCurrent_ = seqFeatures_.begin();
}

/************************************************************************/
/*                           GetNextFeature                             */
/************************************************************************/

OGRFeature* OGRMongoLayer::GetNextFeature()
{
    while ( iterCurrent_ != seqFeatures_.end() )
    {
        OGRFeature* poFeature = (*iterCurrent_);
        CPLAssert( NULL != poFeature );
        ++iterCurrent_;

        if((m_poFilterGeom == NULL
            || FilterGeometry( poFeature->GetGeometryRef() ) )
        && (m_poAttrQuery == NULL
            || m_poAttrQuery->Evaluate( poFeature )) )
        {
            OGRFeature* poFeatureCopy = poFeature->Clone();
            CPLAssert( NULL != poFeatureCopy );

            if (poFeatureCopy->GetGeometryRef() != NULL && poSRS_ != NULL)
            {
                poFeatureCopy->GetGeometryRef()->assignSpatialReference( poSRS_ );
            }

            return poFeatureCopy;
        }
    }

    return NULL;
}

/************************************************************************/
/*                           GetFeature                             */
/************************************************************************/

OGRFeature* OGRMongoLayer::GetFeature( long nFID )
{
	OGRFeature* poFeature = NULL;
	poFeature = OGRLayer::GetFeature( nFID );

	return poFeature;
}

/************************************************************************/
/*                           CreateFeature                              */
/************************************************************************/

OGRErr OGRMongoLayer::CreateFeature( OGRFeature* poFeature )
{
    //VSILFILE* fp = poDS_->GetOutputFile();
	//mongo::DBClientConnection * Conn;
	mongo::DBClientConnection Conn;
	std::string	errmsg;
	Conn.connect( poDS_->GetMongoConnString().c_str() , errmsg ) ;

    if( Conn.isFailed() )
    {
        CPLDebug( "GeoJSON", "Target datasource file is invalid." );
        return CE_Failure;
    }

    if( NULL == poFeature )
    {
        CPLDebug( "GeoJSON", "Feature is null" );
        return OGRERR_INVALID_HANDLE;
    }

    json_object* poObj = OGRGeoJSONWriteFeature( poFeature, bWriteBBOX, nCoordPrecision );
    CPLAssert( NULL != poObj );

	const char * strObj=json_object_to_json_string( poObj );
	mongo::BSONObj p = mongo::fromjson(strObj);

	std::string db=poDS_->GetName();
	std::string coll=this->GetName();
	std::string dbcoll=db+"."+coll;
	Conn.insert(dbcoll,p);

    json_object_put( poObj );

    ++nOutCounter_;

    OGRGeometry* poGeometry = poFeature->GetGeometryRef();
    if ( bWriteBBOX && !poGeometry->IsEmpty() )
    {
        OGREnvelope3D sEnvelope;
        poGeometry->getEnvelope(&sEnvelope);

        if( poGeometry->getCoordinateDimension() == 3 )
            bBBOX3D = TRUE;

        sEnvelopeLayer.Merge(sEnvelope);
    }
	//Conn.~DBClientConnection();
    return OGRERR_NONE;
}

OGRErr OGRMongoLayer::CreateField(OGRFieldDefn* poField, int bApproxOK)
{
    UNREFERENCED_PARAM(bApproxOK);

    for( int i = 0; i < poFeatureDefn_->GetFieldCount(); ++i )
    {
        OGRFieldDefn* poDefn = poFeatureDefn_->GetFieldDefn(i);
        CPLAssert( NULL != poDefn );

        if( EQUAL( poDefn->GetNameRef(), poField->GetNameRef() ) )
        {
            CPLDebug( "GeoJSON", "Field '%s' already present in schema",
                      poField->GetNameRef() );

            // TODO - mloskot: Is this return code correct?
            return OGRERR_NONE;
        }
    }

    poFeatureDefn_->AddFieldDefn( poField );

    return OGRERR_NONE;
}

/************************************************************************/
/*                           TestCapability                             */
/************************************************************************/

int OGRMongoLayer::TestCapability( const char* pszCap )
{
    UNREFERENCED_PARAM(pszCap);

    return FALSE;
}

/************************************************************************/
/*                           GetFIDColumn                               */
/************************************************************************/

const char* OGRMongoLayer::GetFIDColumn()
{
	return sFIDColumn_.c_str();
}

/************************************************************************/
/*                           SetFIDColumn                               */
/************************************************************************/

void OGRMongoLayer::SetFIDColumn( const char* pszFIDColumn )
{
	sFIDColumn_ = pszFIDColumn;
}

/************************************************************************/
/*                           AddFeature                                 */
/************************************************************************/

void OGRMongoLayer::AddFeature( OGRFeature* poFeature )
{
    CPLAssert( NULL != poFeature );

    // NOTE - mloskot:
    // Features may not be sorted according to FID values.

    // TODO: Should we check if feature already exists?
    // TODO: Think about sync operation, upload, etc.

    OGRFeature* poNewFeature = NULL;
    poNewFeature = poFeature->Clone();

    if( -1 == poNewFeature->GetFID() )
    {
        int nFID = static_cast<int>(seqFeatures_.size());
        poNewFeature->SetFID( nFID );

        // TODO - mlokot: We need to redesign creation of FID column
        int nField = poNewFeature->GetFieldIndex( DefaultFIDColumn );
        if( -1 != nField )
        {
            poNewFeature->SetField( nField, nFID );
        }
    }

    seqFeatures_.push_back( poNewFeature );
}

/************************************************************************/
/*                           DetectGeometryType                         */
/************************************************************************/

void OGRMongoLayer::DetectGeometryType()
{
    if (poFeatureDefn_->GetGeomType() != wkbUnknown)
        return;

    OGRwkbGeometryType featType = wkbUnknown;
    OGRGeometry* poGeometry = NULL;
    FeaturesSeq::const_iterator it = seqFeatures_.begin();
    FeaturesSeq::const_iterator end = seqFeatures_.end();

    if( it != end )
    {
        poGeometry = (*it)->GetGeometryRef();
        if( NULL != poGeometry )
        {
            featType = poGeometry->getGeometryType();
            if( featType != poFeatureDefn_->GetGeomType() )
            {
                poFeatureDefn_->SetGeomType( featType );
            }
        }
        ++it;
    }

    while( it != end )
    {
        poGeometry = (*it)->GetGeometryRef();
        if( NULL != poGeometry )
        {
            featType = poGeometry->getGeometryType();
            if( featType != poFeatureDefn_->GetGeomType() )
            {
                CPLDebug( "GeoJSON",
                    "Detected layer of mixed-geometry type features." );
                poFeatureDefn_->SetGeomType( DefaultGeometryType );
                break;
            }
        }
        ++it;
    }
}
#endif
<|endoftext|>


<commit_before><commit_msg>Integrate OS X key mapping into main key map.<commit_after><|endoftext|>


<commit_before><commit_msg>Simplified case where state changes to DEFAULT. Fixed counting of lines when a string terminates just before end of line.<commit_after><|endoftext|>


<commit_before>#include "pldm_base_cmd.hpp"

#include "pldm_cmd_helper.hpp"

#include "libpldm/utils.h"

namespace pldmtool
{

namespace base
{

namespace
{

using namespace pldmtool::helper;

std::vector<std::unique_ptr<CommandInterface>> commands;
const std::map<const char*, pldm_supported_types> pldmTypes{
    {"base", PLDM_BASE}, {"platform", PLDM_PLATFORM}, {"bios", PLDM_BIOS},
    {"fru", PLDM_FRU},   {"oem", PLDM_OEM},
};

} // namespace

class GetPLDMTypes : public CommandInterface
{
  public:
    ~GetPLDMTypes() = default;
    GetPLDMTypes() = delete;
    GetPLDMTypes(const GetPLDMTypes&) = delete;
    GetPLDMTypes(GetPLDMTypes&&) = default;
    GetPLDMTypes& operator=(const GetPLDMTypes&) = delete;
    GetPLDMTypes& operator=(GetPLDMTypes&&) = default;

    using CommandInterface::CommandInterface;

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr));
        auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
        auto rc = encode_get_types_req(PLDM_LOCAL_INSTANCE_ID, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = 0;
        std::vector<bitfield8_t> types(8);
        auto rc = decode_get_types_resp(responsePtr, payloadLength, &cc,
                                        types.data());
        if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
        {
            std::cerr << "Response Message Error: "
                      << "rc=" << rc << ",cc=" << (int)cc << "\n";
            return;
        }

        printPldmTypes(types);
    }

  private:
    void printPldmTypes(std::vector<bitfield8_t>& types)
    {
        std::cout << "Supported types:";
        for (int i = 0; i < PLDM_MAX_TYPES; i++)
        {
            bitfield8_t b = types[i / 8];
            if (b.byte & (1 << i % 8))
            {
                std::cout << " " << i;
                auto it = std::find_if(
                    pldmTypes.begin(), pldmTypes.end(),
                    [i](const auto& typePair) { return typePair.second == i; });
                if (it != pldmTypes.end())
                {

                    std::cout << "(" << it->first << ")";
                }
            }
        }

        std::cout << std::endl;
    }
};

class GetPLDMVersion : public CommandInterface
{
  public:
    ~GetPLDMVersion() = default;
    GetPLDMVersion() = delete;
    GetPLDMVersion(const GetPLDMVersion&) = delete;
    GetPLDMVersion(GetPLDMVersion&&) = default;
    GetPLDMVersion& operator=(const GetPLDMVersion&) = delete;
    GetPLDMVersion& operator=(GetPLDMVersion&&) = default;

    explicit GetPLDMVersion(const char* type, const char* name, CLI::App* app) :
        CommandInterface(type, name, app)
    {
        app->add_option("-t,--type", pldmType, "pldm supported type")
            ->required()
            ->transform(CLI::CheckedTransformer(pldmTypes, CLI::ignore_case));
    }
    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
                                        PLDM_GET_VERSION_REQ_BYTES);
        auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());

        auto rc = encode_get_version_req(PLDM_LOCAL_INSTANCE_ID, 0,
                                         PLDM_GET_FIRSTPART, pldmType, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = 0, transferFlag = 0;
        uint32_t transferHandle = 0;
        ver32_t version;
        auto rc =
            decode_get_version_resp(responsePtr, payloadLength, &cc,
                                    &transferHandle, &transferFlag, &version);
        if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
        {
            std::cerr << "Response Message Error: "
                      << "rc=" << rc << ",cc=" << (int)cc << "\n";
            return;
        }
        char buffer[16] = {0};
        ver2str(&version, buffer, sizeof(buffer));
        std::cout << "Type " << pldmType;
        auto it = std::find_if(
            pldmTypes.begin(), pldmTypes.end(),
            [&](const auto& typePair) { return typePair.second == pldmType; });

        if (it != pldmTypes.end())
        {
            std::cout << "(" << it->first << ")";
        }
        std::cout << ": " << buffer << std::endl;
    }

  private:
    pldm_supported_types pldmType;
};

class GetTID : public CommandInterface
{
  public:
    ~GetTID() = default;
    GetTID() = delete;
    GetTID(const GetTID&) = delete;
    GetTID(GetTID&&) = default;
    GetTID& operator=(const GetTID&) = delete;
    GetTID& operator=(GetTID&&) = default;

    using CommandInterface::CommandInterface;

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr));
        auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
        auto rc = encode_get_tid_req(PLDM_LOCAL_INSTANCE_ID, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = 0;
        uint8_t tid = 0;
        std::vector<bitfield8_t> types(8);
        auto rc = decode_get_tid_resp(responsePtr, payloadLength, &cc, &tid);
        if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
        {
            std::cerr << "Response Message Error: "
                      << "rc=" << rc << ",cc=" << (int)cc << "\n";
            return;
        }
        std::cout << "Parsed Response Msg: " << std::endl;
        std::cout << "TID : " << static_cast<uint32_t>(tid) << std::endl;
    }
};

void registerCommand(CLI::App& app)
{
    auto base = app.add_subcommand("base", "base type command");
    base->require_subcommand(1);

    auto getPLDMTypes =
        base->add_subcommand("GetPLDMTypes", "get pldm supported types");
    commands.push_back(
        std::make_unique<GetPLDMTypes>("base", "GetPLDMTypes", getPLDMTypes));

    auto getPLDMVersion =
        base->add_subcommand("GetPLDMVersion", "get version of a certain type");
    commands.push_back(std::make_unique<GetPLDMVersion>(
        "base", "GetPLDMVersion", getPLDMVersion));

    auto getPLDMTID = base->add_subcommand("GetTID", "get Terminus ID (TID)");
    commands.push_back(std::make_unique<GetTID>("base", "GetTID", getPLDMTID));
}

} // namespace base
} // namespace pldmtool
<commit_msg>pldmtool: BASE: Implement GetPLDMCommands<commit_after>#include "pldm_base_cmd.hpp"

#include "pldm_cmd_helper.hpp"

#include "libpldm/utils.h"

namespace pldmtool
{

namespace base
{

namespace
{

using namespace pldmtool::helper;

std::vector<std::unique_ptr<CommandInterface>> commands;
const std::map<const char*, pldm_supported_types> pldmTypes{
    {"base", PLDM_BASE}, {"platform", PLDM_PLATFORM}, {"bios", PLDM_BIOS},
    {"fru", PLDM_FRU},   {"oem", PLDM_OEM},
};

const std::map<const char*, pldm_supported_commands> pldmBaseCmds{
    {"GetTID", PLDM_GET_TID},
    {"GetPLDMVersion", PLDM_GET_PLDM_VERSION},
    {"GetPLDMTypes", PLDM_GET_PLDM_TYPES},
    {"GetPLDMCommands", PLDM_GET_PLDM_COMMANDS}};

const std::map<const char*, pldm_bios_commands> pldmBiosCmds{
    {"GetBIOSTable", PLDM_GET_BIOS_TABLE},
    {"SetBIOSAttributeCurrentValue", PLDM_SET_BIOS_ATTRIBUTE_CURRENT_VALUE},
    {"GetBIOSAttributeCurrentValueByHandle",
     PLDM_GET_BIOS_ATTRIBUTE_CURRENT_VALUE_BY_HANDLE},
    {"GetDateTime", PLDM_GET_DATE_TIME},
    {"SetDateTime", PLDM_SET_DATE_TIME}};

const std::map<const char*, pldm_platform_commands> pldmPlatformCmds{
    {"SetNumericEffecterValue", PLDM_SET_NUMERIC_EFFECTER_VALUE},
    {"SetStateEffecterStates", PLDM_SET_STATE_EFFECTER_STATES},
    {"GetPDR", PLDM_GET_PDR}};

const std::map<const char*, pldm_fru_commands> pldmFruCmds{
    {"GetFRURecordTableMetadata", PLDM_GET_FRU_RECORD_TABLE_METADATA},
    {"GetFRURecordTable", PLDM_GET_FRU_RECORD_TABLE}};

} // namespace

class GetPLDMTypes : public CommandInterface
{
  public:
    ~GetPLDMTypes() = default;
    GetPLDMTypes() = delete;
    GetPLDMTypes(const GetPLDMTypes&) = delete;
    GetPLDMTypes(GetPLDMTypes&&) = default;
    GetPLDMTypes& operator=(const GetPLDMTypes&) = delete;
    GetPLDMTypes& operator=(GetPLDMTypes&&) = default;

    using CommandInterface::CommandInterface;

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr));
        auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
        auto rc = encode_get_types_req(PLDM_LOCAL_INSTANCE_ID, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = 0;
        std::vector<bitfield8_t> types(8);
        auto rc = decode_get_types_resp(responsePtr, payloadLength, &cc,
                                        types.data());
        if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
        {
            std::cerr << "Response Message Error: "
                      << "rc=" << rc << ",cc=" << (int)cc << "\n";
            return;
        }

        printPldmTypes(types);
    }

  private:
    void printPldmTypes(std::vector<bitfield8_t>& types)
    {
        std::cout << "Supported types:";
        for (int i = 0; i < PLDM_MAX_TYPES; i++)
        {
            bitfield8_t b = types[i / 8];
            if (b.byte & (1 << i % 8))
            {
                std::cout << " " << i;
                auto it = std::find_if(
                    pldmTypes.begin(), pldmTypes.end(),
                    [i](const auto& typePair) { return typePair.second == i; });
                if (it != pldmTypes.end())
                {

                    std::cout << "(" << it->first << ")";
                }
            }
        }

        std::cout << std::endl;
    }
};

class GetPLDMVersion : public CommandInterface
{
  public:
    ~GetPLDMVersion() = default;
    GetPLDMVersion() = delete;
    GetPLDMVersion(const GetPLDMVersion&) = delete;
    GetPLDMVersion(GetPLDMVersion&&) = default;
    GetPLDMVersion& operator=(const GetPLDMVersion&) = delete;
    GetPLDMVersion& operator=(GetPLDMVersion&&) = default;

    explicit GetPLDMVersion(const char* type, const char* name, CLI::App* app) :
        CommandInterface(type, name, app)
    {
        app->add_option("-t,--type", pldmType, "pldm supported type")
            ->required()
            ->transform(CLI::CheckedTransformer(pldmTypes, CLI::ignore_case));
    }
    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
                                        PLDM_GET_VERSION_REQ_BYTES);
        auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());

        auto rc = encode_get_version_req(PLDM_LOCAL_INSTANCE_ID, 0,
                                         PLDM_GET_FIRSTPART, pldmType, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = 0, transferFlag = 0;
        uint32_t transferHandle = 0;
        ver32_t version;
        auto rc =
            decode_get_version_resp(responsePtr, payloadLength, &cc,
                                    &transferHandle, &transferFlag, &version);
        if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
        {
            std::cerr << "Response Message Error: "
                      << "rc=" << rc << ",cc=" << (int)cc << "\n";
            return;
        }
        char buffer[16] = {0};
        ver2str(&version, buffer, sizeof(buffer));
        std::cout << "Type " << pldmType;
        auto it = std::find_if(
            pldmTypes.begin(), pldmTypes.end(),
            [&](const auto& typePair) { return typePair.second == pldmType; });

        if (it != pldmTypes.end())
        {
            std::cout << "(" << it->first << ")";
        }
        std::cout << ": " << buffer << std::endl;
    }

  private:
    pldm_supported_types pldmType;
};

class GetTID : public CommandInterface
{
  public:
    ~GetTID() = default;
    GetTID() = delete;
    GetTID(const GetTID&) = delete;
    GetTID(GetTID&&) = default;
    GetTID& operator=(const GetTID&) = delete;
    GetTID& operator=(GetTID&&) = default;

    using CommandInterface::CommandInterface;

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr));
        auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
        auto rc = encode_get_tid_req(PLDM_LOCAL_INSTANCE_ID, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = 0;
        uint8_t tid = 0;
        std::vector<bitfield8_t> types(8);
        auto rc = decode_get_tid_resp(responsePtr, payloadLength, &cc, &tid);
        if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
        {
            std::cerr << "Response Message Error: "
                      << "rc=" << rc << ",cc=" << (int)cc << "\n";
            return;
        }
        std::cout << "Parsed Response Msg: " << std::endl;
        std::cout << "TID : " << static_cast<uint32_t>(tid) << std::endl;
    }
};

class GetPLDMCommands : public CommandInterface
{
  public:
    ~GetPLDMCommands() = default;
    GetPLDMCommands() = delete;
    GetPLDMCommands(const GetPLDMCommands&) = delete;
    GetPLDMCommands(GetPLDMCommands&&) = default;
    GetPLDMCommands& operator=(const GetPLDMCommands&) = delete;
    GetPLDMCommands& operator=(GetPLDMCommands&&) = default;

    explicit GetPLDMCommands(const char* type, const char* name,
                             CLI::App* app) :
        CommandInterface(type, name, app)
    {
        app->add_option("-t,--type", pldmType, "pldm supported type")
            ->required()
            ->transform(CLI::CheckedTransformer(pldmTypes, CLI::ignore_case));
    }

    std::pair<int, std::vector<uint8_t>> createRequestMsg() override
    {
        std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
                                        PLDM_GET_COMMANDS_REQ_BYTES);
        auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
        ver32_t version{0xFF, 0xFF, 0xFF, 0xFF};
        auto rc = encode_get_commands_req(PLDM_LOCAL_INSTANCE_ID, pldmType,
                                          version, request);
        return {rc, requestMsg};
    }

    void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
    {
        uint8_t cc = 0;
        std::vector<bitfield8_t> cmdTypes(32);
        auto rc = decode_get_commands_resp(responsePtr, payloadLength, &cc,
                                           cmdTypes.data());
        if (rc != PLDM_SUCCESS || cc != PLDM_SUCCESS)
        {
            std::cerr << "Response Message Error: "
                      << "rc=" << rc << ",cc=" << (int)cc << "\n";
            return;
        }
        printPldmCommands(cmdTypes, pldmType);
    }

  private:
    pldm_supported_types pldmType;

    template <typename CommandMap>
    void printCommand(CommandMap& commandMap, int i)
    {
        auto it = std::find_if(
            commandMap.begin(), commandMap.end(),
            [i](const auto& typePair) { return typePair.second == i; });
        if (it != commandMap.end())
        {
            std::cout << "(" << it->first << ")";
        }
    }

    void printPldmCommands(std::vector<bitfield8_t>& cmdTypes,
                           pldm_supported_types pldmType)
    {
        std::cout << "Parsed Response Msg:" << std::endl;
        std::cout << "Supported Commands :";
        for (int i = 0; i < PLDM_MAX_CMDS_PER_TYPE; i++)
        {
            bitfield8_t b = cmdTypes[i / 8];
            if (b.byte & (1 << i % 8))
            {
                std::cout << " " << i;
                switch (pldmType)
                {
                    case PLDM_BASE:
                        printCommand(pldmBaseCmds, i);
                        break;
                    case PLDM_PLATFORM:
                        printCommand(pldmPlatformCmds, i);
                        break;
                    case PLDM_BIOS:
                        printCommand(pldmBiosCmds, i);
                        break;
                    case PLDM_FRU:
                        printCommand(pldmFruCmds, i);
                        break;
                    default:
                        break;
                }
            }
        }
        std::cout << std::endl;
    }
};

void registerCommand(CLI::App& app)
{
    auto base = app.add_subcommand("base", "base type command");
    base->require_subcommand(1);

    auto getPLDMTypes =
        base->add_subcommand("GetPLDMTypes", "get pldm supported types");
    commands.push_back(
        std::make_unique<GetPLDMTypes>("base", "GetPLDMTypes", getPLDMTypes));

    auto getPLDMVersion =
        base->add_subcommand("GetPLDMVersion", "get version of a certain type");
    commands.push_back(std::make_unique<GetPLDMVersion>(
        "base", "GetPLDMVersion", getPLDMVersion));

    auto getPLDMTID = base->add_subcommand("GetTID", "get Terminus ID (TID)");
    commands.push_back(std::make_unique<GetTID>("base", "GetTID", getPLDMTID));

    auto getPLDMCommands = base->add_subcommand(
        "GetPLDMCommands", "get supported commands of pldm type");
    commands.push_back(std::make_unique<GetPLDMCommands>(
        "base", "GetPLDMCommands", getPLDMCommands));
}

} // namespace base
} // namespace pldmtool
<|endoftext|>