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

#ifndef _SVX_EDITSOURCE_HXX
#define _SVX_EDITSOURCE_HXX

#ifndef _SVX_UNOEDSRC_HXX
#include <unoedsrc.hxx>
#endif

class EditEngine;
class SvxEditEngineSourceImpl;

class SvxEditEngineSource : public SvxEditSource
{
public:
    SvxEditEngineSource( EditEngine* pEditEngine );
    virtual ~SvxEditEngineSource();

    virtual SvxEditSource*      Clone() const;
    virtual SvxTextForwarder*   GetTextForwarder();
    virtual void                UpdateData();

private:
    SvxEditEngineSource( SvxEditEngineSourceImpl* pImpl );

    SvxEditEngineSourceImpl*    mpImpl;
};

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

#ifndef _SVX_EDITSOURCE_HXX
#define _SVX_EDITSOURCE_HXX

#ifndef _SVX_UNOEDSRC_HXX
#include <unoedsrc.hxx>
#endif

class EditEngine;
class SvxEditEngineSourceImpl;

class SvxEditEngineSource : public SvxEditSource
{
public:
    SvxEditEngineSource( EditEngine* pEditEngine );
    virtual ~SvxEditEngineSource();

    virtual SvxEditSource*      Clone() const;
    virtual SvxTextForwarder*   GetTextForwarder();
    virtual void                UpdateData();

private:
    SvxEditEngineSource( SvxEditEngineSourceImpl* pImpl );

    SvxEditEngineSourceImpl*    mpImpl;
};

#endif
<|endoftext|>


<commit_before>/* Adventure Creator v2 Run-time engine
   Started 27-May-99 (c) 1999-2011 Chris Jones

  Adventure Game Studio source code Copyright 1999-2011 Chris Jones.
  All rights reserved.

  The AGS Editor Source Code is provided under the Artistic License 2.0
  http://www.opensource.org/licenses/artistic-license-2.0.php

  You MAY NOT compile your own builds of the engine without making it EXPLICITLY
  CLEAR that the code has been altered from the Standard Version.

*/

//
// Quit game procedure
//

#include "util/wgt2allg.h"
#include "gfx/ali3d.h"
#include "ac/cdaudio.h"
#include "ac/gamesetup.h"
#include "ac/gamesetupstruct.h"
#include "ac/record.h"
#include "ac/roomstatus.h"
#include "ac/translation.h"
#include "debug/agseditordebugger.h"
#include "debug/debug_log.h"
#include "debug/debugger.h"
#include "main/main.h"
#include "main/mainheader.h"
#include "main/quit.h"
#include "ac/spritecache.h"
#include "gfx/graphicsdriver.h"
#include "gfx/bitmap.h"

using AGS::Common::IBitmap;
namespace Bitmap = AGS::Common::Bitmap;

extern GameSetupStruct game;
extern int spritewidth[MAX_SPRITES],spriteheight[MAX_SPRITES];
extern SpriteCache spriteset;
extern RoomStatus troom;    // used for non-saveable rooms, eg. intro
extern int our_eip;
extern GameSetup usetup;
extern char pexbuf[STD_BUFFER_SIZE];
extern int proper_exit;
extern char check_dynamic_sprites_at_exit;
extern int editor_debugging_initialized;
extern IAGSEditorDebugger *editor_debugger;
extern int need_to_stop_cd;
extern IBitmap *_old_screen;
extern IBitmap *_sub_screen;
extern int use_cdplayer;
extern IGraphicsDriver *gfxDriver;

bool handledErrorInEditor;

void quit_tell_editor_debugger(char *qmsg)
{
    if (editor_debugging_initialized)
    {
        if ((qmsg[0] == '!') && (qmsg[1] != '|'))
        {
            handledErrorInEditor = send_exception_to_editor(&qmsg[1]);
        }
        send_message_to_editor("EXIT");
        editor_debugger->Shutdown();
    }
}

void quit_stop_cd()
{
    if (need_to_stop_cd)
        cd_manager(3,0);
}

void quit_shutdown_scripts()
{
    ccUnregisterAllObjects();
}

void quit_check_dynamic_sprites(char *qmsg)
{
    if ((qmsg[0] == '|') && (check_dynamic_sprites_at_exit) &&
        (game.options[OPT_DEBUGMODE] != 0)) {
            // game exiting normally -- make sure the dynamic sprites
            // have been deleted
            for (int i = 1; i < spriteset.elements; i++) {
                if (game.spriteflags[i] & SPF_DYNAMICALLOC)
                    debug_log("Dynamic sprite %d was never deleted", i);
            }
    }
}

void quit_shutdown_platform(char *qmsg)
{
    platform->AboutToQuitGame();

    our_eip = 9016;

    platform->ShutdownPlugins();

    quit_check_dynamic_sprites(qmsg);

    // allegro_exit assumes screen is correct
	if (_old_screen) {
		Bitmap::SetScreenBitmap( _old_screen );
	}

    platform->FinishedUsingGraphicsMode();

    if (use_cdplayer)
        platform->ShutdownCDPlayer();
}

void quit_shutdown_audio()
{
    our_eip = 9917;
    game.options[OPT_CROSSFADEMUSIC] = 0;
    stopmusic();
#ifndef PSP_NO_MOD_PLAYBACK
    if (opts.mod_player)
        remove_mod_player();
#endif

    // Quit the sound thread.
    update_mp3_thread_running = false;

    remove_sound();
}

void quit_check_for_error_state(char *qmsg, char *alertis)
{
    if (qmsg[0]=='|') ; //qmsg++;
    else if (qmsg[0]=='!') {
        qmsg++;

        if (qmsg[0] == '|')
            strcpy (alertis, "Abort key pressed.\n\n");
        else if (qmsg[0] == '?') {
            strcpy(alertis, "A fatal error has been generated by the script using the AbortGame function. Please contact the game author for support.\n\n");
            qmsg++;
        }
        else
            strcpy(alertis,"An error has occurred. Please contact the game author for support, as this "
            "is likely to be a scripting error and not a bug in AGS.\n"
            "(ACI version " ACI_VERSION_TEXT ")\n\n");

        strcat (alertis, get_cur_script(5) );

        if (qmsg[0] != '|')
            strcat(alertis,"\nError: ");
        else
            qmsg = "";
    }
    else if (qmsg[0] == '%') {
        qmsg++;

        sprintf(alertis, "A warning has been generated. This is not normally fatal, but you have selected "
            "to treat warnings as errors.\n"
            "(ACI version " ACI_VERSION_TEXT ")\n\n%s\n", get_cur_script(5));
    }
    else strcpy(alertis,"An internal error has occurred. Please note down the following information.\n"
        "If the problem persists, post the details on the AGS Technical Forum.\n"
        "(ACI version " ACI_VERSION_TEXT ")\n"
        "\nError: ");
}

void quit_destroy_subscreen()
{
    // close graphics mode (Win) or return to text mode (DOS)
    delete _sub_screen;
	_sub_screen = NULL;
}

void quit_shutdown_graphics()
{
    // Release the display mode (and anything dependant on the window)
    if (gfxDriver != NULL)
        gfxDriver->UnInit();

    // Tell Allegro that we are no longer in graphics mode
    set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
}

void quit_message_on_exit(char *qmsg, char *alertis)
{
    // successful exit displays no messages (because Windoze closes the dos-box
    // if it is empty).
    if (qmsg[0]=='|') ;
    else if (!handledErrorInEditor)
    {
        // Display the message (at this point the window still exists)
        sprintf(pexbuf,"%s\n",qmsg);
        strcat(alertis,pexbuf);
        platform->DisplayAlert(alertis);
    }
}

void quit_release_gfx_driver()
{
    if (gfxDriver != NULL)
    {
        delete gfxDriver;
        gfxDriver = NULL;
    }
}

void quit_release_data()
{
    // wipe all the interaction structs so they don't de-alloc the children twice
    resetRoomStatuses();
    memset (&troom, 0, sizeof(RoomStatus));

    /*  _CrtMemState memstart;
    _CrtMemCheckpoint(&memstart);
    _CrtMemDumpStatistics( &memstart );*/
}

void quit_print_last_fps(char *qmsg)
{
    /*  // print the FPS if there wasn't an error
    if ((play.debug_mode!=0) && (qmsg[0]=='|'))
    printf("Last cycle fps: %d\n",fps);*/
}

void quit_delete_temp_files()
{
    al_ffblk	dfb;
    int	dun = al_findfirst("~ac*.tmp",&dfb,FA_SEARCH);
    while (!dun) {
        unlink(dfb.name);
        dun = al_findnext(&dfb);
    }
    al_findclose (&dfb);
}

// TODO: move to test unit
#include "gfx/allegrobitmap.h"
using AGS::Common::CAllegroBitmap;
extern CAllegroBitmap *test_allegro_bitmap;
extern IDriverDependantBitmap *test_allegro_ddb;
void allegro_bitmap_test_release()
{
	delete test_allegro_bitmap;
	if (test_allegro_ddb)
		gfxDriver->DestroyDDB(test_allegro_ddb);
}

char return_to_roomedit[30] = "\0";
char return_to_room[150] = "\0";
// quit - exits the engine, shutting down everything gracefully
// The parameter is the message to print. If this message begins with
// an '!' character, then it is printed as a "contact game author" error.
// If it begins with a '|' then it is treated as a "thanks for playing" type
// message. If it begins with anything else, it is treated as an internal
// error.
// "!|" is a special code used to mean that the player has aborted (Alt+X)
void quit(char*quitmsg) {

    // Need to copy it in case it's from a plugin (since we're
    // about to free plugins)
    char qmsgbufr[STD_BUFFER_SIZE];
    strncpy(qmsgbufr, quitmsg, STD_BUFFER_SIZE);
    qmsgbufr[STD_BUFFER_SIZE - 1] = 0;
    char *qmsg = &qmsgbufr[0];

	allegro_bitmap_test_release();

    handledErrorInEditor = false;

    quit_tell_editor_debugger(qmsg);

    our_eip = 9900;

    stop_recording();

    quit_stop_cd();

    our_eip = 9020;

    quit_shutdown_scripts();

    quit_shutdown_platform(qmsg);

    our_eip = 9019;

    quit_shutdown_audio();

    our_eip = 9901;

    char alertis[1500]="\0";
    quit_check_for_error_state(qmsg, alertis);

    shutdown_font_renderer();
    our_eip = 9902;

    quit_destroy_subscreen();

    our_eip = 9907;

    close_translation();

    our_eip = 9908;

    quit_shutdown_graphics();

    quit_message_on_exit(qmsg, alertis);

    // remove the game window
    allegro_exit();

    quit_release_gfx_driver();

    platform->PostAllegroExit();

    our_eip = 9903;

    quit_release_data();

    quit_print_last_fps(qmsg);

    quit_delete_temp_files();

    proper_exit=1;

    write_log_debug("***** ENGINE HAS SHUTDOWN");

    shutdown_debug_system();

    our_eip = 9904;
    exit(EXIT_NORMAL);
}

extern "C" {
    void quit_c(char*msg) {
        quit(msg);
    }
}
<commit_msg>Fixed error message having extra characters<commit_after>/* Adventure Creator v2 Run-time engine
   Started 27-May-99 (c) 1999-2011 Chris Jones

  Adventure Game Studio source code Copyright 1999-2011 Chris Jones.
  All rights reserved.

  The AGS Editor Source Code is provided under the Artistic License 2.0
  http://www.opensource.org/licenses/artistic-license-2.0.php

  You MAY NOT compile your own builds of the engine without making it EXPLICITLY
  CLEAR that the code has been altered from the Standard Version.

*/

//
// Quit game procedure
//

#include "util/wgt2allg.h"
#include "gfx/ali3d.h"
#include "ac/cdaudio.h"
#include "ac/gamesetup.h"
#include "ac/gamesetupstruct.h"
#include "ac/record.h"
#include "ac/roomstatus.h"
#include "ac/translation.h"
#include "debug/agseditordebugger.h"
#include "debug/debug_log.h"
#include "debug/debugger.h"
#include "main/main.h"
#include "main/mainheader.h"
#include "main/quit.h"
#include "ac/spritecache.h"
#include "gfx/graphicsdriver.h"
#include "gfx/bitmap.h"

using AGS::Common::IBitmap;
namespace Bitmap = AGS::Common::Bitmap;

extern GameSetupStruct game;
extern int spritewidth[MAX_SPRITES],spriteheight[MAX_SPRITES];
extern SpriteCache spriteset;
extern RoomStatus troom;    // used for non-saveable rooms, eg. intro
extern int our_eip;
extern GameSetup usetup;
extern char pexbuf[STD_BUFFER_SIZE];
extern int proper_exit;
extern char check_dynamic_sprites_at_exit;
extern int editor_debugging_initialized;
extern IAGSEditorDebugger *editor_debugger;
extern int need_to_stop_cd;
extern IBitmap *_old_screen;
extern IBitmap *_sub_screen;
extern int use_cdplayer;
extern IGraphicsDriver *gfxDriver;

bool handledErrorInEditor;

void quit_tell_editor_debugger(char *qmsg)
{
    if (editor_debugging_initialized)
    {
        if ((qmsg[0] == '!') && (qmsg[1] != '|'))
        {
            handledErrorInEditor = send_exception_to_editor(&qmsg[1]);
        }
        send_message_to_editor("EXIT");
        editor_debugger->Shutdown();
    }
}

void quit_stop_cd()
{
    if (need_to_stop_cd)
        cd_manager(3,0);
}

void quit_shutdown_scripts()
{
    ccUnregisterAllObjects();
}

void quit_check_dynamic_sprites(char *qmsg)
{
    if ((qmsg[0] == '|') && (check_dynamic_sprites_at_exit) &&
        (game.options[OPT_DEBUGMODE] != 0)) {
            // game exiting normally -- make sure the dynamic sprites
            // have been deleted
            for (int i = 1; i < spriteset.elements; i++) {
                if (game.spriteflags[i] & SPF_DYNAMICALLOC)
                    debug_log("Dynamic sprite %d was never deleted", i);
            }
    }
}

void quit_shutdown_platform(char *qmsg)
{
    platform->AboutToQuitGame();

    our_eip = 9016;

    platform->ShutdownPlugins();

    quit_check_dynamic_sprites(qmsg);

    // allegro_exit assumes screen is correct
	if (_old_screen) {
		Bitmap::SetScreenBitmap( _old_screen );
	}

    platform->FinishedUsingGraphicsMode();

    if (use_cdplayer)
        platform->ShutdownCDPlayer();
}

void quit_shutdown_audio()
{
    our_eip = 9917;
    game.options[OPT_CROSSFADEMUSIC] = 0;
    stopmusic();
#ifndef PSP_NO_MOD_PLAYBACK
    if (opts.mod_player)
        remove_mod_player();
#endif

    // Quit the sound thread.
    update_mp3_thread_running = false;

    remove_sound();
}

void quit_check_for_error_state(char *&qmsg, char *alertis)
{
    if (qmsg[0]=='|') ; //qmsg++;
    else if (qmsg[0]=='!') {
        qmsg++;

        if (qmsg[0] == '|')
            strcpy (alertis, "Abort key pressed.\n\n");
        else if (qmsg[0] == '?') {
            strcpy(alertis, "A fatal error has been generated by the script using the AbortGame function. Please contact the game author for support.\n\n");
            qmsg++;
        }
        else
            strcpy(alertis,"An error has occurred. Please contact the game author for support, as this "
            "is likely to be a scripting error and not a bug in AGS.\n"
            "(ACI version " ACI_VERSION_TEXT ")\n\n");

        strcat (alertis, get_cur_script(5) );

        if (qmsg[0] != '|')
            strcat(alertis,"\nError: ");
        else
            qmsg = "";
    }
    else if (qmsg[0] == '%') {
        qmsg++;

        sprintf(alertis, "A warning has been generated. This is not normally fatal, but you have selected "
            "to treat warnings as errors.\n"
            "(ACI version " ACI_VERSION_TEXT ")\n\n%s\n", get_cur_script(5));
    }
    else strcpy(alertis,"An internal error has occurred. Please note down the following information.\n"
        "If the problem persists, post the details on the AGS Technical Forum.\n"
        "(ACI version " ACI_VERSION_TEXT ")\n"
        "\nError: ");
}

void quit_destroy_subscreen()
{
    // close graphics mode (Win) or return to text mode (DOS)
    delete _sub_screen;
	_sub_screen = NULL;
}

void quit_shutdown_graphics()
{
    // Release the display mode (and anything dependant on the window)
    if (gfxDriver != NULL)
        gfxDriver->UnInit();

    // Tell Allegro that we are no longer in graphics mode
    set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
}

void quit_message_on_exit(char *qmsg, char *alertis)
{
    // successful exit displays no messages (because Windoze closes the dos-box
    // if it is empty).
    if (qmsg[0]=='|') ;
    else if (!handledErrorInEditor)
    {
        // Display the message (at this point the window still exists)
        sprintf(pexbuf,"%s\n",qmsg);
        strcat(alertis,pexbuf);
        platform->DisplayAlert(alertis);
    }
}

void quit_release_gfx_driver()
{
    if (gfxDriver != NULL)
    {
        delete gfxDriver;
        gfxDriver = NULL;
    }
}

void quit_release_data()
{
    // wipe all the interaction structs so they don't de-alloc the children twice
    resetRoomStatuses();
    memset (&troom, 0, sizeof(RoomStatus));

    /*  _CrtMemState memstart;
    _CrtMemCheckpoint(&memstart);
    _CrtMemDumpStatistics( &memstart );*/
}

void quit_print_last_fps(char *qmsg)
{
    /*  // print the FPS if there wasn't an error
    if ((play.debug_mode!=0) && (qmsg[0]=='|'))
    printf("Last cycle fps: %d\n",fps);*/
}

void quit_delete_temp_files()
{
    al_ffblk	dfb;
    int	dun = al_findfirst("~ac*.tmp",&dfb,FA_SEARCH);
    while (!dun) {
        unlink(dfb.name);
        dun = al_findnext(&dfb);
    }
    al_findclose (&dfb);
}

// TODO: move to test unit
#include "gfx/allegrobitmap.h"
using AGS::Common::CAllegroBitmap;
extern CAllegroBitmap *test_allegro_bitmap;
extern IDriverDependantBitmap *test_allegro_ddb;
void allegro_bitmap_test_release()
{
	delete test_allegro_bitmap;
	if (test_allegro_ddb)
		gfxDriver->DestroyDDB(test_allegro_ddb);
}

char return_to_roomedit[30] = "\0";
char return_to_room[150] = "\0";
// quit - exits the engine, shutting down everything gracefully
// The parameter is the message to print. If this message begins with
// an '!' character, then it is printed as a "contact game author" error.
// If it begins with a '|' then it is treated as a "thanks for playing" type
// message. If it begins with anything else, it is treated as an internal
// error.
// "!|" is a special code used to mean that the player has aborted (Alt+X)
void quit(char*quitmsg) {

    // Need to copy it in case it's from a plugin (since we're
    // about to free plugins)
    char qmsgbufr[STD_BUFFER_SIZE];
    strncpy(qmsgbufr, quitmsg, STD_BUFFER_SIZE);
    qmsgbufr[STD_BUFFER_SIZE - 1] = 0;
    char *qmsg = &qmsgbufr[0];

	allegro_bitmap_test_release();

    handledErrorInEditor = false;

    quit_tell_editor_debugger(qmsg);

    our_eip = 9900;

    stop_recording();

    quit_stop_cd();

    our_eip = 9020;

    quit_shutdown_scripts();

    quit_shutdown_platform(qmsg);

    our_eip = 9019;

    quit_shutdown_audio();

    our_eip = 9901;

    char alertis[1500]="\0";
    quit_check_for_error_state(qmsg, alertis);

    shutdown_font_renderer();
    our_eip = 9902;

    quit_destroy_subscreen();

    our_eip = 9907;

    close_translation();

    our_eip = 9908;

    quit_shutdown_graphics();

    quit_message_on_exit(qmsg, alertis);

    // remove the game window
    allegro_exit();

    quit_release_gfx_driver();

    platform->PostAllegroExit();

    our_eip = 9903;

    quit_release_data();

    quit_print_last_fps(qmsg);

    quit_delete_temp_files();

    proper_exit=1;

    write_log_debug("***** ENGINE HAS SHUTDOWN");

    shutdown_debug_system();

    our_eip = 9904;
    exit(EXIT_NORMAL);
}

extern "C" {
    void quit_c(char*msg) {
        quit(msg);
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2020 The Orbit Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "Utils.h"

#ifdef _WIN32
// clang-format off
#include <cguid.h>
#include <AtlBase.h>
#include <atlconv.h>
// clang-format on
#else
#include <sys/uio.h>
#endif

#include <time.h>
#include <algorithm>
#include <mutex>
#include <thread>

#include "absl/base/attributes.h"

#ifdef _WIN32
//-----------------------------------------------------------------------------
std::string GetLastErrorAsString() {
  // Get the error message, if any.
  DWORD errorMessageID = ::GetLastError();
  if (errorMessageID == 0) return "No error message has been recorded";

  LPSTR messageBuffer = nullptr;
  size_t size = FormatMessageA(
      FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
          FORMAT_MESSAGE_IGNORE_INSERTS,
      NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
      (LPSTR)&messageBuffer, 0, NULL);

  std::string message(messageBuffer, size);

  // Free the buffer.
  LocalFree(messageBuffer);

  return message;
}

//-----------------------------------------------------------------------------
std::string GuidToString(GUID a_Guid) {
  std::string guidStr;
  LPOLESTR wszCLSID = NULL;
  HRESULT hr = StringFromCLSID(a_Guid, &wszCLSID);
  if (hr == S_OK) {
    // wszCLSID looks like: "{96F93FED-50B7-44B8-94AF-C205B68334FE}"
    guidStr = ws2s(wszCLSID);
    CoTaskMemFree(wszCLSID);
    auto len = guidStr.size();
    if (len > 2) {
      guidStr = guidStr.substr(1, len - 2);
    }
    guidStr.erase(std::remove(guidStr.begin(), guidStr.end(), '-'),
                  guidStr.end());
  }

  return guidStr;
}

#include "dde.h"

struct AFX_MAP_MESSAGE {
  UINT nMsg;
  LPCSTR lpszMsg;
};
#define DEFINE_MESSAGE(wm) \
  { wm, #wm }
static const AFX_MAP_MESSAGE allMessages[] = {
    DEFINE_MESSAGE(WM_CREATE),
    DEFINE_MESSAGE(WM_DESTROY),
    DEFINE_MESSAGE(WM_MOVE),
    DEFINE_MESSAGE(WM_SIZE),
    DEFINE_MESSAGE(WM_ACTIVATE),
    DEFINE_MESSAGE(WM_SETFOCUS),
    DEFINE_MESSAGE(WM_KILLFOCUS),
    DEFINE_MESSAGE(WM_ENABLE),
    DEFINE_MESSAGE(WM_SETREDRAW),
    DEFINE_MESSAGE(WM_SETTEXT),
    DEFINE_MESSAGE(WM_GETTEXT),
    DEFINE_MESSAGE(WM_GETTEXTLENGTH),
    DEFINE_MESSAGE(WM_PAINT),
    DEFINE_MESSAGE(WM_CLOSE),
    DEFINE_MESSAGE(WM_QUERYENDSESSION),
    DEFINE_MESSAGE(WM_QUIT),
    DEFINE_MESSAGE(WM_QUERYOPEN),
    DEFINE_MESSAGE(WM_ERASEBKGND),
    DEFINE_MESSAGE(WM_SYSCOLORCHANGE),
    DEFINE_MESSAGE(WM_ENDSESSION),
    DEFINE_MESSAGE(WM_SHOWWINDOW),
    DEFINE_MESSAGE(WM_CTLCOLORMSGBOX),
    DEFINE_MESSAGE(WM_CTLCOLOREDIT),
    DEFINE_MESSAGE(WM_CTLCOLORLISTBOX),
    DEFINE_MESSAGE(WM_CTLCOLORBTN),
    DEFINE_MESSAGE(WM_CTLCOLORDLG),
    DEFINE_MESSAGE(WM_CTLCOLORSCROLLBAR),
    DEFINE_MESSAGE(WM_CTLCOLORSTATIC),
    DEFINE_MESSAGE(WM_WININICHANGE),
    DEFINE_MESSAGE(WM_SETTINGCHANGE),
    DEFINE_MESSAGE(WM_DEVMODECHANGE),
    DEFINE_MESSAGE(WM_ACTIVATEAPP),
    DEFINE_MESSAGE(WM_FONTCHANGE),
    DEFINE_MESSAGE(WM_TIMECHANGE),
    DEFINE_MESSAGE(WM_CANCELMODE),
    DEFINE_MESSAGE(WM_SETCURSOR),
    DEFINE_MESSAGE(WM_MOUSEACTIVATE),
    DEFINE_MESSAGE(WM_CHILDACTIVATE),
    DEFINE_MESSAGE(WM_QUEUESYNC),
    DEFINE_MESSAGE(WM_GETMINMAXINFO),
    DEFINE_MESSAGE(WM_ICONERASEBKGND),
    DEFINE_MESSAGE(WM_NEXTDLGCTL),
    DEFINE_MESSAGE(WM_SPOOLERSTATUS),
    DEFINE_MESSAGE(WM_DRAWITEM),
    DEFINE_MESSAGE(WM_MEASUREITEM),
    DEFINE_MESSAGE(WM_DELETEITEM),
    DEFINE_MESSAGE(WM_VKEYTOITEM),
    DEFINE_MESSAGE(WM_CHARTOITEM),
    DEFINE_MESSAGE(WM_SETFONT),
    DEFINE_MESSAGE(WM_GETFONT),
    DEFINE_MESSAGE(WM_QUERYDRAGICON),
    DEFINE_MESSAGE(WM_COMPAREITEM),
    DEFINE_MESSAGE(WM_COMPACTING),
    DEFINE_MESSAGE(WM_NCCREATE),
    DEFINE_MESSAGE(WM_NCDESTROY),
    DEFINE_MESSAGE(WM_NCCALCSIZE),
    DEFINE_MESSAGE(WM_NCHITTEST),
    DEFINE_MESSAGE(WM_NCPAINT),
    DEFINE_MESSAGE(WM_NCACTIVATE),
    DEFINE_MESSAGE(WM_GETDLGCODE),
    DEFINE_MESSAGE(WM_NCMOUSEMOVE),
    DEFINE_MESSAGE(WM_NCLBUTTONDOWN),
    DEFINE_MESSAGE(WM_NCLBUTTONUP),
    DEFINE_MESSAGE(WM_NCLBUTTONDBLCLK),
    DEFINE_MESSAGE(WM_NCRBUTTONDOWN),
    DEFINE_MESSAGE(WM_NCRBUTTONUP),
    DEFINE_MESSAGE(WM_NCRBUTTONDBLCLK),
    DEFINE_MESSAGE(WM_NCMBUTTONDOWN),
    DEFINE_MESSAGE(WM_NCMBUTTONUP),
    DEFINE_MESSAGE(WM_NCMBUTTONDBLCLK),
    DEFINE_MESSAGE(WM_KEYDOWN),
    DEFINE_MESSAGE(WM_KEYUP),
    DEFINE_MESSAGE(WM_CHAR),
    DEFINE_MESSAGE(WM_DEADCHAR),
    DEFINE_MESSAGE(WM_SYSKEYDOWN),
    DEFINE_MESSAGE(WM_SYSKEYUP),
    DEFINE_MESSAGE(WM_SYSCHAR),
    DEFINE_MESSAGE(WM_SYSDEADCHAR),
    DEFINE_MESSAGE(WM_KEYLAST),
    DEFINE_MESSAGE(WM_INITDIALOG),
    DEFINE_MESSAGE(WM_COMMAND),
    DEFINE_MESSAGE(WM_SYSCOMMAND),
    DEFINE_MESSAGE(WM_TIMER),
    DEFINE_MESSAGE(WM_HSCROLL),
    DEFINE_MESSAGE(WM_VSCROLL),
    DEFINE_MESSAGE(WM_INITMENU),
    DEFINE_MESSAGE(WM_INITMENUPOPUP),
    DEFINE_MESSAGE(WM_MENUSELECT),
    DEFINE_MESSAGE(WM_MENUCHAR),
    DEFINE_MESSAGE(WM_ENTERIDLE),
    DEFINE_MESSAGE(WM_MOUSEWHEEL),
    DEFINE_MESSAGE(WM_MOUSEMOVE),
    DEFINE_MESSAGE(WM_LBUTTONDOWN),
    DEFINE_MESSAGE(WM_LBUTTONUP),
    DEFINE_MESSAGE(WM_LBUTTONDBLCLK),
    DEFINE_MESSAGE(WM_RBUTTONDOWN),
    DEFINE_MESSAGE(WM_RBUTTONUP),
    DEFINE_MESSAGE(WM_RBUTTONDBLCLK),
    DEFINE_MESSAGE(WM_MBUTTONDOWN),
    DEFINE_MESSAGE(WM_MBUTTONUP),
    DEFINE_MESSAGE(WM_MBUTTONDBLCLK),
    DEFINE_MESSAGE(WM_PARENTNOTIFY),
    DEFINE_MESSAGE(WM_MDICREATE),
    DEFINE_MESSAGE(WM_MDIDESTROY),
    DEFINE_MESSAGE(WM_MDIACTIVATE),
    DEFINE_MESSAGE(WM_MDIRESTORE),
    DEFINE_MESSAGE(WM_MDINEXT),
    DEFINE_MESSAGE(WM_MDIMAXIMIZE),
    DEFINE_MESSAGE(WM_MDITILE),
    DEFINE_MESSAGE(WM_MDICASCADE),
    DEFINE_MESSAGE(WM_MDIICONARRANGE),
    DEFINE_MESSAGE(WM_MDIGETACTIVE),
    DEFINE_MESSAGE(WM_MDISETMENU),
    DEFINE_MESSAGE(WM_CUT),
    DEFINE_MESSAGE(WM_COPYDATA),
    DEFINE_MESSAGE(WM_COPY),
    DEFINE_MESSAGE(WM_PASTE),
    DEFINE_MESSAGE(WM_CLEAR),
    DEFINE_MESSAGE(WM_UNDO),
    DEFINE_MESSAGE(WM_RENDERFORMAT),
    DEFINE_MESSAGE(WM_RENDERALLFORMATS),
    DEFINE_MESSAGE(WM_DESTROYCLIPBOARD),
    DEFINE_MESSAGE(WM_DRAWCLIPBOARD),
    DEFINE_MESSAGE(WM_PAINTCLIPBOARD),
    DEFINE_MESSAGE(WM_VSCROLLCLIPBOARD),
    DEFINE_MESSAGE(WM_SIZECLIPBOARD),
    DEFINE_MESSAGE(WM_ASKCBFORMATNAME),
    DEFINE_MESSAGE(WM_CHANGECBCHAIN),
    DEFINE_MESSAGE(WM_HSCROLLCLIPBOARD),
    DEFINE_MESSAGE(WM_QUERYNEWPALETTE),
    DEFINE_MESSAGE(WM_PALETTEISCHANGING),
    DEFINE_MESSAGE(WM_PALETTECHANGED),
    DEFINE_MESSAGE(WM_DDE_INITIATE),
    DEFINE_MESSAGE(WM_DDE_TERMINATE),
    DEFINE_MESSAGE(WM_DDE_ADVISE),
    DEFINE_MESSAGE(WM_DDE_UNADVISE),
    DEFINE_MESSAGE(WM_DDE_ACK),
    DEFINE_MESSAGE(WM_DDE_DATA),
    DEFINE_MESSAGE(WM_DDE_REQUEST),
    DEFINE_MESSAGE(WM_DDE_POKE),
    DEFINE_MESSAGE(WM_DDE_EXECUTE),
    DEFINE_MESSAGE(WM_DROPFILES),
    DEFINE_MESSAGE(WM_POWER),
    DEFINE_MESSAGE(WM_WINDOWPOSCHANGED),
    DEFINE_MESSAGE(WM_WINDOWPOSCHANGING),
    // MFC specific messages
    /*DEFINE_MESSAGE(WM_SIZEPARENT),
    DEFINE_MESSAGE(WM_SETMESSAGESTRING),
    DEFINE_MESSAGE(WM_IDLEUPDATECMDUI),
    DEFINE_MESSAGE(WM_INITIALUPDATE),
    DEFINE_MESSAGE(WM_COMMANDHELP),
    DEFINE_MESSAGE(WM_HELPHITTEST),
    DEFINE_MESSAGE(WM_EXITHELPMODE),*/
    DEFINE_MESSAGE(WM_HELP),
    DEFINE_MESSAGE(WM_NOTIFY),
    DEFINE_MESSAGE(WM_CONTEXTMENU),
    DEFINE_MESSAGE(WM_TCARD),
    DEFINE_MESSAGE(WM_MDIREFRESHMENU),
    DEFINE_MESSAGE(WM_MOVING),
    DEFINE_MESSAGE(WM_STYLECHANGED),
    DEFINE_MESSAGE(WM_STYLECHANGING),
    DEFINE_MESSAGE(WM_SIZING),
    DEFINE_MESSAGE(WM_SETHOTKEY),
    DEFINE_MESSAGE(WM_PRINT),
    DEFINE_MESSAGE(WM_PRINTCLIENT),
    DEFINE_MESSAGE(WM_POWERBROADCAST),
    DEFINE_MESSAGE(WM_HOTKEY),
    DEFINE_MESSAGE(WM_GETICON),
    DEFINE_MESSAGE(WM_EXITMENULOOP),
    DEFINE_MESSAGE(WM_ENTERMENULOOP),
    DEFINE_MESSAGE(WM_DISPLAYCHANGE),
    DEFINE_MESSAGE(WM_STYLECHANGED),
    DEFINE_MESSAGE(WM_STYLECHANGING),
    DEFINE_MESSAGE(WM_GETICON),
    DEFINE_MESSAGE(WM_SETICON),
    DEFINE_MESSAGE(WM_SIZING),
    DEFINE_MESSAGE(WM_MOVING),
    DEFINE_MESSAGE(WM_CAPTURECHANGED),
    DEFINE_MESSAGE(WM_DEVICECHANGE),
    DEFINE_MESSAGE(WM_PRINT),
    DEFINE_MESSAGE(WM_PRINTCLIENT),
    {
        0,
        NULL,
    }  // end of message list
};
std::string CWindowsMessageToString::GetStringFromMsg(
    DWORD dwMessage, bool bShowFrequentMessages) {
  if (!bShowFrequentMessages &&
      (dwMessage == WM_MOUSEMOVE || dwMessage == WM_NCMOUSEMOVE ||
       dwMessage == WM_NCHITTEST || dwMessage == WM_SETCURSOR ||
       dwMessage == WM_CTLCOLORBTN || dwMessage == WM_CTLCOLORDLG ||
       dwMessage == WM_CTLCOLOREDIT || dwMessage == WM_CTLCOLORLISTBOX ||
       dwMessage == WM_CTLCOLORMSGBOX || dwMessage == WM_CTLCOLORSCROLLBAR ||
       dwMessage == WM_CTLCOLORSTATIC || dwMessage == WM_ENTERIDLE ||
       dwMessage == WM_CANCELMODE ||
       dwMessage == 0x0118))  // WM_SYSTIMER (caret blink)
  {
    // don't report very frequently sent messages
    return "";
  }
  const AFX_MAP_MESSAGE* pMapMsg = allMessages;
  for (/*null*/; pMapMsg->lpszMsg != NULL; pMapMsg++) {
    if (pMapMsg->nMsg == dwMessage) {
      return pMapMsg->lpszMsg;
    }
  }

  return std::to_string(dwMessage);
}

#else
std::string GetLastErrorAsString() { return ""; }
#endif

//-----------------------------------------------------------------------------
std::string OrbitUtils::GetTimeStamp() {
  time_t rawtime;
  time(&rawtime);
  return FormatTime(rawtime);
}

//-----------------------------------------------------------------------------
std::string OrbitUtils::FormatTime(const time_t& rawtime) {
  struct tm* time_info = nullptr;
  char buffer[80];
#ifdef _WIN32
  struct tm timeinfo;
  localtime_s(&timeinfo, &rawtime);
  time_info = &timeinfo;
#else
  time_info = localtime(&rawtime);
#endif

  strftime(buffer, 80, "%Y_%m_%d_%H_%M_%S", time_info);

  return std::string(buffer);
}

//-----------------------------------------------------------------------------
bool ReadProcessMemory(int32_t pid, uint64_t address, byte* buffer,
                       uint64_t size, uint64_t* num_bytes_read) {
#ifdef _WIN32
  HANDLE h_process = reinterpret_cast<HANDLE>(static_cast<uintptr_t>(pid));
  SIZE_T bytes_read;
  BOOL res = ReadProcessMemory(h_process, reinterpret_cast<void*>(address),
                               buffer, size, &bytes_read);
  if (num_bytes_read) *num_bytes_read = bytes_read;
  return res == TRUE;
#else
  iovec local_iov[] = {{buffer, size}};
  iovec remote_iov[] = {{reinterpret_cast<void*>(address), size}};
  *num_bytes_read = process_vm_readv(pid, local_iov, ABSL_ARRAYSIZE(local_iov),
                                     remote_iov, ABSL_ARRAYSIZE(remote_iov), 0);
  return *num_bytes_read == size;
#endif
}
<commit_msg>Remove dependency on ATL (#871)<commit_after>// Copyright (c) 2020 The Orbit Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "Utils.h"

#ifdef _WIN32
// clang-format off
#include <cguid.h>
#include <combaseapi.h>
// clang-format on
#else
#include <sys/uio.h>
#endif

#include <time.h>
#include <algorithm>
#include <mutex>
#include <thread>

#include "absl/base/attributes.h"

#ifdef _WIN32
//-----------------------------------------------------------------------------
std::string GetLastErrorAsString() {
  // Get the error message, if any.
  DWORD errorMessageID = ::GetLastError();
  if (errorMessageID == 0) return "No error message has been recorded";

  LPSTR messageBuffer = nullptr;
  size_t size = FormatMessageA(
      FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
          FORMAT_MESSAGE_IGNORE_INSERTS,
      NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
      (LPSTR)&messageBuffer, 0, NULL);

  std::string message(messageBuffer, size);

  // Free the buffer.
  LocalFree(messageBuffer);

  return message;
}

//-----------------------------------------------------------------------------
std::string GuidToString(GUID a_Guid) {
  std::string guidStr;
  LPOLESTR wszCLSID = NULL;
  HRESULT hr = StringFromCLSID(a_Guid, &wszCLSID);
  if (hr == S_OK) {
    // wszCLSID looks like: "{96F93FED-50B7-44B8-94AF-C205B68334FE}"
    guidStr = ws2s(wszCLSID);
    CoTaskMemFree(wszCLSID);
    auto len = guidStr.size();
    if (len > 2) {
      guidStr = guidStr.substr(1, len - 2);
    }
    guidStr.erase(std::remove(guidStr.begin(), guidStr.end(), '-'),
                  guidStr.end());
  }

  return guidStr;
}

#include "dde.h"

struct AFX_MAP_MESSAGE {
  UINT nMsg;
  LPCSTR lpszMsg;
};
#define DEFINE_MESSAGE(wm) \
  { wm, #wm }
static const AFX_MAP_MESSAGE allMessages[] = {
    DEFINE_MESSAGE(WM_CREATE),
    DEFINE_MESSAGE(WM_DESTROY),
    DEFINE_MESSAGE(WM_MOVE),
    DEFINE_MESSAGE(WM_SIZE),
    DEFINE_MESSAGE(WM_ACTIVATE),
    DEFINE_MESSAGE(WM_SETFOCUS),
    DEFINE_MESSAGE(WM_KILLFOCUS),
    DEFINE_MESSAGE(WM_ENABLE),
    DEFINE_MESSAGE(WM_SETREDRAW),
    DEFINE_MESSAGE(WM_SETTEXT),
    DEFINE_MESSAGE(WM_GETTEXT),
    DEFINE_MESSAGE(WM_GETTEXTLENGTH),
    DEFINE_MESSAGE(WM_PAINT),
    DEFINE_MESSAGE(WM_CLOSE),
    DEFINE_MESSAGE(WM_QUERYENDSESSION),
    DEFINE_MESSAGE(WM_QUIT),
    DEFINE_MESSAGE(WM_QUERYOPEN),
    DEFINE_MESSAGE(WM_ERASEBKGND),
    DEFINE_MESSAGE(WM_SYSCOLORCHANGE),
    DEFINE_MESSAGE(WM_ENDSESSION),
    DEFINE_MESSAGE(WM_SHOWWINDOW),
    DEFINE_MESSAGE(WM_CTLCOLORMSGBOX),
    DEFINE_MESSAGE(WM_CTLCOLOREDIT),
    DEFINE_MESSAGE(WM_CTLCOLORLISTBOX),
    DEFINE_MESSAGE(WM_CTLCOLORBTN),
    DEFINE_MESSAGE(WM_CTLCOLORDLG),
    DEFINE_MESSAGE(WM_CTLCOLORSCROLLBAR),
    DEFINE_MESSAGE(WM_CTLCOLORSTATIC),
    DEFINE_MESSAGE(WM_WININICHANGE),
    DEFINE_MESSAGE(WM_SETTINGCHANGE),
    DEFINE_MESSAGE(WM_DEVMODECHANGE),
    DEFINE_MESSAGE(WM_ACTIVATEAPP),
    DEFINE_MESSAGE(WM_FONTCHANGE),
    DEFINE_MESSAGE(WM_TIMECHANGE),
    DEFINE_MESSAGE(WM_CANCELMODE),
    DEFINE_MESSAGE(WM_SETCURSOR),
    DEFINE_MESSAGE(WM_MOUSEACTIVATE),
    DEFINE_MESSAGE(WM_CHILDACTIVATE),
    DEFINE_MESSAGE(WM_QUEUESYNC),
    DEFINE_MESSAGE(WM_GETMINMAXINFO),
    DEFINE_MESSAGE(WM_ICONERASEBKGND),
    DEFINE_MESSAGE(WM_NEXTDLGCTL),
    DEFINE_MESSAGE(WM_SPOOLERSTATUS),
    DEFINE_MESSAGE(WM_DRAWITEM),
    DEFINE_MESSAGE(WM_MEASUREITEM),
    DEFINE_MESSAGE(WM_DELETEITEM),
    DEFINE_MESSAGE(WM_VKEYTOITEM),
    DEFINE_MESSAGE(WM_CHARTOITEM),
    DEFINE_MESSAGE(WM_SETFONT),
    DEFINE_MESSAGE(WM_GETFONT),
    DEFINE_MESSAGE(WM_QUERYDRAGICON),
    DEFINE_MESSAGE(WM_COMPAREITEM),
    DEFINE_MESSAGE(WM_COMPACTING),
    DEFINE_MESSAGE(WM_NCCREATE),
    DEFINE_MESSAGE(WM_NCDESTROY),
    DEFINE_MESSAGE(WM_NCCALCSIZE),
    DEFINE_MESSAGE(WM_NCHITTEST),
    DEFINE_MESSAGE(WM_NCPAINT),
    DEFINE_MESSAGE(WM_NCACTIVATE),
    DEFINE_MESSAGE(WM_GETDLGCODE),
    DEFINE_MESSAGE(WM_NCMOUSEMOVE),
    DEFINE_MESSAGE(WM_NCLBUTTONDOWN),
    DEFINE_MESSAGE(WM_NCLBUTTONUP),
    DEFINE_MESSAGE(WM_NCLBUTTONDBLCLK),
    DEFINE_MESSAGE(WM_NCRBUTTONDOWN),
    DEFINE_MESSAGE(WM_NCRBUTTONUP),
    DEFINE_MESSAGE(WM_NCRBUTTONDBLCLK),
    DEFINE_MESSAGE(WM_NCMBUTTONDOWN),
    DEFINE_MESSAGE(WM_NCMBUTTONUP),
    DEFINE_MESSAGE(WM_NCMBUTTONDBLCLK),
    DEFINE_MESSAGE(WM_KEYDOWN),
    DEFINE_MESSAGE(WM_KEYUP),
    DEFINE_MESSAGE(WM_CHAR),
    DEFINE_MESSAGE(WM_DEADCHAR),
    DEFINE_MESSAGE(WM_SYSKEYDOWN),
    DEFINE_MESSAGE(WM_SYSKEYUP),
    DEFINE_MESSAGE(WM_SYSCHAR),
    DEFINE_MESSAGE(WM_SYSDEADCHAR),
    DEFINE_MESSAGE(WM_KEYLAST),
    DEFINE_MESSAGE(WM_INITDIALOG),
    DEFINE_MESSAGE(WM_COMMAND),
    DEFINE_MESSAGE(WM_SYSCOMMAND),
    DEFINE_MESSAGE(WM_TIMER),
    DEFINE_MESSAGE(WM_HSCROLL),
    DEFINE_MESSAGE(WM_VSCROLL),
    DEFINE_MESSAGE(WM_INITMENU),
    DEFINE_MESSAGE(WM_INITMENUPOPUP),
    DEFINE_MESSAGE(WM_MENUSELECT),
    DEFINE_MESSAGE(WM_MENUCHAR),
    DEFINE_MESSAGE(WM_ENTERIDLE),
    DEFINE_MESSAGE(WM_MOUSEWHEEL),
    DEFINE_MESSAGE(WM_MOUSEMOVE),
    DEFINE_MESSAGE(WM_LBUTTONDOWN),
    DEFINE_MESSAGE(WM_LBUTTONUP),
    DEFINE_MESSAGE(WM_LBUTTONDBLCLK),
    DEFINE_MESSAGE(WM_RBUTTONDOWN),
    DEFINE_MESSAGE(WM_RBUTTONUP),
    DEFINE_MESSAGE(WM_RBUTTONDBLCLK),
    DEFINE_MESSAGE(WM_MBUTTONDOWN),
    DEFINE_MESSAGE(WM_MBUTTONUP),
    DEFINE_MESSAGE(WM_MBUTTONDBLCLK),
    DEFINE_MESSAGE(WM_PARENTNOTIFY),
    DEFINE_MESSAGE(WM_MDICREATE),
    DEFINE_MESSAGE(WM_MDIDESTROY),
    DEFINE_MESSAGE(WM_MDIACTIVATE),
    DEFINE_MESSAGE(WM_MDIRESTORE),
    DEFINE_MESSAGE(WM_MDINEXT),
    DEFINE_MESSAGE(WM_MDIMAXIMIZE),
    DEFINE_MESSAGE(WM_MDITILE),
    DEFINE_MESSAGE(WM_MDICASCADE),
    DEFINE_MESSAGE(WM_MDIICONARRANGE),
    DEFINE_MESSAGE(WM_MDIGETACTIVE),
    DEFINE_MESSAGE(WM_MDISETMENU),
    DEFINE_MESSAGE(WM_CUT),
    DEFINE_MESSAGE(WM_COPYDATA),
    DEFINE_MESSAGE(WM_COPY),
    DEFINE_MESSAGE(WM_PASTE),
    DEFINE_MESSAGE(WM_CLEAR),
    DEFINE_MESSAGE(WM_UNDO),
    DEFINE_MESSAGE(WM_RENDERFORMAT),
    DEFINE_MESSAGE(WM_RENDERALLFORMATS),
    DEFINE_MESSAGE(WM_DESTROYCLIPBOARD),
    DEFINE_MESSAGE(WM_DRAWCLIPBOARD),
    DEFINE_MESSAGE(WM_PAINTCLIPBOARD),
    DEFINE_MESSAGE(WM_VSCROLLCLIPBOARD),
    DEFINE_MESSAGE(WM_SIZECLIPBOARD),
    DEFINE_MESSAGE(WM_ASKCBFORMATNAME),
    DEFINE_MESSAGE(WM_CHANGECBCHAIN),
    DEFINE_MESSAGE(WM_HSCROLLCLIPBOARD),
    DEFINE_MESSAGE(WM_QUERYNEWPALETTE),
    DEFINE_MESSAGE(WM_PALETTEISCHANGING),
    DEFINE_MESSAGE(WM_PALETTECHANGED),
    DEFINE_MESSAGE(WM_DDE_INITIATE),
    DEFINE_MESSAGE(WM_DDE_TERMINATE),
    DEFINE_MESSAGE(WM_DDE_ADVISE),
    DEFINE_MESSAGE(WM_DDE_UNADVISE),
    DEFINE_MESSAGE(WM_DDE_ACK),
    DEFINE_MESSAGE(WM_DDE_DATA),
    DEFINE_MESSAGE(WM_DDE_REQUEST),
    DEFINE_MESSAGE(WM_DDE_POKE),
    DEFINE_MESSAGE(WM_DDE_EXECUTE),
    DEFINE_MESSAGE(WM_DROPFILES),
    DEFINE_MESSAGE(WM_POWER),
    DEFINE_MESSAGE(WM_WINDOWPOSCHANGED),
    DEFINE_MESSAGE(WM_WINDOWPOSCHANGING),
    // MFC specific messages
    /*DEFINE_MESSAGE(WM_SIZEPARENT),
    DEFINE_MESSAGE(WM_SETMESSAGESTRING),
    DEFINE_MESSAGE(WM_IDLEUPDATECMDUI),
    DEFINE_MESSAGE(WM_INITIALUPDATE),
    DEFINE_MESSAGE(WM_COMMANDHELP),
    DEFINE_MESSAGE(WM_HELPHITTEST),
    DEFINE_MESSAGE(WM_EXITHELPMODE),*/
    DEFINE_MESSAGE(WM_HELP),
    DEFINE_MESSAGE(WM_NOTIFY),
    DEFINE_MESSAGE(WM_CONTEXTMENU),
    DEFINE_MESSAGE(WM_TCARD),
    DEFINE_MESSAGE(WM_MDIREFRESHMENU),
    DEFINE_MESSAGE(WM_MOVING),
    DEFINE_MESSAGE(WM_STYLECHANGED),
    DEFINE_MESSAGE(WM_STYLECHANGING),
    DEFINE_MESSAGE(WM_SIZING),
    DEFINE_MESSAGE(WM_SETHOTKEY),
    DEFINE_MESSAGE(WM_PRINT),
    DEFINE_MESSAGE(WM_PRINTCLIENT),
    DEFINE_MESSAGE(WM_POWERBROADCAST),
    DEFINE_MESSAGE(WM_HOTKEY),
    DEFINE_MESSAGE(WM_GETICON),
    DEFINE_MESSAGE(WM_EXITMENULOOP),
    DEFINE_MESSAGE(WM_ENTERMENULOOP),
    DEFINE_MESSAGE(WM_DISPLAYCHANGE),
    DEFINE_MESSAGE(WM_STYLECHANGED),
    DEFINE_MESSAGE(WM_STYLECHANGING),
    DEFINE_MESSAGE(WM_GETICON),
    DEFINE_MESSAGE(WM_SETICON),
    DEFINE_MESSAGE(WM_SIZING),
    DEFINE_MESSAGE(WM_MOVING),
    DEFINE_MESSAGE(WM_CAPTURECHANGED),
    DEFINE_MESSAGE(WM_DEVICECHANGE),
    DEFINE_MESSAGE(WM_PRINT),
    DEFINE_MESSAGE(WM_PRINTCLIENT),
    {
        0,
        NULL,
    }  // end of message list
};
std::string CWindowsMessageToString::GetStringFromMsg(
    DWORD dwMessage, bool bShowFrequentMessages) {
  if (!bShowFrequentMessages &&
      (dwMessage == WM_MOUSEMOVE || dwMessage == WM_NCMOUSEMOVE ||
       dwMessage == WM_NCHITTEST || dwMessage == WM_SETCURSOR ||
       dwMessage == WM_CTLCOLORBTN || dwMessage == WM_CTLCOLORDLG ||
       dwMessage == WM_CTLCOLOREDIT || dwMessage == WM_CTLCOLORLISTBOX ||
       dwMessage == WM_CTLCOLORMSGBOX || dwMessage == WM_CTLCOLORSCROLLBAR ||
       dwMessage == WM_CTLCOLORSTATIC || dwMessage == WM_ENTERIDLE ||
       dwMessage == WM_CANCELMODE ||
       dwMessage == 0x0118))  // WM_SYSTIMER (caret blink)
  {
    // don't report very frequently sent messages
    return "";
  }
  const AFX_MAP_MESSAGE* pMapMsg = allMessages;
  for (/*null*/; pMapMsg->lpszMsg != NULL; pMapMsg++) {
    if (pMapMsg->nMsg == dwMessage) {
      return pMapMsg->lpszMsg;
    }
  }

  return std::to_string(dwMessage);
}

#else
std::string GetLastErrorAsString() { return ""; }
#endif

//-----------------------------------------------------------------------------
std::string OrbitUtils::GetTimeStamp() {
  time_t rawtime;
  time(&rawtime);
  return FormatTime(rawtime);
}

//-----------------------------------------------------------------------------
std::string OrbitUtils::FormatTime(const time_t& rawtime) {
  struct tm* time_info = nullptr;
  char buffer[80];
#ifdef _WIN32
  struct tm timeinfo;
  localtime_s(&timeinfo, &rawtime);
  time_info = &timeinfo;
#else
  time_info = localtime(&rawtime);
#endif

  strftime(buffer, 80, "%Y_%m_%d_%H_%M_%S", time_info);

  return std::string(buffer);
}

//-----------------------------------------------------------------------------
bool ReadProcessMemory(int32_t pid, uint64_t address, byte* buffer,
                       uint64_t size, uint64_t* num_bytes_read) {
#ifdef _WIN32
  HANDLE h_process = reinterpret_cast<HANDLE>(static_cast<uintptr_t>(pid));
  SIZE_T bytes_read;
  BOOL res = ReadProcessMemory(h_process, reinterpret_cast<void*>(address),
                               buffer, size, &bytes_read);
  if (num_bytes_read) *num_bytes_read = bytes_read;
  return res == TRUE;
#else
  iovec local_iov[] = {{buffer, size}};
  iovec remote_iov[] = {{reinterpret_cast<void*>(address), size}};
  *num_bytes_read = process_vm_readv(pid, local_iov, ABSL_ARRAYSIZE(local_iov),
                                     remote_iov, ABSL_ARRAYSIZE(remote_iov), 0);
  return *num_bytes_read == size;
#endif
}
<|endoftext|>


<commit_before>// Time:  O(k * C(n, k)), k is max length of combination
// Space: O(k)

class Solution {
public:
    /**
     * @param num: Given the candidate numbers
     * @param target: Given the target number
     * @return: All the combinations that sum to target
     */
    vector<vector<int>> combinationSum2(vector<int> &num, int target) {
        sort(num.begin(), num.end());
        vector<vector<int>> ans;
        vector<int> v;
        combinationSum2Helper(num, target, 0, v, ans);
        return ans;
    }

private:
    void combinationSum2Helper(vector<int>& num, int gap, int begin, vector<int>& v,vector<vector<int>> &ans) {
        if (gap == 0) {
            ans.emplace_back(v);
            return;
        }

        for (size_t i = begin; i < num.size() && num[i] <= gap; i++) {
            if ( i == begin || num[i] != num[i - 1]) {  // Skip duplicates.
                v.emplace_back(num[i]);
                // Each same element could be chosen only once
                // with the same previous nums.
                combinationSum2Helper(num, gap - num[i], i + 1, v, ans);
                v.pop_back();
            }
        }
    }
};
<commit_msg>Update combination-sum-ii.cpp<commit_after>// Time:  O(k * C(n, k)), k is max length of combination
// Space: O(k)

class Solution {
public:
    /**
     * @param num: Given the candidate numbers
     * @param target: Given the target number
     * @return: All the combinations that sum to target
     */
    vector<vector<int>> combinationSum2(vector<int> &num, int target) {
        sort(num.begin(), num.end());
        vector<vector<int>> ans;
        vector<int> v;
        combinationSum2Helper(num, target, 0, v, ans);
        return ans;
    }

private:
    void combinationSum2Helper(vector<int>& num, int gap, int begin, vector<int>& v,vector<vector<int>> &ans) {
        if (gap == 0) {
            ans.emplace_back(v);
            return;
        }

        for (size_t i = begin; i < num.size() && num[i] <= gap; i++) {
            if ( i == begin || num[i] != num[i - 1]) {  // Skip duplicates.
                // Each same element could be chosen only once
                // with the same previous nums.
                v.emplace_back(num[i]);
                combinationSum2Helper(num, gap - num[i], i + 1, v, ans);
                v.pop_back();
            }
        }
    }
};
<|endoftext|>


<commit_before>//
// Created by Sam on 9/25/2017.
//

#include "../../include/Game/Board.h"
#include "../../include/Game/Card.h"
#include "../../include/Game/Game.h"
#include "../../include/Game/Player.h"
#include "../../include/Network/Client.h"
#include "../../include/Network/HTTPRequest.h"
#include "../../include/Network/Message.h"
#include "../../include/Network/Server.h"
#include "../../include/Network/Request/Lobby/AuthMessage.h"
#include "../../include/Network/Request/Lobby/QueueMessage.h"

#include <iostream>
#include <utility>
#include <pybind11/pytypes.h>

Client::pointer Client::create(boost::asio::io_service &ioService)
{
    return pointer(new Client(ioService));
}

boost::asio::ip::tcp::socket & Client::getSocket()
{
    return socket;
}

std::string Client::getAddress()
{
    return shared_from_this()->getSocket().remote_endpoint().address().to_string();
}

void Client::start(std::shared_ptr<Server> server)
{
    this->server = std::move(server);
    write(Message::success());

    listening = true;
    write(Message::login());
    asyncListen(&Client::lobbyListen);
}

void Client::write(std::string data)
{
    data.append(delimiter);

    boost::asio::async_write(socket, boost::asio::buffer(data.c_str(), data.size()),
                             boost::bind(&Client::onWrite, shared_from_this(),
                                         boost::asio::placeholders::error, data));
}

void Client::disconnect()
{
    if (player->game->players.size() > 1)
    {
        player->quit();
    }

    socket.close();
    server->removeClient(shared_from_this());
    std::cout << "Lost connection to client!" << std::endl;
}

void Client::asyncListen(func callback)
{
    boost::asio::async_read_until(socket, buffer, delimiter,
                                  boost::bind(&Client::listen, shared_from_this(),
                                              boost::asio::placeholders::error, callback));
}

void Client::listen(const boost::system::error_code &errorCode, func callback)
{
    if (errorCode.value() == WINDOWS_ERROR_OPERATION_ABORTED or errorCode.value() == UNIX_ECANCELED)
    {
        return;
    }

    if (errorCode == nullptr && listening)
    {
        try
        {
            (*this.*callback)();
        }
        catch(const std::exception &error)
        {
            std::cout << "Error during callback: " << error.what() << std::endl;
            write(Message::fail(error.what()));
            asyncListen(callback);
        }
    }
    else
    {
        disconnect();
        std::cout << "Error code: " << errorCode.value() << std::endl;
    }
}

void Client::handleQueue(const json& rawJSON)
{
    QueueMessage qMessage(rawJSON);

    player = std::make_shared<Player>(shared_from_this());
    assembleDeck(qMessage.deckID);

    server->queue.push_back(player);
    std::cout << "Queue | Name: " << player->name << " deckID: " << qMessage.deckID << std::endl;

    // Send the player into the gameListen function
    listenerCallback = &Client::gameListen;
}

void Client::handleLogin(const json& rawJSON)
{
    AuthMessage authMessage(rawJSON);

    steamID = HTTPRequest::getSteamID(authMessage.token);

    handleNewPlayerSetup();

    json playerInfoJSON = HTTPRequest::getPlayerInfo(steamID);
    name = playerInfoJSON["personaname"];
    avatarURL = playerInfoJSON["avatarfull"];

    server->addClient(shared_from_this());

    json deckJSON = createRegisterPlayerJSON();
    write(Message::registerPlayer(deckJSON, shared_from_this()));
}

void Client::handleNewPlayerSetup()
{
    if (server->database.isNewSteamID(steamID))
    {
        server->database.setupUser(steamID);
    }
}

std::vector<json> Client::createRegisterPlayerJSON() const
{
    std::vector<json> deckJSON;

    std::map<std::string, Deck> deckMap = server->database.getAllDeckCards(steamID, &server->factory);

    for (const auto& deckInfo : deckMap)
    {
        Deck deck = deckInfo.second;
        deckJSON.push_back(deck.getJSON());
    }

    return deckJSON;
}

std::string Client::getString(boost::asio::streambuf &buffer)
{
    boost::asio::streambuf::const_buffers_type bufs = buffer.data();
    std::string data(
            boost::asio::buffers_begin(bufs),
            boost::asio::buffers_begin(bufs) + buffer.size());

    emptyBuffer();

    // Return everything except the last character delimeter
    return data.substr(0, data.size() - 1);
}

void Client::emptyBuffer()
{
    buffer.consume(buffer.size());
}

void Client::onWrite(const boost::system::error_code &errorCode, const std::string& data)
{
    if (errorCode != nullptr)
    {
        std::cout << "Failed to send " << getAddress() << " '" << data.substr(0, data.size()-1) << "'" << std::endl;
    }
}

void Client::assembleDeck(const std::string& deckID)
{
    std::vector<std::string> pythonNames = server->database.getDeckCards(steamID, deckID);

    std::vector<std::shared_ptr<Card>> cards;
    for (const auto &pythonName : pythonNames)
    {
        auto card = server->factory.createCard(pythonName);
        card->player = player;
        cards.push_back(card);
    }

    player->board->deck = std::make_shared<Deck>(deckID, cards);
}

void Client::assembleProtocolMap()
{
    lobbyFunctions[Message::LOGIN] = &Client::handleLogin;
    lobbyFunctions[Message::QUEUE] = &Client::handleQueue;

    gameFunctions[Message::CHAT] = &Player::sendChatMessage;
    gameFunctions[Message::PLAY_CARD] = &Player::playCard;
    gameFunctions[Message::STOP_TURN] = &Player::endTurn;
    gameFunctions[Message::STOP_GAME] = &Player::surrender;
    gameFunctions[Message::FIGHT_PLAYER] = &Player::fightPlayer;
    gameFunctions[Message::FIGHT_CREATURE] = &Player::fightCreature;
}

void Client::lobbyListen()
{
    std::string data = getString(buffer);
    auto rawJSON = json::parse(data);
    std::string type = rawJSON[Message::TYPE_KEY];

    auto iterator = lobbyFunctions.find(type);
    bool callable = !(iterator == lobbyFunctions.end());

    if (callable)
    {
        ((*this).*lobbyFunctions[type])(rawJSON);
    }
    else
    {
        write(Message::fail("Unknown lobby protocol '" + type + "'"));
    }

    asyncListen(listenerCallback);
}

void Client::gameListen()
{
    std::string data = getString(buffer);
    auto rawJSON = json::parse(data);
    std::string type = rawJSON[Message::TYPE_KEY];

    auto iterator = gameFunctions.find(type);
    bool callable = !(iterator == gameFunctions.end());

    if (callable)
    {
        ((*player).*gameFunctions[type])(rawJSON);
    }
    else
    {
        write(Message::fail("Unknown game protocol '" + type + "'"));
    }

    asyncListen(listenerCallback);
}

void Client::resetLobbyListen()
{
    getSocket().cancel();
    asyncListen(&Client::lobbyListen);
}

Client::Client(boost::asio::io_service & ioService)
        : player(nullptr), server(nullptr),
          listening(false), socket(ioService), delimiter("\n"), listenerCallback(&Client::lobbyListen)
{
    assembleProtocolMap();
}
<commit_msg>Added an if statement to prevent a segfault when checking the players in the game<commit_after>//
// Created by Sam on 9/25/2017.
//

#include "../../include/Game/Board.h"
#include "../../include/Game/Card.h"
#include "../../include/Game/Game.h"
#include "../../include/Game/Player.h"
#include "../../include/Network/Client.h"
#include "../../include/Network/HTTPRequest.h"
#include "../../include/Network/Message.h"
#include "../../include/Network/Server.h"
#include "../../include/Network/Request/Lobby/AuthMessage.h"
#include "../../include/Network/Request/Lobby/QueueMessage.h"

#include <iostream>
#include <utility>
#include <pybind11/pytypes.h>

Client::pointer Client::create(boost::asio::io_service &ioService)
{
    return pointer(new Client(ioService));
}

boost::asio::ip::tcp::socket & Client::getSocket()
{
    return socket;
}

std::string Client::getAddress()
{
    return shared_from_this()->getSocket().remote_endpoint().address().to_string();
}

void Client::start(std::shared_ptr<Server> server)
{
    this->server = std::move(server);
    write(Message::success());

    listening = true;
    write(Message::login());
    asyncListen(&Client::lobbyListen);
}

void Client::write(std::string data)
{
    data.append(delimiter);

    boost::asio::async_write(socket, boost::asio::buffer(data.c_str(), data.size()),
                             boost::bind(&Client::onWrite, shared_from_this(),
                                         boost::asio::placeholders::error, data));
}

void Client::disconnect()
{
    if (player->game)
    {
        if (player->game->players.size() > 1)
        {
            player->quit();
        }
    }

    socket.close();
    server->removeClient(shared_from_this());
    std::cout << "Lost connection to client!" << std::endl;
}

void Client::asyncListen(func callback)
{
    boost::asio::async_read_until(socket, buffer, delimiter,
                                  boost::bind(&Client::listen, shared_from_this(),
                                              boost::asio::placeholders::error, callback));
}

void Client::listen(const boost::system::error_code &errorCode, func callback)
{
    if (errorCode.value() == WINDOWS_ERROR_OPERATION_ABORTED or errorCode.value() == UNIX_ECANCELED)
    {
        return;
    }

    if (errorCode == nullptr && listening)
    {
        try
        {
            (*this.*callback)();
        }
        catch(const std::exception &error)
        {
            std::cout << "Error during callback: " << error.what() << std::endl;
            write(Message::fail(error.what()));
            asyncListen(callback);
        }
    }
    else
    {
        disconnect();
        std::cout << "Error code: " << errorCode.value() << std::endl;
    }
}

void Client::handleQueue(const json& rawJSON)
{
    QueueMessage qMessage(rawJSON);

    player = std::make_shared<Player>(shared_from_this());
    assembleDeck(qMessage.deckID);

    server->queue.push_back(player);
    std::cout << "Queue | Name: " << player->name << " deckID: " << qMessage.deckID << std::endl;

    // Send the player into the gameListen function
    listenerCallback = &Client::gameListen;
}

void Client::handleLogin(const json& rawJSON)
{
    AuthMessage authMessage(rawJSON);

    steamID = HTTPRequest::getSteamID(authMessage.token);

    handleNewPlayerSetup();

    json playerInfoJSON = HTTPRequest::getPlayerInfo(steamID);
    name = playerInfoJSON["personaname"];
    avatarURL = playerInfoJSON["avatarfull"];

    server->addClient(shared_from_this());

    json deckJSON = createRegisterPlayerJSON();
    write(Message::registerPlayer(deckJSON, shared_from_this()));
}

void Client::handleNewPlayerSetup()
{
    if (server->database.isNewSteamID(steamID))
    {
        server->database.setupUser(steamID);
    }
}

std::vector<json> Client::createRegisterPlayerJSON() const
{
    std::vector<json> deckJSON;

    std::map<std::string, Deck> deckMap = server->database.getAllDeckCards(steamID, &server->factory);

    for (const auto& deckInfo : deckMap)
    {
        Deck deck = deckInfo.second;
        deckJSON.push_back(deck.getJSON());
    }

    return deckJSON;
}

std::string Client::getString(boost::asio::streambuf &buffer)
{
    boost::asio::streambuf::const_buffers_type bufs = buffer.data();
    std::string data(
            boost::asio::buffers_begin(bufs),
            boost::asio::buffers_begin(bufs) + buffer.size());

    emptyBuffer();

    // Return everything except the last character delimeter
    return data.substr(0, data.size() - 1);
}

void Client::emptyBuffer()
{
    buffer.consume(buffer.size());
}

void Client::onWrite(const boost::system::error_code &errorCode, const std::string& data)
{
    if (errorCode != nullptr)
    {
        std::cout << "Failed to send " << getAddress() << " '" << data.substr(0, data.size()-1) << "'" << std::endl;
    }
}

void Client::assembleDeck(const std::string& deckID)
{
    std::vector<std::string> pythonNames = server->database.getDeckCards(steamID, deckID);

    std::vector<std::shared_ptr<Card>> cards;
    for (const auto &pythonName : pythonNames)
    {
        auto card = server->factory.createCard(pythonName);
        card->player = player;
        cards.push_back(card);
    }

    player->board->deck = std::make_shared<Deck>(deckID, cards);
}

void Client::assembleProtocolMap()
{
    lobbyFunctions[Message::LOGIN] = &Client::handleLogin;
    lobbyFunctions[Message::QUEUE] = &Client::handleQueue;

    gameFunctions[Message::CHAT] = &Player::sendChatMessage;
    gameFunctions[Message::PLAY_CARD] = &Player::playCard;
    gameFunctions[Message::STOP_TURN] = &Player::endTurn;
    gameFunctions[Message::STOP_GAME] = &Player::surrender;
    gameFunctions[Message::FIGHT_PLAYER] = &Player::fightPlayer;
    gameFunctions[Message::FIGHT_CREATURE] = &Player::fightCreature;
}

void Client::lobbyListen()
{
    std::string data = getString(buffer);
    auto rawJSON = json::parse(data);
    std::string type = rawJSON[Message::TYPE_KEY];

    auto iterator = lobbyFunctions.find(type);
    bool callable = !(iterator == lobbyFunctions.end());

    if (callable)
    {
        ((*this).*lobbyFunctions[type])(rawJSON);
    }
    else
    {
        write(Message::fail("Unknown lobby protocol '" + type + "'"));
    }

    asyncListen(listenerCallback);
}

void Client::gameListen()
{
    std::string data = getString(buffer);
    auto rawJSON = json::parse(data);
    std::string type = rawJSON[Message::TYPE_KEY];

    auto iterator = gameFunctions.find(type);
    bool callable = !(iterator == gameFunctions.end());

    if (callable)
    {
        ((*player).*gameFunctions[type])(rawJSON);
    }
    else
    {
        write(Message::fail("Unknown game protocol '" + type + "'"));
    }

    asyncListen(listenerCallback);
}

void Client::resetLobbyListen()
{
    getSocket().cancel();
    asyncListen(&Client::lobbyListen);
}

Client::Client(boost::asio::io_service & ioService)
        : player(nullptr), server(nullptr),
          listening(false), socket(ioService), delimiter("\n"), listenerCallback(&Client::lobbyListen)
{
    assembleProtocolMap();
}
<|endoftext|>


<commit_before>#include <time.h>
#include <string>
#include <sstream>
#include "Foundation.h"
#include "AlembicLicensing.h"
#include "Alembic.h"
#include <maxscript/maxscript.h>

using namespace std;

#ifndef EC_LOG_ERROR
	#define EC_LOG_ERROR(a)		ESS_LOG_ERROR(a)
#endif
#ifndef EC_LOG_WARNING
	#define EC_LOG_WARNING(a)	ESS_LOG_WARNING(a)
#endif
#ifndef EC_LOG_INFO
	#define EC_LOG_INFO(a)		ESS_LOG_INFO(a)
#endif
#ifndef EC_ASSERT
	#define EC_ASSERT(a)
#endif

#include "RlmSingleton.h"

int gLicenseToken = EC_LICENSE_RESULT_NO_LICENSE;

#if defined( EXOCORTEX_RLM_ONLY )
	#include "RlmSingletonDeclarations.h"
#endif // EXOCORTEX_RLM_ONLY

bool HasFullLicense()
{
	return ( GetLicense() == EC_LICENSE_RESULT_FULL_LICENSE );
}

int GetLicense()
{
	if( gLicenseToken == EC_LICENSE_RESULT_NO_LICENSE )
	{
		// default license status, could be overriden below.
		gLicenseToken = EC_LICENSE_RESULT_DEMO_LICENSE;

		// check RLM license first, so that users see that RLM is either used or not prior to expiry.
#if defined( EXOCORTEX_RLM_ONLY )
		{
			#pragma message( "Exocortex Licensing mode: RLM only" )
			static string pluginName(PLUGIN_NAME);
			ESS_LOG_INFO( "Looking for RLM license for " << pluginName << "..." );
			Exocortex::RlmSingleton& rlmSingleton = Exocortex::RlmSingleton::getSingleton();

			RlmProductID pluginLicenseIds2[] = ALEMBIC_WRITER_LICENSE_IDS;
			vector<RlmProductID> rlmProductIds;
			for( int i = 0; i < sizeof( pluginLicenseIds2 ) / sizeof( RlmProductID ); i ++ ) {
				rlmProductIds.push_back( pluginLicenseIds2[i] );
			}

			if( rlmSingleton.checkoutLicense( "", pluginName, rlmProductIds ) ) {
				gLicenseToken = EC_LICENSE_RESULT_FULL_LICENSE;
				return gLicenseToken;
			}
		}
#endif // EXOCORTEX_RLM_ONLY

#if defined( EXOCORTEX_BETA_EXPIRY_DATE )
		{
			#pragma message( "Exocortex Licensing mode: Fixed expiry date" )
			time_t now = time(NULL);
			if( now <= EXOCORTEX_BETA_EXPIRY_DATE ) {  //http://unixtime-converter.com/
				static string pluginName(PLUGIN_NAME);
				ESS_LOG_WARNING( "Expiry date licensing is being used for " << pluginName );
				gLicenseToken = EC_LICENSE_RESULT_FULL_LICENSE;
				return gLicenseToken;
			}
		}
#endif // Exocortex_BETA_EXPIRY_DATE

	}

	return gLicenseToken;
}

#ifdef EXOCORTEX_SERVICES

void MaxLogSink(const char* szLogMessage, Exocortex::ecLogLevel::Value level ) {
	mprintf( "Exocortex Alembic: %s\n", szLogMessage );
}

namespace Exocortex {
	void essOnDemandInitialization() {
		static string pluginName(PLUGIN_NAME);

		essInitialize( pluginName.c_str(), PLUGIN_MAJOR_VERSION, PLUGIN_MINOR_VERSION, "C:\\ExocortexLogs", MaxLogSink );
		//ESS_LOG_INFO( "Exocortex Alembic for 3DS Max initialized." );
	}
}

#endif // EXOCORTEX_SERVICES
<commit_msg>INFO messages go to the file log only, only warning and errors go to the MAXScript Listener log window.<commit_after>#include <time.h>
#include <string>
#include <sstream>
#include "Foundation.h"
#include "AlembicLicensing.h"
#include "Alembic.h"
#include <maxscript/maxscript.h>

using namespace std;

#ifndef EC_LOG_ERROR
	#define EC_LOG_ERROR(a)		ESS_LOG_ERROR(a)
#endif
#ifndef EC_LOG_WARNING
	#define EC_LOG_WARNING(a)	ESS_LOG_WARNING(a)
#endif
#ifndef EC_LOG_INFO
	#define EC_LOG_INFO(a)		ESS_LOG_INFO(a)
#endif
#ifndef EC_ASSERT
	#define EC_ASSERT(a)
#endif

#include "RlmSingleton.h"

int gLicenseToken = EC_LICENSE_RESULT_NO_LICENSE;

#if defined( EXOCORTEX_RLM_ONLY )
	#include "RlmSingletonDeclarations.h"
#endif // EXOCORTEX_RLM_ONLY

bool HasFullLicense()
{
	return ( GetLicense() == EC_LICENSE_RESULT_FULL_LICENSE );
}

int GetLicense()
{
	if( gLicenseToken == EC_LICENSE_RESULT_NO_LICENSE )
	{
		// default license status, could be overriden below.
		gLicenseToken = EC_LICENSE_RESULT_DEMO_LICENSE;

		// check RLM license first, so that users see that RLM is either used or not prior to expiry.
#if defined( EXOCORTEX_RLM_ONLY )
		{
			#pragma message( "Exocortex Licensing mode: RLM only" )
			static string pluginName(PLUGIN_NAME);
			ESS_LOG_INFO( "Looking for RLM license for " << pluginName << "..." );
			Exocortex::RlmSingleton& rlmSingleton = Exocortex::RlmSingleton::getSingleton();

			RlmProductID pluginLicenseIds2[] = ALEMBIC_WRITER_LICENSE_IDS;
			vector<RlmProductID> rlmProductIds;
			for( int i = 0; i < sizeof( pluginLicenseIds2 ) / sizeof( RlmProductID ); i ++ ) {
				rlmProductIds.push_back( pluginLicenseIds2[i] );
			}

			if( rlmSingleton.checkoutLicense( "", pluginName, rlmProductIds ) ) {
				gLicenseToken = EC_LICENSE_RESULT_FULL_LICENSE;
				return gLicenseToken;
			}
		}
#endif // EXOCORTEX_RLM_ONLY

#if defined( EXOCORTEX_BETA_EXPIRY_DATE )
		{
			#pragma message( "Exocortex Licensing mode: Fixed expiry date" )
			time_t now = time(NULL);
			if( now <= EXOCORTEX_BETA_EXPIRY_DATE ) {  //http://unixtime-converter.com/
				static string pluginName(PLUGIN_NAME);
				ESS_LOG_WARNING( "Expiry date licensing is being used for " << pluginName );
				gLicenseToken = EC_LICENSE_RESULT_FULL_LICENSE;
				return gLicenseToken;
			}
		}
#endif // Exocortex_BETA_EXPIRY_DATE

	}

	return gLicenseToken;
}

#ifdef EXOCORTEX_SERVICES

void MaxLogSink(const char* szLogMessage, Exocortex::ecLogLevel::Value level ) {
	if( level != Exocortex::ecLogLevel::Info ) {
		mprintf( "Exocortex Alembic: %s\n", szLogMessage );
	}
	switch( level ) {
	case Exocortex::ecLogLevel::Info:
		//mprintf( "Exocortex Alembic: %s\n", szLogMessage );
		break;
	case Exocortex::ecLogLevel::Warning:
		mprintf( "Exocortex Alembic Warning: %s\n", szLogMessage );
		break;
	case Exocortex::ecLogLevel::Error:
		mprintf( "Exocortex Alembic Error: %s\n", szLogMessage );
		break;
	}
}

namespace Exocortex {
	void essOnDemandInitialization() {
		static string pluginName(PLUGIN_NAME);

		essInitialize( pluginName.c_str(), PLUGIN_MAJOR_VERSION, PLUGIN_MINOR_VERSION, "C:\\ExocortexLogs", MaxLogSink );
		//ESS_LOG_INFO( "Exocortex Alembic for 3DS Max initialized." );
	}
}

#endif // EXOCORTEX_SERVICES
<|endoftext|>


<commit_before>/* dlvhex -- Answer-Set Programming with external interfaces.
 * Copyright (C) 2005, 2006, 2007 Roman Schindlauer
 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Thomas Krennwallner
 * Copyright (C) 2009, 2010 Peter Schüller
 * Copyright (C) 2011, 2012, 2013 Christoph Redl
 *
 * This file is part of dlvhex.
 *
 * dlvhex 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.
 *
 * dlvhex 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 dlvhex; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA.
 */

/**
 * @file NogoodGrounder.cpp
 * @author Christoph Redl
 *
 * @brief Implements a grounder for nonground nogoods.
 */

#define DLVHEX_BENCHMARK

#include "dlvhex2/NogoodGrounder.h"
#include "dlvhex2/Logger.h"
#include "dlvhex2/Registry.h"
#include "dlvhex2/Printer.h"
#include "dlvhex2/Benchmarking.h"
#include "dlvhex2/Nogood.h"

#include <bm/bmalgo.h>

#include <boost/foreach.hpp>

DLVHEX_NAMESPACE_BEGIN

NogoodGrounder::NogoodGrounder(RegistryPtr reg, SimpleNogoodContainerPtr watched, SimpleNogoodContainerPtr destination, AnnotatedGroundProgram& agp) :
	reg(reg), watched(watched), destination(destination), agp(agp){
}

void NogoodGrounder::resetWatched(SimpleNogoodContainerPtr watched){
	this->watched = watched;
}

ImmediateNogoodGrounder::ImmediateNogoodGrounder(RegistryPtr reg, SimpleNogoodContainerPtr watched, SimpleNogoodContainerPtr destination, AnnotatedGroundProgram& agp) :
	NogoodGrounder(reg, watched, destination, agp), instantiatedNongroundNogoodsIndex(0){
}

void ImmediateNogoodGrounder::update(InterpretationConstPtr partialInterpretation, InterpretationConstPtr factWasSet, InterpretationConstPtr changed){

	// go through all nonground nogoods which have not been instantiated so far
	int max = watched->getNogoodCount();
	if (instantiatedNongroundNogoodsIndex >= max) instantiatedNongroundNogoodsIndex = 0;
	DBGLOG(DBG, "Updating nogood grounder from " << instantiatedNongroundNogoodsIndex << " to " << max);
	for (int i = instantiatedNongroundNogoodsIndex; i < max; ++i){
		Nogood ng = watched->getNogood(i);
		DBGLOG(DBG, "Checking nogood " << ng.getStringRepresentation(reg));
		if (ng.isGround()) continue;

		DBGLOG(DBG, "Searching for watched literal in nogood " << i);
		int maxBoundVariables = 0;
		ID watchedLit = ID_FAIL;
		BOOST_FOREACH (ID lit, ng){
			if (lit.isOrdinaryGroundAtom()) continue;

			const OrdinaryAtom& atom = reg->onatoms.getByID(lit);

			std::set<ID> distinctVar;
			int var = 0;
			BOOST_FOREACH (ID p, atom.tuple){
				if (p.isVariableTerm()){
					if (std::find(distinctVar.begin(), distinctVar.end(), p) == distinctVar.end()){
						distinctVar.insert(p);
						var++;
					}
				}
			}

			if (var > maxBoundVariables){
				maxBoundVariables = var;
				watchedLit = lit;
			}
		}
		assert (watchedLit != ID_FAIL);

		// watch the atom and the corresponding nogood
		DBGLOG(DBG, "Watching literal " << watchedLit << " in nogood " << i);
		const OrdinaryAtom& watchedAtom = reg->onatoms.getByAddress(watchedLit.address);

		// For each atom A of the program, check if the watched literal unifies with A
		bm::bvector<>::enumerator en = agp.getProgramMask()->getStorage().first();
		bm::bvector<>::enumerator en_end = agp.getProgramMask()->getStorage().end();

		DBGLOG(DBG, "Searching for unifying program atoms");
		while (en < en_end){

			DBGLOG(DBG, "Checking atom " << *en);

			const OrdinaryAtom& currentAtom = reg->ogatoms.getByAddress(*en);
			if (currentAtom.unifiesWith(watchedAtom, reg)){
				Nogood instantiatedNG;
				ng.match(reg, reg->ogatoms.getIDByAddress(*en), instantiatedNG);
				DBGLOG(DBG, "Instantiated " << instantiatedNG.getStringRepresentation(reg) << " from " << ng.getStringRepresentation(reg));

				// check if the instance of the nogood contains a ground literal which does not appear in the program
				bool relevant = true;
				Nogood simplifiedNG;
				BOOST_FOREACH (ID lit, instantiatedNG){
					if (lit.isOrdinaryGroundAtom() && !reg->ogatoms.getIDByAddress(lit.address).isAuxiliary() && !agp.getProgramMask()->getFact(lit.address)){
						if (!lit.isNaf()){
							// can never be true --> remove whole instance
							relevant = false;
							break;
						}else{
							// is always true --> remove literal
						}
					}else{
						// might be true --> keep literal
						simplifiedNG.insert(lit);
					}
				}

				if (relevant){
					if (simplifiedNG.isGround()){
						destination->addNogood(simplifiedNG);
					}else{
						watched->addNogood(simplifiedNG);
					}
				}
			}

			en++;
		}

	}
	DBGLOG(DBG, "Finished updating");
	instantiatedNongroundNogoodsIndex = max;
}

void ImmediateNogoodGrounder::resetWatched(SimpleNogoodContainerPtr watched){
	NogoodGrounder::resetWatched(watched);
	instantiatedNongroundNogoodsIndex = 0;
}

LazyNogoodGrounder::LazyNogoodGrounder(RegistryPtr reg, SimpleNogoodContainerPtr watched, SimpleNogoodContainerPtr destination, AnnotatedGroundProgram& agp) :
	NogoodGrounder(reg, watched, destination, agp), watchedNogoodsCount(0){
}

void LazyNogoodGrounder::update(InterpretationConstPtr partialInterpretation, InterpretationConstPtr factWasSet, InterpretationConstPtr changed){

	if (!factWasSet) return;

	// Watch for all new nonground nogoods the literal which binds the highest number of variables
	DBGLOG(DBG, "Updating watches of nonground nogoods");
	int max = watched->getNogoodCount();
	if (watchedNogoodsCount >= max) watchedNogoodsCount = 0;
	DBGLOG(DBG, "Updating nogood grounder from " << watchedNogoodsCount << " to " << max);
	for (int i = watchedNogoodsCount; i < max; ++i){
		Nogood ng = watched->getNogood(i);
		DBGLOG(DBG, "Checking nogood " << ng.getStringRepresentation(reg));
		if (ng.isGround()) continue;

		DBGLOG(DBG, "Searching for watched literal in nogood " << i);
		int maxBoundVariables = 0;
		ID watchedLit = ID_FAIL;
		BOOST_FOREACH (ID lit, ng){
			if (lit.isOrdinaryGroundAtom()) continue;

			const OrdinaryAtom& atom = reg->onatoms.getByID(lit);

			std::set<ID> distinctVar;
			int var = 0;
			BOOST_FOREACH (ID p, atom.tuple){
				if (p.isVariableTerm()){
					if (std::find(distinctVar.begin(), distinctVar.end(), p) == distinctVar.end()){
						distinctVar.insert(p);
						var++;
					}
				}
			}

			if (var > maxBoundVariables){
				maxBoundVariables = var;
				watchedLit = lit;
			}
		}
		assert (watchedLit != ID_FAIL);

		// watch the atom and the corresponding nogood
		DBGLOG(DBG, "Watching literal " << watchedLit << " in nogood " << i);
		watchedLiterals.push_back(std::pair<ID, int>(watchedLit, i));
	}
	watchedNogoodsCount = watched->getNogoodCount();

	// For each atom A with changed truth value: go through all watches and check if
	// 1. the watched literal unifies with A
	// 2. the corresponding clause has not been instantiated for A yet
	bm::bvector<>::enumerator en = changed->getStorage().first();
	bm::bvector<>::enumerator en_end = changed->getStorage().end();

	DBGLOG(DBG, "Instantiating nonground nogoods");
	while (en < en_end){

		DBGLOG(DBG, "Instantiating for atom " << *en);
		typedef std::pair<ID, int> Pair;
		BOOST_FOREACH (Pair p, watchedLiterals){
			DBGLOG(DBG, "Matching nonground nogood " << p.second);

			// 2.
			if (std::find(alreadyCompared.begin(), alreadyCompared.end(), std::pair<IDAddress, int>(*en, p.second)) != alreadyCompared.end()) continue;

			const OrdinaryAtom& currentAtom = reg->ogatoms.getByAddress(*en);
			const OrdinaryAtom& watchedAtom = reg->onatoms.getByAddress(p.first.address);
			// 1.
			if (currentAtom.unifiesWith(watchedAtom, reg)){
				Nogood instantiatedNG;
				watched->getNogood(p.second).match(reg, reg->ogatoms.getIDByAddress(*en), instantiatedNG);
				DBGLOG(DBG, "Instantiated " << instantiatedNG.getStringRepresentation(reg) << " from " << watched->getNogood(p.second).getStringRepresentation(reg));

				if (instantiatedNG.isGround()){
					destination->addNogood(instantiatedNG);
				}else{
					watched->addNogood(instantiatedNG);
				}
			}

			alreadyCompared.insert(std::pair<IDAddress, int>(*en, p.second));
		}
		en++;
	}
}

void LazyNogoodGrounder::resetWatched(SimpleNogoodContainerPtr watched){
	NogoodGrounder::resetWatched(watched);
}

DLVHEX_NAMESPACE_END

<commit_msg>add debug output to nogood grounder<commit_after>/* dlvhex -- Answer-Set Programming with external interfaces.
 * Copyright (C) 2005, 2006, 2007 Roman Schindlauer
 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Thomas Krennwallner
 * Copyright (C) 2009, 2010 Peter Schüller
 * Copyright (C) 2011, 2012, 2013 Christoph Redl
 *
 * This file is part of dlvhex.
 *
 * dlvhex 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.
 *
 * dlvhex 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 dlvhex; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA.
 */

/**
 * @file NogoodGrounder.cpp
 * @author Christoph Redl
 *
 * @brief Implements a grounder for nonground nogoods.
 */

#define DLVHEX_BENCHMARK

#include "dlvhex2/NogoodGrounder.h"
#include "dlvhex2/Logger.h"
#include "dlvhex2/Registry.h"
#include "dlvhex2/Printer.h"
#include "dlvhex2/Benchmarking.h"
#include "dlvhex2/Nogood.h"

#include <bm/bmalgo.h>

#include <boost/foreach.hpp>

DLVHEX_NAMESPACE_BEGIN

NogoodGrounder::NogoodGrounder(RegistryPtr reg, SimpleNogoodContainerPtr watched, SimpleNogoodContainerPtr destination, AnnotatedGroundProgram& agp) :
	reg(reg), watched(watched), destination(destination), agp(agp){
}

void NogoodGrounder::resetWatched(SimpleNogoodContainerPtr watched){
	this->watched = watched;
}

ImmediateNogoodGrounder::ImmediateNogoodGrounder(RegistryPtr reg, SimpleNogoodContainerPtr watched, SimpleNogoodContainerPtr destination, AnnotatedGroundProgram& agp) :
	NogoodGrounder(reg, watched, destination, agp), instantiatedNongroundNogoodsIndex(0){
}

void ImmediateNogoodGrounder::update(InterpretationConstPtr partialInterpretation, InterpretationConstPtr factWasSet, InterpretationConstPtr changed){

	// go through all nonground nogoods which have not been instantiated so far
	int max = watched->getNogoodCount();
	if (instantiatedNongroundNogoodsIndex >= max) instantiatedNongroundNogoodsIndex = 0;
	DBGLOG(DBG, "Updating nogood grounder from " << instantiatedNongroundNogoodsIndex << " to " << max);
	for (int i = instantiatedNongroundNogoodsIndex; i < max; ++i){
		Nogood ng = watched->getNogood(i);
		DBGLOG(DBG, "Checking nogood " << ng.getStringRepresentation(reg));
		if (ng.isGround()) continue;

		DBGLOG(DBG, "Searching for watched literal in nogood " << i);
		int maxBoundVariables = 0;
		ID watchedLit = ID_FAIL;
		BOOST_FOREACH (ID lit, ng){
			if (lit.isOrdinaryGroundAtom()) continue;

			const OrdinaryAtom& atom = reg->onatoms.getByID(lit);

			std::set<ID> distinctVar;
			int var = 0;
			BOOST_FOREACH (ID p, atom.tuple){
				if (p.isVariableTerm()){
					if (std::find(distinctVar.begin(), distinctVar.end(), p) == distinctVar.end()){
						distinctVar.insert(p);
						var++;
					}
				}
			}

			if (var > maxBoundVariables){
				maxBoundVariables = var;
				watchedLit = lit;
			}
		}
		assert (watchedLit != ID_FAIL);

		// watch the atom and the corresponding nogood
		DBGLOG(DBG, "Watching literal " << watchedLit << " in nogood " << i);
		const OrdinaryAtom& watchedAtom = reg->onatoms.getByAddress(watchedLit.address);

		// For each atom A of the program, check if the watched literal unifies with A
		bm::bvector<>::enumerator en = agp.getProgramMask()->getStorage().first();
		bm::bvector<>::enumerator en_end = agp.getProgramMask()->getStorage().end();

		DBGLOG(DBG, "Searching for unifying program atoms");
		while (en < en_end){

			DBGLOG(DBG, "Checking atom " << *en);

			const OrdinaryAtom& currentAtom = reg->ogatoms.getByAddress(*en);
			if (currentAtom.unifiesWith(watchedAtom, reg)){
				Nogood instantiatedNG;
				ng.match(reg, reg->ogatoms.getIDByAddress(*en), instantiatedNG);
				DBGLOG(DBG, "Instantiated " << instantiatedNG.getStringRepresentation(reg) << " from " << ng.getStringRepresentation(reg));

				// check if the instance of the nogood contains a ground literal which does not appear in the program
				bool relevant = true;
				Nogood simplifiedNG;
				BOOST_FOREACH (ID lit, instantiatedNG){
					if (lit.isOrdinaryGroundAtom() && !reg->ogatoms.getIDByAddress(lit.address).isAuxiliary() && !agp.getProgramMask()->getFact(lit.address)){
						if (!lit.isNaf()){
							// can never be true --> remove whole instance
#ifndef NDEBUG
							std::string str = RawPrinter::toString(reg, lit);
							DBGLOG(DBG, "Removing because negative " << str << " can never be true");
#endif
							relevant = false;
							break;
						}else{
							// is always true --> remove literal
						}
					}else{
						// might be true --> keep literal
						simplifiedNG.insert(lit);
					}
				}

				if (relevant){
					if (simplifiedNG.isGround()){
						DBGLOG(DBG, "Keeping ground nogood " << simplifiedNG.getStringRepresentation(reg));
						destination->addNogood(simplifiedNG);
					}else{
						DBGLOG(DBG, "Keeping nonground nogood " << simplifiedNG.getStringRepresentation(reg));
						watched->addNogood(simplifiedNG);
					}
				}else{
						DBGLOG(DBG, "Removing nogood " << simplifiedNG.getStringRepresentation(reg));
				}
			}

			en++;
		}

	}
	DBGLOG(DBG, "Finished updating");
	instantiatedNongroundNogoodsIndex = max;
}

void ImmediateNogoodGrounder::resetWatched(SimpleNogoodContainerPtr watched){
	NogoodGrounder::resetWatched(watched);
	instantiatedNongroundNogoodsIndex = 0;
}

LazyNogoodGrounder::LazyNogoodGrounder(RegistryPtr reg, SimpleNogoodContainerPtr watched, SimpleNogoodContainerPtr destination, AnnotatedGroundProgram& agp) :
	NogoodGrounder(reg, watched, destination, agp), watchedNogoodsCount(0){
}

void LazyNogoodGrounder::update(InterpretationConstPtr partialInterpretation, InterpretationConstPtr factWasSet, InterpretationConstPtr changed){

	if (!factWasSet) return;

	// Watch for all new nonground nogoods the literal which binds the highest number of variables
	DBGLOG(DBG, "Updating watches of nonground nogoods");
	int max = watched->getNogoodCount();
	if (watchedNogoodsCount >= max) watchedNogoodsCount = 0;
	DBGLOG(DBG, "Updating nogood grounder from " << watchedNogoodsCount << " to " << max);
	for (int i = watchedNogoodsCount; i < max; ++i){
		Nogood ng = watched->getNogood(i);
		DBGLOG(DBG, "Checking nogood " << ng.getStringRepresentation(reg));
		if (ng.isGround()) continue;

		DBGLOG(DBG, "Searching for watched literal in nogood " << i);
		int maxBoundVariables = 0;
		ID watchedLit = ID_FAIL;
		BOOST_FOREACH (ID lit, ng){
			if (lit.isOrdinaryGroundAtom()) continue;

			const OrdinaryAtom& atom = reg->onatoms.getByID(lit);

			std::set<ID> distinctVar;
			int var = 0;
			BOOST_FOREACH (ID p, atom.tuple){
				if (p.isVariableTerm()){
					if (std::find(distinctVar.begin(), distinctVar.end(), p) == distinctVar.end()){
						distinctVar.insert(p);
						var++;
					}
				}
			}

			if (var > maxBoundVariables){
				maxBoundVariables = var;
				watchedLit = lit;
			}
		}
		assert (watchedLit != ID_FAIL);

		// watch the atom and the corresponding nogood
		DBGLOG(DBG, "Watching literal " << watchedLit << " in nogood " << i);
		watchedLiterals.push_back(std::pair<ID, int>(watchedLit, i));
	}
	watchedNogoodsCount = watched->getNogoodCount();

	// For each atom A with changed truth value: go through all watches and check if
	// 1. the watched literal unifies with A
	// 2. the corresponding clause has not been instantiated for A yet
	bm::bvector<>::enumerator en = changed->getStorage().first();
	bm::bvector<>::enumerator en_end = changed->getStorage().end();

	DBGLOG(DBG, "Instantiating nonground nogoods");
	while (en < en_end){

		DBGLOG(DBG, "Instantiating for atom " << *en);
		typedef std::pair<ID, int> Pair;
		BOOST_FOREACH (Pair p, watchedLiterals){
			DBGLOG(DBG, "Matching nonground nogood " << p.second);

			// 2.
			if (std::find(alreadyCompared.begin(), alreadyCompared.end(), std::pair<IDAddress, int>(*en, p.second)) != alreadyCompared.end()) continue;

			const OrdinaryAtom& currentAtom = reg->ogatoms.getByAddress(*en);
			const OrdinaryAtom& watchedAtom = reg->onatoms.getByAddress(p.first.address);
			// 1.
			if (currentAtom.unifiesWith(watchedAtom, reg)){
				Nogood instantiatedNG;
				watched->getNogood(p.second).match(reg, reg->ogatoms.getIDByAddress(*en), instantiatedNG);
				DBGLOG(DBG, "Instantiated " << instantiatedNG.getStringRepresentation(reg) << " from " << watched->getNogood(p.second).getStringRepresentation(reg));

				if (instantiatedNG.isGround()){
					destination->addNogood(instantiatedNG);
				}else{
					watched->addNogood(instantiatedNG);
				}
			}

			alreadyCompared.insert(std::pair<IDAddress, int>(*en, p.second));
		}
		en++;
	}
}

void LazyNogoodGrounder::resetWatched(SimpleNogoodContainerPtr watched){
	NogoodGrounder::resetWatched(watched);
}

DLVHEX_NAMESPACE_END

<|endoftext|>


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

#pragma hdrstop

#ifndef _HINTIDS_HXX
#include <hintids.hxx>
#endif
#ifndef _HELPID_H
#include <helpid.h>
#endif
#define _SVSTDARR_STRINGSSORT
#include <svtools/svstdarr.hxx>

#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_SEARCHOPTIONS_HPP_
#include <com/sun/star/util/SearchOptions.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_SEARCHFLAGS_HPP_
#include <com/sun/star/util/SearchFlags.hpp>
#endif
#ifndef _COM_SUN_STAR_I18N_TRANSLITERATIONMODULES_HPP_
#include <com/sun/star/i18n/TransliterationModules.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_LOCALE_HPP_
#include <com/sun/star/lang/Locale.hpp>
#endif

#ifndef _SFXSTRITEM_HXX //autogen
#include <svtools/stritem.hxx>
#endif
#ifndef _MSGBOX_HXX //autogen
#include <vcl/msgbox.hxx>
#endif
#ifndef _SFXDISPATCH_HXX //autogen
#include <sfx2/dispatch.hxx>
#endif
#ifndef _SFXENUMITEM_HXX //autogen
#include <svtools/eitem.hxx>
#endif
#ifndef _TXTCMP_HXX //autogen
#include <svtools/txtcmp.hxx>
#endif
#ifndef _SFXVIEWFRM_HXX
#include <sfx2/viewfrm.hxx>
#endif
#ifndef _SVX_SCRIPTTYPEITEM_HXX
#include <svx/scripttypeitem.hxx>
#endif
#ifndef _SFXITEMSET_HXX
#include <svtools/itemset.hxx>
#endif
#ifndef _SVX_LANGITEM_HXX
#include <svx/langitem.hxx>
#endif

#ifndef _SWTYPES_HXX
#include <swtypes.hxx>
#endif
#ifndef _IDXMRK_HXX
#include <idxmrk.hxx>
#endif
#ifndef _TXTTXMRK_HXX
#include <txttxmrk.hxx>
#endif
#ifndef _WRTSH_HXX
#include <wrtsh.hxx>
#endif
#ifndef _VIEW_HXX
#include <view.hxx>
#endif
#ifndef _TOXMGR_HXX
#include <toxmgr.hxx>
#endif
#ifndef _MULTMRK_HXX
#include <multmrk.hxx>
#endif
#ifndef _SWUNDO_HXX
#include <swundo.hxx>                   // fuer Undo-Ids
#endif

#ifndef _CMDID_H
#include <cmdid.h>
#endif
#ifndef _INDEX_HRC
#include <index.hrc>
#endif
#ifndef _IDXMRK_HRC
#include <idxmrk.hrc>
#endif
#ifndef _SWMODULE_HXX
#include <swmodule.hxx>
#endif
#ifndef _FLDMGR_HXX
#include <fldmgr.hxx>
#endif
#ifndef _FLDBAS_HXX
#include <fldbas.hxx>
#endif
#include <utlui.hrc>
#ifndef _SWCONT_HXX
#include <swcont.hxx>
#endif
#ifndef _AUTHFLD_HXX
#include <authfld.hxx>
#endif
#ifndef _SVTOOLS_CJKOPTIONS_HXX
#include <svtools/cjkoptions.hxx>
#endif
#ifndef _NDTXT_HXX
#include <ndtxt.hxx>
#endif
#ifndef _BREAKIT_HXX
#include <breakit.hxx>
#endif

/* -----------------07.09.99 08:15-------------------

 --------------------------------------------------*/
SFX_IMPL_CHILDWINDOW(SwInsertIdxMarkWrapper, FN_INSERT_IDX_ENTRY_DLG)

SwInsertIdxMarkWrapper::SwInsertIdxMarkWrapper( Window *pParentWindow,
                            sal_uInt16 nId,
                            SfxBindings* pBindings,
                            SfxChildWinInfo* pInfo ) :
        SfxChildWindow(pParentWindow, nId)
{

    //CHINA001 pWindow = new SwIndexMarkFloatDlg(pBindings, this, pParentWindow, pInfo );
    SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();//CHINA001
    DBG_ASSERT(pFact, "SwAbstractDialogFactory fail!");//CHINA001
    pAbstDlg = pFact->CreateIndexMarkFloatDlg( ResId( DLG_INSIDXMARK ), pBindings, this, pParentWindow, pInfo );
    DBG_ASSERT(pAbstDlg, "Dialogdiet fail!");//CHINA001
    pWindow = pAbstDlg->GetWindow(); //CHINA001
    pWindow->Show();    // at this point,because before pSh has to be initialized in ReInitDlg()
                        // -> Show() will invoke StateChanged() and save pos
    eChildAlignment = SFX_ALIGN_NOALIGNMENT;
}
/* -----------------07.09.99 09:14-------------------

 --------------------------------------------------*/
SfxChildWinInfo SwInsertIdxMarkWrapper::GetInfo() const
{
    SfxChildWinInfo aInfo = SfxChildWindow::GetInfo();

    return aInfo;
}

void    SwInsertIdxMarkWrapper::ReInitDlg(SwWrtShell& rWrtShell)
{
    pAbstDlg->ReInitDlg(rWrtShell); //CHINA001 ((SwIndexMarkFloatDlg*)pWindow)->ReInitDlg(rWrtShell);
}

/* -----------------07.09.99 08:15-------------------

 --------------------------------------------------*/
SFX_IMPL_CHILDWINDOW(SwInsertAuthMarkWrapper, FN_INSERT_AUTH_ENTRY_DLG)

SwInsertAuthMarkWrapper::SwInsertAuthMarkWrapper(   Window *pParentWindow,
                            sal_uInt16 nId,
                            SfxBindings* pBindings,
                            SfxChildWinInfo* pInfo ) :
        SfxChildWindow(pParentWindow, nId)
{

    //CHINA001 pWindow = new SwAuthMarkFloatDlg(pBindings, this, pParentWindow, pInfo );
    SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();//CHINA001
    DBG_ASSERT(pFact, "SwAbstractDialogFactory fail!");//CHINA001
    pAbstDlg = pFact->CreateAuthMarkFloatDlg( ResId( DLG_INSAUTHMARK ), pBindings, this, pParentWindow, pInfo );
    DBG_ASSERT(pAbstDlg, "Dialogdiet fail!");//CHINA001
    pWindow = pAbstDlg->GetWindow(); //CHINA001

    eChildAlignment = SFX_ALIGN_NOALIGNMENT;
}
/* -----------------07.09.99 09:14-------------------

 --------------------------------------------------*/
SfxChildWinInfo SwInsertAuthMarkWrapper::GetInfo() const
{
    SfxChildWinInfo aInfo = SfxChildWindow::GetInfo();
    return aInfo;
}
/* -----------------19.10.99 11:16-------------------

 --------------------------------------------------*/
void    SwInsertAuthMarkWrapper::ReInitDlg(SwWrtShell& rWrtShell)
{
    pAbstDlg->ReInitDlg(rWrtShell);//CHINA001 ((SwAuthMarkFloatDlg*)pWindow)->ReInitDlg(rWrtShell);
}

<commit_msg>INTEGRATION: CWS ooo19126 (1.31.726); FILE MERGED 2005/09/05 13:46:22 rt 1.31.726.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: idxmrk.cxx,v $
 *
 *  $Revision: 1.32 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 10:21:51 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#pragma hdrstop

#ifndef _HINTIDS_HXX
#include <hintids.hxx>
#endif
#ifndef _HELPID_H
#include <helpid.h>
#endif
#define _SVSTDARR_STRINGSSORT
#include <svtools/svstdarr.hxx>

#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_SEARCHOPTIONS_HPP_
#include <com/sun/star/util/SearchOptions.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_SEARCHFLAGS_HPP_
#include <com/sun/star/util/SearchFlags.hpp>
#endif
#ifndef _COM_SUN_STAR_I18N_TRANSLITERATIONMODULES_HPP_
#include <com/sun/star/i18n/TransliterationModules.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_LOCALE_HPP_
#include <com/sun/star/lang/Locale.hpp>
#endif

#ifndef _SFXSTRITEM_HXX //autogen
#include <svtools/stritem.hxx>
#endif
#ifndef _MSGBOX_HXX //autogen
#include <vcl/msgbox.hxx>
#endif
#ifndef _SFXDISPATCH_HXX //autogen
#include <sfx2/dispatch.hxx>
#endif
#ifndef _SFXENUMITEM_HXX //autogen
#include <svtools/eitem.hxx>
#endif
#ifndef _TXTCMP_HXX //autogen
#include <svtools/txtcmp.hxx>
#endif
#ifndef _SFXVIEWFRM_HXX
#include <sfx2/viewfrm.hxx>
#endif
#ifndef _SVX_SCRIPTTYPEITEM_HXX
#include <svx/scripttypeitem.hxx>
#endif
#ifndef _SFXITEMSET_HXX
#include <svtools/itemset.hxx>
#endif
#ifndef _SVX_LANGITEM_HXX
#include <svx/langitem.hxx>
#endif

#ifndef _SWTYPES_HXX
#include <swtypes.hxx>
#endif
#ifndef _IDXMRK_HXX
#include <idxmrk.hxx>
#endif
#ifndef _TXTTXMRK_HXX
#include <txttxmrk.hxx>
#endif
#ifndef _WRTSH_HXX
#include <wrtsh.hxx>
#endif
#ifndef _VIEW_HXX
#include <view.hxx>
#endif
#ifndef _TOXMGR_HXX
#include <toxmgr.hxx>
#endif
#ifndef _MULTMRK_HXX
#include <multmrk.hxx>
#endif
#ifndef _SWUNDO_HXX
#include <swundo.hxx>                   // fuer Undo-Ids
#endif

#ifndef _CMDID_H
#include <cmdid.h>
#endif
#ifndef _INDEX_HRC
#include <index.hrc>
#endif
#ifndef _IDXMRK_HRC
#include <idxmrk.hrc>
#endif
#ifndef _SWMODULE_HXX
#include <swmodule.hxx>
#endif
#ifndef _FLDMGR_HXX
#include <fldmgr.hxx>
#endif
#ifndef _FLDBAS_HXX
#include <fldbas.hxx>
#endif
#include <utlui.hrc>
#ifndef _SWCONT_HXX
#include <swcont.hxx>
#endif
#ifndef _AUTHFLD_HXX
#include <authfld.hxx>
#endif
#ifndef _SVTOOLS_CJKOPTIONS_HXX
#include <svtools/cjkoptions.hxx>
#endif
#ifndef _NDTXT_HXX
#include <ndtxt.hxx>
#endif
#ifndef _BREAKIT_HXX
#include <breakit.hxx>
#endif

/* -----------------07.09.99 08:15-------------------

 --------------------------------------------------*/
SFX_IMPL_CHILDWINDOW(SwInsertIdxMarkWrapper, FN_INSERT_IDX_ENTRY_DLG)

SwInsertIdxMarkWrapper::SwInsertIdxMarkWrapper( Window *pParentWindow,
                            sal_uInt16 nId,
                            SfxBindings* pBindings,
                            SfxChildWinInfo* pInfo ) :
        SfxChildWindow(pParentWindow, nId)
{

    //CHINA001 pWindow = new SwIndexMarkFloatDlg(pBindings, this, pParentWindow, pInfo );
    SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();//CHINA001
    DBG_ASSERT(pFact, "SwAbstractDialogFactory fail!");//CHINA001
    pAbstDlg = pFact->CreateIndexMarkFloatDlg( ResId( DLG_INSIDXMARK ), pBindings, this, pParentWindow, pInfo );
    DBG_ASSERT(pAbstDlg, "Dialogdiet fail!");//CHINA001
    pWindow = pAbstDlg->GetWindow(); //CHINA001
    pWindow->Show();    // at this point,because before pSh has to be initialized in ReInitDlg()
                        // -> Show() will invoke StateChanged() and save pos
    eChildAlignment = SFX_ALIGN_NOALIGNMENT;
}
/* -----------------07.09.99 09:14-------------------

 --------------------------------------------------*/
SfxChildWinInfo SwInsertIdxMarkWrapper::GetInfo() const
{
    SfxChildWinInfo aInfo = SfxChildWindow::GetInfo();

    return aInfo;
}

void    SwInsertIdxMarkWrapper::ReInitDlg(SwWrtShell& rWrtShell)
{
    pAbstDlg->ReInitDlg(rWrtShell); //CHINA001 ((SwIndexMarkFloatDlg*)pWindow)->ReInitDlg(rWrtShell);
}

/* -----------------07.09.99 08:15-------------------

 --------------------------------------------------*/
SFX_IMPL_CHILDWINDOW(SwInsertAuthMarkWrapper, FN_INSERT_AUTH_ENTRY_DLG)

SwInsertAuthMarkWrapper::SwInsertAuthMarkWrapper(   Window *pParentWindow,
                            sal_uInt16 nId,
                            SfxBindings* pBindings,
                            SfxChildWinInfo* pInfo ) :
        SfxChildWindow(pParentWindow, nId)
{

    //CHINA001 pWindow = new SwAuthMarkFloatDlg(pBindings, this, pParentWindow, pInfo );
    SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();//CHINA001
    DBG_ASSERT(pFact, "SwAbstractDialogFactory fail!");//CHINA001
    pAbstDlg = pFact->CreateAuthMarkFloatDlg( ResId( DLG_INSAUTHMARK ), pBindings, this, pParentWindow, pInfo );
    DBG_ASSERT(pAbstDlg, "Dialogdiet fail!");//CHINA001
    pWindow = pAbstDlg->GetWindow(); //CHINA001

    eChildAlignment = SFX_ALIGN_NOALIGNMENT;
}
/* -----------------07.09.99 09:14-------------------

 --------------------------------------------------*/
SfxChildWinInfo SwInsertAuthMarkWrapper::GetInfo() const
{
    SfxChildWinInfo aInfo = SfxChildWindow::GetInfo();
    return aInfo;
}
/* -----------------19.10.99 11:16-------------------

 --------------------------------------------------*/
void    SwInsertAuthMarkWrapper::ReInitDlg(SwWrtShell& rWrtShell)
{
    pAbstDlg->ReInitDlg(rWrtShell);//CHINA001 ((SwAuthMarkFloatDlg*)pWindow)->ReInitDlg(rWrtShell);
}

<|endoftext|>