<commit_before>#include <assert.h>
#include <sys/socket.h>

#include "utils.h"
#include "client_base.h"

const int WRITE_QUEUE_SIZE = -1;

int BaseClient::total_clients = 0;

BaseClient::BaseClient(ev::loop_ref *loop, int sock_, DatabasePool *database_pool_, double active_timeout_, double idle_timeout_)
	: io_read(*loop),
	  io_write(*loop),
	  closed(false),
	  sock(sock_),
	  database_pool(database_pool_),
	  write_queue(WRITE_QUEUE_SIZE)
{
	sig.set<BaseClient, &BaseClient::signal_cb>(this);
	sig.start(SIGINT);

	io_read.set<BaseClient, &BaseClient::io_cb>(this);
	io_read.start(sock, ev::READ);

	io_write.set<BaseClient, &BaseClient::io_cb>(this);
	io_write.set(sock, ev::WRITE);
}

BaseClient::~BaseClient()
{
	destroy();
	sig.stop();
	LOG_OBJ(this, "DELETED!\n");
}

void BaseClient::signal_cb(ev::sig &signal, int revents)
{
	LOG_EV(this, "Signaled destroy!!\n");
	destroy();
	delete this;
}

void BaseClient::destroy()
{
	if (sock == -1) {
		return;
	}

	close();

	// Stop and free watcher if client socket is closing
	io_read.stop();
	io_write.stop();

	::close(sock);
	sock = -1;

	LOG_OBJ(this, "DESTROYED!\n");
}

void BaseClient::close() {
	if (closed) {
		return;
	}

	closed = true;
	LOG_OBJ(this, "CLOSED!\n");
}

void BaseClient::io_update() {
	if (sock != -1) {
		if (write_queue.empty()) {
			if (closed) {
				destroy();
			} else {
				io_write.stop();
			}
		} else {
			io_write.start();
		}
	}

	if (sock == -1) {
		delete this;
	}

}

void BaseClient::io_cb(ev::io &watcher, int revents)
{
	if (revents & EV_ERROR) {
		LOG_ERR(this, "ERROR: got invalid event (sock=%d): %s\n", sock, strerror(errno));
		destroy();
		return;
	}

	LOG_EV(this, "IO_CB (sock=%d) %x\n", sock, revents);

	if (sock == -1) {
		return;
	}

	assert(sock == watcher.fd);

	if (sock != -1 && revents & EV_WRITE) {
		write_cb();
	}

	if (sock != -1 && revents & EV_READ) {
		read_cb();
	}

	io_update();
}

void BaseClient::write_cb()
{
	if (!write_queue.empty()) {
		Buffer* buffer = write_queue.front();

		size_t buf_size = buffer->nbytes();
		const char * buf = buffer->dpos();

		LOG_CONN(this, "(sock=%d) <<-- '%s'\n", sock, repr(buf, buf_size).c_str());

		ssize_t written = ::write(sock, buf, buf_size);

		if (written < 0) {
			if (errno != EAGAIN) {
				LOG_ERR(this, "ERROR: write error (sock=%d): %s\n", sock, strerror(errno));
				destroy();
			}
		} else if (written == 0) {
			// nothing written?
		} else {
			buffer->pos += written;
			if (buffer->nbytes() == 0) {
				write_queue.pop(buffer);
				delete buffer;
			}
		}
	}
}

void BaseClient::read_cb()
{
	char buf[1024];

	ssize_t received = ::read(sock, buf, sizeof(buf));

	if (received < 0) {
		if (errno != EAGAIN) {
			LOG_ERR(this, "ERROR: read error (sock=%d): %s\n", sock, strerror(errno));
			destroy();
		}
	} else if (received == 0) {
		// The peer has closed its half side of the connection.
		LOG_CONN(this, "Received EOF (sock=%d)!\n", sock);
		destroy();
	} else {
		LOG_CONN(this, "(sock=%d) -->> '%s'\n", sock, repr(buf, received).c_str());
		on_read(buf, received);
	}
}

void BaseClient::write(const char *buf, size_t buf_size)
{
	LOG_CONN(this, "(sock=%d) <ENQUEUE> '%s'\n", sock, repr(buf, buf_size).c_str());

	Buffer *buffer = new Buffer('\0', buf, buf_size);
	write_queue.push(buffer);

	io_update();
}
<commit_msg>Log READ_CB or WRITE_CB<commit_after>#include <assert.h>
#include <sys/socket.h>

#include "utils.h"
#include "client_base.h"

const int WRITE_QUEUE_SIZE = -1;

int BaseClient::total_clients = 0;

BaseClient::BaseClient(ev::loop_ref *loop, int sock_, DatabasePool *database_pool_, double active_timeout_, double idle_timeout_)
	: io_read(*loop),
	  io_write(*loop),
	  closed(false),
	  sock(sock_),
	  database_pool(database_pool_),
	  write_queue(WRITE_QUEUE_SIZE)
{
	sig.set<BaseClient, &BaseClient::signal_cb>(this);
	sig.start(SIGINT);

	io_read.set<BaseClient, &BaseClient::io_cb>(this);
	io_read.start(sock, ev::READ);

	io_write.set<BaseClient, &BaseClient::io_cb>(this);
	io_write.set(sock, ev::WRITE);
}

BaseClient::~BaseClient()
{
	destroy();
	sig.stop();
	LOG_OBJ(this, "DELETED!\n");
}

void BaseClient::signal_cb(ev::sig &signal, int revents)
{
	LOG_EV(this, "Signaled destroy!!\n");
	destroy();
	delete this;
}

void BaseClient::destroy()
{
	if (sock == -1) {
		return;
	}

	close();

	// Stop and free watcher if client socket is closing
	io_read.stop();
	io_write.stop();

	::close(sock);
	sock = -1;

	LOG_OBJ(this, "DESTROYED!\n");
}

void BaseClient::close() {
	if (closed) {
		return;
	}

	closed = true;
	LOG_OBJ(this, "CLOSED!\n");
}

void BaseClient::io_update() {
	if (sock != -1) {
		if (write_queue.empty()) {
			if (closed) {
				destroy();
			} else {
				io_write.stop();
			}
		} else {
			io_write.start();
		}
	}

	if (sock == -1) {
		delete this;
	}

}

void BaseClient::io_cb(ev::io &watcher, int revents)
{
	if (revents & EV_ERROR) {
		LOG_ERR(this, "ERROR: got invalid event (sock=%d): %s\n", sock, strerror(errno));
		destroy();
		return;
	}

	LOG_EV(this, "%s (sock=%d) %x\n", (revents & EV_WRITE & EV_READ) ? "IO_CB" : (revents & EV_WRITE) ? "WRITE_CB" : (revents & EV_READ) ? "READ_CB" : "IO_CB", sock, revents);

	if (sock == -1) {
		return;
	}

	assert(sock == watcher.fd);

	if (sock != -1 && revents & EV_WRITE) {
		write_cb();
	}

	if (sock != -1 && revents & EV_READ) {
		read_cb();
	}

	io_update();
}

void BaseClient::write_cb()
{
	if (!write_queue.empty()) {
		Buffer* buffer = write_queue.front();

		size_t buf_size = buffer->nbytes();
		const char * buf = buffer->dpos();

		LOG_CONN(this, "(sock=%d) <<-- '%s'\n", sock, repr(buf, buf_size).c_str());

		ssize_t written = ::write(sock, buf, buf_size);

		if (written < 0) {
			if (errno != EAGAIN) {
				LOG_ERR(this, "ERROR: write error (sock=%d): %s\n", sock, strerror(errno));
				destroy();
			}
		} else if (written == 0) {
			// nothing written?
		} else {
			buffer->pos += written;
			if (buffer->nbytes() == 0) {
				write_queue.pop(buffer);
				delete buffer;
			}
		}
	}
}

void BaseClient::read_cb()
{
	char buf[1024];

	ssize_t received = ::read(sock, buf, sizeof(buf));

	if (received < 0) {
		if (errno != EAGAIN) {
			LOG_ERR(this, "ERROR: read error (sock=%d): %s\n", sock, strerror(errno));
			destroy();
		}
	} else if (received == 0) {
		// The peer has closed its half side of the connection.
		LOG_CONN(this, "Received EOF (sock=%d)!\n", sock);
		destroy();
	} else {
		LOG_CONN(this, "(sock=%d) -->> '%s'\n", sock, repr(buf, received).c_str());
		on_read(buf, received);
	}
}

void BaseClient::write(const char *buf, size_t buf_size)
{
	LOG_CONN(this, "(sock=%d) <ENQUEUE> '%s'\n", sock, repr(buf, buf_size).c_str());

	Buffer *buffer = new Buffer('\0', buf, buf_size);
	write_queue.push(buffer);

	io_update();
}
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "after_streaming_fixture.h"
#include "testsupport/fileutils.h"

class FileTest : public AfterStreamingFixture {
 protected:
  // Creates the string åäö.pcm.
  std::string CreateTrickyFilenameInUtf8() {
    char filename[16] = { 0xc3, 0xa5, 0xc3, 0xa4, 0xc3, 0xb6, 0 };
    return std::string(filename) + ".pcm";
  }
};

TEST_F(FileTest, ManualRecordToFileForThreeSecondsAndPlayback) {
  SwitchToManualMicrophone();

  std::string recording_filename =
      webrtc::test::OutputPath() + CreateTrickyFilenameInUtf8();

  TEST_LOG("Recording to %s for 3 seconds.\n", recording_filename.c_str());
  EXPECT_EQ(0, voe_file_->StartRecordingMicrophone(recording_filename.c_str()));
  Sleep(3000);
  EXPECT_EQ(0, voe_file_->StopRecordingMicrophone());

  TEST_LOG("Playing back %s.\n", recording_filename.c_str());
  EXPECT_EQ(0, voe_file_->StartPlayingFileLocally(
      channel_, recording_filename.c_str()));

  // Play the file to the user and ensure the is-playing-locally
  // and scaling methods also work. The clip is 3 seconds long.
  Sleep(250);
  EXPECT_EQ(1, voe_file_->IsPlayingFileLocally(channel_));
  Sleep(1500);
  TEST_LOG("Decreasing level by 50%%.\n");
  EXPECT_EQ(0, voe_file_->ScaleLocalFilePlayout(channel_, 0.5f));
  Sleep(1500);
  EXPECT_EQ(0, voe_file_->IsPlayingFileLocally(channel_));
}

TEST_F(FileTest, ManualRecordPlayoutToWavFileForThreeSecondsAndPlayback) {
  webrtc::CodecInst send_codec;
  voe_codec_->GetSendCodec(channel_, send_codec);

  std::string recording_filename =
      webrtc::test::OutputPath() + "playout.wav";

  TEST_LOG("Recording playout to %s.\n", recording_filename.c_str());
  EXPECT_EQ(0, voe_file_->StartRecordingPlayout(
      channel_, recording_filename.c_str(), &send_codec));
  Sleep(3000);
  EXPECT_EQ(0, voe_file_->StopRecordingPlayout(channel_));

  TEST_LOG("Playing back the recording in looping mode.\n");
  EXPECT_EQ(0, voe_file_->StartPlayingFileAsMicrophone(
      channel_, recording_filename.c_str(), true, false,
      webrtc::kFileFormatWavFile));

  Sleep(2000);
  EXPECT_EQ(1, voe_file_->IsPlayingFileAsMicrophone(channel_));
  Sleep(2000);
  // We should still be playing since we're looping.
  EXPECT_EQ(1, voe_file_->IsPlayingFileAsMicrophone(channel_));

  // Try scaling as well.
  TEST_LOG("Decreasing level by 50%%.\n");
  EXPECT_EQ(0, voe_file_->ScaleFileAsMicrophonePlayout(channel_, 0.5f));
  Sleep(1000);

  EXPECT_EQ(0, voe_file_->StopPlayingFileAsMicrophone(channel_));
}
<commit_msg>Fixed compilation error on Windows.<commit_after>/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "after_streaming_fixture.h"
#include "testsupport/fileutils.h"

class FileTest : public AfterStreamingFixture {
 protected:
  // Creates the string åäö.pcm.
  std::string CreateTrickyFilenameInUtf8() {
    char filename[16] = { static_cast<char>(0xc3), static_cast<char>(0xa5),
                          static_cast<char>(0xc3), static_cast<char>(0xa4),
                          static_cast<char>(0xc3), static_cast<char>(0xb6),
                          static_cast<char>(0) };
    return std::string(filename) + ".pcm";
  }
};

TEST_F(FileTest, ManualRecordToFileForThreeSecondsAndPlayback) {
  SwitchToManualMicrophone();

  std::string recording_filename =
      webrtc::test::OutputPath() + CreateTrickyFilenameInUtf8();

  TEST_LOG("Recording to %s for 3 seconds.\n", recording_filename.c_str());
  EXPECT_EQ(0, voe_file_->StartRecordingMicrophone(recording_filename.c_str()));
  Sleep(3000);
  EXPECT_EQ(0, voe_file_->StopRecordingMicrophone());

  TEST_LOG("Playing back %s.\n", recording_filename.c_str());
  EXPECT_EQ(0, voe_file_->StartPlayingFileLocally(
      channel_, recording_filename.c_str()));

  // Play the file to the user and ensure the is-playing-locally
  // and scaling methods also work. The clip is 3 seconds long.
  Sleep(250);
  EXPECT_EQ(1, voe_file_->IsPlayingFileLocally(channel_));
  Sleep(1500);
  TEST_LOG("Decreasing level by 50%%.\n");
  EXPECT_EQ(0, voe_file_->ScaleLocalFilePlayout(channel_, 0.5f));
  Sleep(1500);
  EXPECT_EQ(0, voe_file_->IsPlayingFileLocally(channel_));
}

TEST_F(FileTest, ManualRecordPlayoutToWavFileForThreeSecondsAndPlayback) {
  webrtc::CodecInst send_codec;
  voe_codec_->GetSendCodec(channel_, send_codec);

  std::string recording_filename =
      webrtc::test::OutputPath() + "playout.wav";

  TEST_LOG("Recording playout to %s.\n", recording_filename.c_str());
  EXPECT_EQ(0, voe_file_->StartRecordingPlayout(
      channel_, recording_filename.c_str(), &send_codec));
  Sleep(3000);
  EXPECT_EQ(0, voe_file_->StopRecordingPlayout(channel_));

  TEST_LOG("Playing back the recording in looping mode.\n");
  EXPECT_EQ(0, voe_file_->StartPlayingFileAsMicrophone(
      channel_, recording_filename.c_str(), true, false,
      webrtc::kFileFormatWavFile));

  Sleep(2000);
  EXPECT_EQ(1, voe_file_->IsPlayingFileAsMicrophone(channel_));
  Sleep(2000);
  // We should still be playing since we're looping.
  EXPECT_EQ(1, voe_file_->IsPlayingFileAsMicrophone(channel_));

  // Try scaling as well.
  TEST_LOG("Decreasing level by 50%%.\n");
  EXPECT_EQ(0, voe_file_->ScaleFileAsMicrophonePlayout(channel_, 0.5f));
  Sleep(1000);

  EXPECT_EQ(0, voe_file_->StopPlayingFileAsMicrophone(channel_));
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: cachecontroller.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: hr $ $Date: 2004-06-18 15:52:00 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

/* PLEASE DON'T DELETE ANY COMMENT LINES, ALSO IT'S UNNECESSARY. */

#ifndef CONFIGMGR_BACKEND_CACHECONTROLLER_HXX
#define CONFIGMGR_BACKEND_CACHECONTROLLER_HXX

#ifndef CONFIGMGR_UTILITY_HXX_
#include "utility.hxx"
#endif
#ifndef CONFIGMGR_BACKEND_CACHEDDATAPROVIDER_HXX
#include "cacheddataprovider.hxx"
#endif
#ifndef CONFIGMGR_BACKEND_MERGEDDATAPROVIDER_HXX
#include "mergeddataprovider.hxx"
#endif

#ifndef CONFIGMGR_CACHEACCESS_HXX
#include "cacheaccess.hxx"
#endif
#ifndef CONFIGMGR_BACKEND_CACHEMULTICASTER_HXX
#include "cachemulticaster.hxx"
#endif
#ifndef CONFIGMGR_MISC_REQUESTOPTIONS_HXX_
#include "requestoptions.hxx"
#endif

#ifndef CONFIGMGR_AUTOREFERENCEMAP_HXX
#include "autoreferencemap.hxx"
#endif

#ifndef _COM_SUN_STAR_UNO_XCOMPONENTCONTEXT_HPP_
#include <com/sun/star/uno/XComponentContext.hpp>
#endif

namespace configmgr
{
// ---------------------------------------------------------------------------
    class OTreeDisposeScheduler;
    class OCacheWriteScheduler;
// ---------------------------------------------------------------------------
    namespace backend
    {
// ---------------------------------------------------------------------------

    /** manages a shared data cache for configuration data
        trying to ensure consistency with a backend
        and provides access to the data for clients
    */
    class CacheController

    : public ICachedDataProvider
    , public IDirectDataProvider // Refcounted
    , public INodeDataListener
    {
        typedef backend::IMergedDataProvider Backend;
        typedef rtl::Reference< Backend > BackendRef;
        typedef ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >
            CreationContext;
    public:
        /** ctor
        */
        explicit
        CacheController(BackendRef const & _xBackend,
                        memory::HeapManager & _rCacheHeapManager,
                        const uno::Reference<uno::XComponentContext>& xContext);

    // ICachedDataProvider implementation
    public:
        // disposing the cache before destroying
        virtual void dispose() CFG_UNO_THROW_RTE();

        /** locates data of a component in the cache.

 If the data isn't in the cache it is loaded from the backend.

            @param _aRequest
                identifies the component to be loaded.

            @returns
                data that can be used to locate the loaded data in the cache.

            @throws com::sun::star::uno::Exception
                if loading the data fails.
                The exact exception being thrown may depend on the underlying backend.
        */
        virtual CacheLocation loadComponent(ComponentRequest const & _aRequest)
            CFG_UNO_THROW_ALL();

        /** releases data of a component from the cache.

 Should be called when a client is done with a component.
                Each calls to <method>loadComponent</method> should
                be balanced by exactly one call to <method>freeComponent</method>.

            @param _aRequest
                identifies a component previously loaded via <method>loadComponent</method>.

            @returns
                data that can be used to locate the loaded data in the cache.
        */
        virtual void freeComponent(ComponentRequest const & _aRequest)
            CFG_NOTHROW();

        /** refreshes data of an existing component from the backend

 If the data is in the cache already, it is refreshed from the
                backend and the change are notified to all registered listeners.

 If the data isn't in the cache nothing is done and
                a NULL location is returned.

Note: the caller must not hold any lock on the cache line affected.

            @param _aRequest
                identifies the component to be refreshed.

            @returns
                data that can be used to locate the refreshed data in the cache.

If there is no data to refresh a NULL location is returned.

            @throws com::sun::star::uno::Exception
                if loading the data fails.
                The exact exception being thrown may depend on the underlying backend.
        */
        virtual CacheLocation refreshComponent(ComponentRequest const & _aRequest)
            CFG_UNO_THROW_ALL();
         /** refreshes data of all existing components from the backend

 If the data is in the cache already, it is refreshed from the
                backend and the change are notified to all registered listeners.

 If the data isn't in the cache nothing is done and
                a NULL location is returned.

Note: the caller must not hold any lock on the cache line affected.

             @throws com::sun::star::uno::Exception
                if loading the data fails.
                The exact exception being thrown may depend on the underlying backend.
        */
        virtual void refreshAllComponents()
            CFG_UNO_THROW_ALL();

        /** locates a template in the cache.

 If the data isn't in the cache it is loaded from the backend.

Note: the caller must not hold any lock on the cache line affected.

            @param _aRequest
                identifies the template to be loaded.

            @returns
                data that can be used to locate the template data in the cache.

            @throws com::sun::star::uno::Exception
                if loading the template data fails.
                The exact exception being thrown may depend on the underlying backend.
        */
        virtual CacheLocation loadTemplate(TemplateRequest const & _aRequest)
            CFG_UNO_THROW_ALL();

        /** saves changes to the backend and notifies them to registered listeners.

 Must be called after the changes have been applied to the cache
                and before any subsequent changes to the same component.

 Notifications are guaranteed to be delivered
                before any subsequent changes to the same component are possible.

 Note: the caller must hold a read lock (but no write lock)
                on the cache line affected during the call.

            @param _anUpdate
                identifies the node that changed and describes the changes.

            @throws com::sun::star::uno::Exception
                if saving the changes to the backend fails.
                The exact exception being thrown may depend on the underlying backend.
        */
        virtual void saveAndNotify(UpdateRequest const & _anUpdate)
            CFG_UNO_THROW_ALL();

       /** @returns
                an object that can used to broadcast changes done through this object.

 The object returned is guaranteed to live as long
                    as this ICachedDataProvider lives.

        */
        virtual ICachedDataNotifier & getNotifier() CFG_NOTHROW()
        { return m_aNotifier; }

       /**  @returns
                an object that can be used to retrieve owned copies of the data,
                defaults and templates.

 The object returned is guaranteed to live as long
                    as this ICachedDataProvider lives.

        */
        virtual IDirectDataProvider & getDirectDataProvider() CFG_NOTHROW()
        { return *this; }

    // IDirectDataProvider implementation
    public:
        /** loads merged data for a (complete) tree and returns it as return value.

            @param _aRequest
                identifies the component to be loaded

            @param __bAddListenter
                identifies is listener is to be registered to backend

            @returns
                A valid component instance for the given component.

            @throws com::sun::star::uno::Exception
                if the node cannot be retrieved.
                The exact exception being thrown may depend on the underlying backend.

        */
        virtual ComponentResult getComponentData(ComponentRequest const & _aRequest,
                                                 bool _bAddListenter)
            CFG_UNO_THROW_ALL();

        /** loads default data for a (partial) tree and returns it as return value

            @param _aRequest
                identifies the node to be loaded

            @returns
                A valid node instance for the default state of the given node.

May be NULL, if the node exists but has no default equivalent.

            @throws com::sun::star::uno::Exception
                if the default cannot be retrieved.
                The exact exception being thrown may depend on the underlying backend.
        */
        virtual NodeResult getDefaultData(NodeRequest const & _aRequest)
            CFG_UNO_THROW_ALL();

        /** loads a given template and returns it as return value

            @param _aRequest
                identifies the template to be loaded

            @returns
                A valid instance of the given template.

 Currently a request with empty template name
                    will retrieve a group node holding all templates
                    of a component.

            @throws com::sun::star::uno::Exception
                if the template cannot be retrieved.
                The exact exception being thrown may depend on the underlying backend.
        */
        virtual TemplateResult getTemplateData(TemplateRequest const & _aRequest)
            CFG_UNO_THROW_ALL();
        //INodeDataListener Implementation
        /** Triggered when component data is changed

            @param _aRequest
                identifies the data that changed
        */
        virtual void dataChanged(const ComponentRequest& _aRequest) CFG_NOTHROW();
    protected:
        // ref counted, that's why no public dtor
        ~CacheController();

        memory::HeapManager & getCacheHeapManager() const;
    // implementation
    private:
        typedef CacheLoadingAccess      Cache;
        typedef rtl::Reference<Cache>   CacheRef;

    private:
        AbsolutePath encodeTemplateLocation(const Name& _rName, const Name &_rModule) const;

        AbsolutePath ensureTemplate(Name const& _rName, Name const& _rModule) CFG_UNO_THROW_ALL(  );

        // adjust a node result for locale, ...
        bool normalizeResult(std::auto_ptr<ISubtree> &  _aResult, RequestOptions const & _aOptions);

        // reads data from the backend directly
        ComponentResult loadDirectly(ComponentRequest const & _aRequest, bool _bAddListenter )
            CFG_UNO_THROW_ALL(  );
        // reads default data from the backend directly
        NodeResult loadDefaultsDirectly(NodeRequest const & _aRequest) CFG_UNO_THROW_ALL(  );
        // writes an update  to the backend directly
        void saveDirectly(UpdateRequest const & _anUpdate) CFG_UNO_THROW_ALL(  );

        // marks a component as invalid and initiates a (background ?) refresh on it
        void invalidateComponent(ComponentRequest const & _aComponent) CFG_UNO_THROW_ALL(  );
        // writes updates for a component to the backend directly
        void savePendingChanges(CacheRef const & _aCache, ComponentRequest const & _aComponent)
            CFG_UNO_THROW_ALL(  );
        // saves all pending changes from a cache access to the backend
        bool saveAllPendingChanges(CacheRef const & _aCache, RequestOptions const & _aOptions)
            CFG_UNO_THROW_RTE(  );
        // load templates componentwise from backend
        std::auto_ptr<ISubtree> loadTemplateData(TemplateRequest const & _aRequest)
            CFG_UNO_THROW_ALL(  );

        void flushPendingUpdates() CFG_NOTHROW();
        // add templates componentwise to cache
        data::TreeAddress addTemplates ( backend::ComponentData const & _aComponentInstance );
        CacheRef getCacheAlways(RequestOptions const & _aOptions);

        OTreeDisposeScheduler   * createDisposer(const CreationContext& _xContext);
        OCacheWriteScheduler    * createCacheWriter(const CreationContext& _xContext);

        // disposing
        void disposeAll(bool _bFlushRemainingUpdates);
        void disposeOne(RequestOptions const & _aOptions, bool _bFlushUpdates = true);
        void disposeUser(RequestOptions const & _aUserOptions, bool _bFlushUpdates = true);
        void implDisposeOne(CacheRef const & _aCache, RequestOptions const & _aOptions, bool _bFlushUpdates);

        void closeModules(Cache::DisposeList & _aList, RequestOptions const & _aOptions);
    private:
        typedef AutoReferenceMap<RequestOptions,Cache,lessRequestOptions>   CacheList;
        typedef TemplateCacheData TemplateCache;

        CacheChangeMulticaster  m_aNotifier;
        BackendRef              m_xBackend;

        CacheList               m_aCacheList; // Map
        TemplateCache           m_aTemplates;

        osl::Mutex              m_aTemplatesMutex;

        OTreeDisposeScheduler*  m_pDisposer;
        OCacheWriteScheduler *  m_pCacheWriter;

        bool m_bDisposing; // disables async writing and automatic refresh

        friend class configmgr::OTreeDisposeScheduler;
        friend class configmgr::OCacheWriteScheduler;
        friend class OInvalidateTreeThread;

    };
// ---------------------------------------------------------------------------
    } // namespace backend

// ---------------------------------------------------------------------------
} // namespace configmgr

#endif

<commit_msg>INTEGRATION: CWS cfglooseends (1.8.30); FILE MERGED 2004/11/08 10:46:13 jb 1.8.30.1: #i36826# Correct various brokenness in flushAll and refreshAll<commit_after>/*************************************************************************
 *
 *  $RCSfile: cachecontroller.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: obo $ $Date: 2004-11-15 13:37:34 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

/* PLEASE DON'T DELETE ANY COMMENT LINES, ALSO IT'S UNNECESSARY. */

#ifndef CONFIGMGR_BACKEND_CACHECONTROLLER_HXX
#define CONFIGMGR_BACKEND_CACHECONTROLLER_HXX

#ifndef CONFIGMGR_UTILITY_HXX_
#include "utility.hxx"
#endif
#ifndef CONFIGMGR_BACKEND_CACHEDDATAPROVIDER_HXX
#include "cacheddataprovider.hxx"
#endif
#ifndef CONFIGMGR_BACKEND_MERGEDDATAPROVIDER_HXX
#include "mergeddataprovider.hxx"
#endif

#ifndef CONFIGMGR_CACHEACCESS_HXX
#include "cacheaccess.hxx"
#endif
#ifndef CONFIGMGR_BACKEND_CACHEMULTICASTER_HXX
#include "cachemulticaster.hxx"
#endif
#ifndef CONFIGMGR_MISC_REQUESTOPTIONS_HXX_
#include "requestoptions.hxx"
#endif

#ifndef CONFIGMGR_AUTOREFERENCEMAP_HXX
#include "autoreferencemap.hxx"
#endif

#ifndef _COM_SUN_STAR_UNO_XCOMPONENTCONTEXT_HPP_
#include <com/sun/star/uno/XComponentContext.hpp>
#endif

namespace configmgr
{
// ---------------------------------------------------------------------------
    class OTreeDisposeScheduler;
    class OCacheWriteScheduler;
// ---------------------------------------------------------------------------
    namespace backend
    {
// ---------------------------------------------------------------------------

    /** manages a shared data cache for configuration data
        trying to ensure consistency with a backend
        and provides access to the data for clients
    */
    class CacheController

    : public ICachedDataProvider
    , public IDirectDataProvider // Refcounted
    , public INodeDataListener
    {
        typedef backend::IMergedDataProvider Backend;
        typedef rtl::Reference< Backend > BackendRef;
        typedef ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >
            CreationContext;
    public:
        /** ctor
        */
        explicit
        CacheController(BackendRef const & _xBackend,
                        memory::HeapManager & _rCacheHeapManager,
                        const uno::Reference<uno::XComponentContext>& xContext);

    // ICachedDataProvider implementation
    public:
        // disposing the cache before destroying
        virtual void dispose() CFG_UNO_THROW_RTE();

        /** locates data of a component in the cache.

 If the data isn't in the cache it is loaded from the backend.

            @param _aRequest
                identifies the component to be loaded.

            @returns
                data that can be used to locate the loaded data in the cache.

            @throws com::sun::star::uno::Exception
                if loading the data fails.
                The exact exception being thrown may depend on the underlying backend.
        */
        virtual CacheLocation loadComponent(ComponentRequest const & _aRequest)
            CFG_UNO_THROW_ALL();

        /** releases data of a component from the cache.

 Should be called when a client is done with a component.
                Each calls to <method>loadComponent</method> should
                be balanced by exactly one call to <method>freeComponent</method>.

            @param _aRequest
                identifies a component previously loaded via <method>loadComponent</method>.

            @returns
                data that can be used to locate the loaded data in the cache.
        */
        virtual void freeComponent(ComponentRequest const & _aRequest)
            CFG_NOTHROW();

        /** refreshes data of an existing component from the backend

 If the data is in the cache already, it is refreshed from the
                backend and the change are notified to all registered listeners.

 If the data isn't in the cache nothing is done and
                a NULL location is returned.

Note: the caller must not hold any lock on the cache line affected.

            @param _aRequest
                identifies the component to be refreshed.

            @returns
                data that can be used to locate the refreshed data in the cache.

If there is no data to refresh a NULL location is returned.

            @throws com::sun::star::uno::Exception
                if loading the data fails.
                The exact exception being thrown may depend on the underlying backend.
        */
        virtual CacheLocation refreshComponent(ComponentRequest const & _aRequest)
            CFG_UNO_THROW_ALL();
         /** refreshes data of all existing components from the backend

 If the data is in the cache already, it is refreshed from the
                backend and the change are notified to all registered listeners.

 If the data isn't in the cache nothing is done and
                a NULL location is returned.

Note: the caller must not hold any lock on the cache line affected.

             @throws com::sun::star::uno::Exception
                if loading the data fails.
                The exact exception being thrown may depend on the underlying backend.
        */
        virtual void refreshAllComponents()
            CFG_UNO_THROW_ALL();

        /** locates a template in the cache.

 If the data isn't in the cache it is loaded from the backend.

Note: the caller must not hold any lock on the cache line affected.

            @param _aRequest
                identifies the template to be loaded.

            @returns
                data that can be used to locate the template data in the cache.

            @throws com::sun::star::uno::Exception
                if loading the template data fails.
                The exact exception being thrown may depend on the underlying backend.
        */
        virtual CacheLocation loadTemplate(TemplateRequest const & _aRequest)
            CFG_UNO_THROW_ALL();

        /** saves changes to the backend and notifies them to registered listeners.

 Must be called after the changes have been applied to the cache
                and before any subsequent changes to the same component.

 Notifications are guaranteed to be delivered
                before any subsequent changes to the same component are possible.

 Note: the caller must hold a read lock (but no write lock)
                on the cache line affected during the call.

            @param _anUpdate
                identifies the node that changed and describes the changes.

            @throws com::sun::star::uno::Exception
                if saving the changes to the backend fails.
                The exact exception being thrown may depend on the underlying backend.
        */
        virtual void saveAndNotify(UpdateRequest const & _anUpdate)
            CFG_UNO_THROW_ALL();

       /** @returns
                an object that can used to broadcast changes done through this object.

 The object returned is guaranteed to live as long
                    as this ICachedDataProvider lives.

        */
        virtual ICachedDataNotifier & getNotifier() CFG_NOTHROW()
        { return m_aNotifier; }

       /**  @returns
                an object that can be used to retrieve owned copies of the data,
                defaults and templates.

 The object returned is guaranteed to live as long
                    as this ICachedDataProvider lives.

        */
        virtual IDirectDataProvider & getDirectDataProvider() CFG_NOTHROW()
        { return *this; }

    // IDirectDataProvider implementation
    public:
        /** loads merged data for a (complete) tree and returns it as return value.

            @param _aRequest
                identifies the component to be loaded

            @param __bAddListenter
                identifies is listener is to be registered to backend

            @returns
                A valid component instance for the given component.

            @throws com::sun::star::uno::Exception
                if the node cannot be retrieved.
                The exact exception being thrown may depend on the underlying backend.

        */
        virtual ComponentResult getComponentData(ComponentRequest const & _aRequest,
                                                 bool _bAddListenter)
            CFG_UNO_THROW_ALL();

        /** loads default data for a (partial) tree and returns it as return value

            @param _aRequest
                identifies the node to be loaded

            @returns
                A valid node instance for the default state of the given node.

May be NULL, if the node exists but has no default equivalent.

            @throws com::sun::star::uno::Exception
                if the default cannot be retrieved.
                The exact exception being thrown may depend on the underlying backend.
        */
        virtual NodeResult getDefaultData(NodeRequest const & _aRequest)
            CFG_UNO_THROW_ALL();

        /** loads a given template and returns it as return value

            @param _aRequest
                identifies the template to be loaded

            @returns
                A valid instance of the given template.

 Currently a request with empty template name
                    will retrieve a group node holding all templates
                    of a component.

            @throws com::sun::star::uno::Exception
                if the template cannot be retrieved.
                The exact exception being thrown may depend on the underlying backend.
        */
        virtual TemplateResult getTemplateData(TemplateRequest const & _aRequest)
            CFG_UNO_THROW_ALL();
        //INodeDataListener Implementation
        /** Triggered when component data is changed

            @param _aRequest
                identifies the data that changed
        */
        virtual void dataChanged(const ComponentRequest& _aRequest) CFG_NOTHROW();
    protected:
        // ref counted, that's why no public dtor
        ~CacheController();

        memory::HeapManager & getCacheHeapManager() const;
    // implementation
    private:
        typedef CacheLoadingAccess      Cache;
        typedef rtl::Reference<Cache>   CacheRef;

    private:
        AbsolutePath encodeTemplateLocation(const Name& _rName, const Name &_rModule) const;

        AbsolutePath ensureTemplate(Name const& _rName, Name const& _rModule) CFG_UNO_THROW_ALL(  );

        // adjust a node result for locale, ...
        bool normalizeResult(std::auto_ptr<ISubtree> &  _aResult, RequestOptions const & _aOptions);

        // reads data from the backend directly
        ComponentResult loadDirectly(ComponentRequest const & _aRequest, bool _bAddListenter )
            CFG_UNO_THROW_ALL(  );
        // reads default data from the backend directly
        NodeResult loadDefaultsDirectly(NodeRequest const & _aRequest) CFG_UNO_THROW_ALL(  );
        // writes an update  to the backend directly
        void saveDirectly(UpdateRequest const & _anUpdate) CFG_UNO_THROW_ALL(  );

        // marks a component as invalid and initiates a (background ?) refresh on it
        void invalidateComponent(ComponentRequest const & _aComponent) CFG_UNO_THROW_ALL(  );
        // writes updates for a component to the backend directly
        void savePendingChanges(CacheRef const & _aCache, ComponentRequest const & _aComponent)
            CFG_UNO_THROW_ALL(  );
        // saves all pending changes from a cache access to the backend
        bool saveAllPendingChanges(CacheRef const & _aCache, RequestOptions const & _aOptions)
            CFG_UNO_THROW_RTE(  );
        // load templates componentwise from backend
        std::auto_ptr<ISubtree> loadTemplateData(TemplateRequest const & _aRequest)
            CFG_UNO_THROW_ALL(  );

        void flushPendingUpdates() CFG_UNO_THROW_ALL();

        void flushCacheWriter() CFG_NOTHROW();
        // add templates componentwise to cache
        data::TreeAddress addTemplates ( backend::ComponentData const & _aComponentInstance );
        CacheRef getCacheAlways(RequestOptions const & _aOptions);

        OTreeDisposeScheduler   * createDisposer(const CreationContext& _xContext);
        OCacheWriteScheduler    * createCacheWriter(const CreationContext& _xContext);

        // disposing
        void disposeAll(bool _bFlushRemainingUpdates);
        void disposeOne(RequestOptions const & _aOptions, bool _bFlushUpdates = true);
        void disposeUser(RequestOptions const & _aUserOptions, bool _bFlushUpdates = true);
        void implDisposeOne(CacheRef const & _aCache, RequestOptions const & _aOptions, bool _bFlushUpdates);

        void closeModules(Cache::DisposeList & _aList, RequestOptions const & _aOptions);
    private:
        typedef AutoReferenceMap<RequestOptions,Cache,lessRequestOptions>   CacheList;
        typedef TemplateCacheData TemplateCache;

        CacheChangeMulticaster  m_aNotifier;
        BackendRef              m_xBackend;

        CacheList               m_aCacheList; // Map
        TemplateCache           m_aTemplates;

        osl::Mutex              m_aTemplatesMutex;

        OTreeDisposeScheduler*  m_pDisposer;
        OCacheWriteScheduler *  m_pCacheWriter;

        bool m_bDisposing; // disables async writing and automatic refresh

        friend class configmgr::OTreeDisposeScheduler;
        friend class configmgr::OCacheWriteScheduler;
        friend class OInvalidateTreeThread;

    };
// ---------------------------------------------------------------------------
    } // namespace backend

// ---------------------------------------------------------------------------
} // namespace configmgr

#endif

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: HTables.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: kz $ $Date: 2006-07-19 15:53:06 $
 *
 *  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 CONNECTIVITY_HSQLDB_TABLES_HXX
#include "hsqldb/HTables.hxx"
#endif
#ifndef _CONNECTIVITY_HSQLDB_VIEWS_HXX_
#include "hsqldb/HViews.hxx"
#endif
#ifndef CONNECTIVITY_HSQLDB_TABLE_HXX
#include "hsqldb/HTable.hxx"
#endif
#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
#include <com/sun/star/sdbc/XRow.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XRESULTSET_HPP_
#include <com/sun/star/sdbc/XResultSet.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_COLUMNVALUE_HPP_
#include <com/sun/star/sdbc/ColumnValue.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_PRIVILEGE_HPP_
#include <com/sun/star/sdbcx/Privilege.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_KEYRULE_HPP_
#include <com/sun/star/sdbc/KeyRule.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_KEYTYPE_HPP_
#include <com/sun/star/sdbcx/KeyType.hpp>
#endif
#ifndef CONNECTIVITY_HSQLDB_CATALOG_HXX
#include "hsqldb/HCatalog.hxx"
#endif
#ifndef _COMPHELPER_EXTRACT_HXX_
#include <comphelper/extract.hxx>
#endif
#ifndef _CONNECTIVITY_DBTOOLS_HXX_
#include "connectivity/dbtools.hxx"
#endif
#ifndef _DBHELPER_DBEXCEPTION_HXX_
#include "connectivity/dbexception.hxx"
#endif
#ifndef _CPPUHELPER_INTERFACECONTAINER_H_
#include <cppuhelper/interfacecontainer.h>
#endif
#ifndef _COMPHELPER_TYPES_HXX_
#include <comphelper/types.hxx>
#endif
#ifndef CONNECTIVITY_CONNECTION_HXX
#include "TConnection.hxx"
#endif

using namespace ::comphelper;
using namespace connectivity;
using namespace ::cppu;
using namespace connectivity::hsqldb;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::lang;
using namespace dbtools;
typedef connectivity::sdbcx::OCollection OCollection_TYPE;

sdbcx::ObjectType OTables::createObject(const ::rtl::OUString& _rName)
{
    ::rtl::OUString sCatalog,sSchema,sTable;
    ::dbtools::qualifiedNameComponents(m_xMetaData,_rName,sCatalog,sSchema,sTable,::dbtools::eInDataManipulation);

    static const ::rtl::OUString s_sTableTypeView(RTL_CONSTASCII_USTRINGPARAM("VIEW"));
    static const ::rtl::OUString s_sTableTypeTable(RTL_CONSTASCII_USTRINGPARAM("TABLE"));
    static const ::rtl::OUString s_sAll(RTL_CONSTASCII_USTRINGPARAM("%"));

    Sequence< ::rtl::OUString > sTableTypes(3);
    sTableTypes[0] = s_sTableTypeView;
    sTableTypes[1] = s_sTableTypeTable;
    sTableTypes[2] = s_sAll;    // just to be sure to include anything else ....

    Any aCatalog;
    if ( sCatalog.getLength() )
        aCatalog <<= sCatalog;
    Reference< XResultSet > xResult = m_xMetaData->getTables(aCatalog,sSchema,sTable,sTableTypes);

    sdbcx::ObjectType xRet = NULL;
    if ( xResult.is() )
    {
        Reference< XRow > xRow(xResult,UNO_QUERY);
        if ( xResult->next() ) // there can be only one table with this name
        {
            sal_Int32 nPrivileges = ::dbtools::getTablePrivileges( m_xMetaData, sCatalog, sSchema, sTable );
            if ( m_xMetaData->isReadOnly() )
                nPrivileges &= ~( Privilege::INSERT | Privilege::UPDATE | Privilege::DELETE | Privilege::CREATE | Privilege::ALTER | Privilege::DROP );

            // obtain privileges
            OHSQLTable* pRet = new OHSQLTable( this
                                                ,static_cast<OHCatalog&>(m_rParent).getConnection()
                                                ,sTable
                                                ,xRow->getString(4)
                                                ,xRow->getString(5)
                                                ,sSchema
                                                ,sCatalog
                                                ,nPrivileges);
            xRet = pRet;
        }
        ::comphelper::disposeComponent(xResult);
    }

    return xRet;
}
// -------------------------------------------------------------------------
void OTables::impl_refresh(  ) throw(RuntimeException)
{
    static_cast<OHCatalog&>(m_rParent).refreshTables();
}
// -------------------------------------------------------------------------
void OTables::disposing(void)
{
    m_xMetaData = NULL;
    OCollection::disposing();
}
// -------------------------------------------------------------------------
Reference< XPropertySet > OTables::createDescriptor()
{
    return new OHSQLTable(this,static_cast<OHCatalog&>(m_rParent).getConnection());
}
// -------------------------------------------------------------------------
// XAppend
sdbcx::ObjectType OTables::appendObject( const ::rtl::OUString& _rForName, const Reference< XPropertySet >& descriptor )
{
    createTable(descriptor);
    return createObject( _rForName );
}
// -------------------------------------------------------------------------
// XDrop
void OTables::dropObject(sal_Int32 _nPos,const ::rtl::OUString _sElementName)
{
    Reference< XInterface > xObject( getObject( _nPos ) );
    sal_Bool bIsNew = connectivity::sdbcx::ODescriptor::isNew( xObject );
    if (!bIsNew)
    {
        Reference< XConnection > xConnection = static_cast<OHCatalog&>(m_rParent).getConnection();

        ::rtl::OUString sCatalog,sSchema,sTable;
        ::dbtools::qualifiedNameComponents(m_xMetaData,_sElementName,sCatalog,sSchema,sTable,::dbtools::eInDataManipulation);

        ::rtl::OUString aSql = ::rtl::OUString::createFromAscii("DROP ");

        Reference<XPropertySet> xProp(xObject,UNO_QUERY);
        sal_Bool bIsView;
        if((bIsView = (xProp.is() && ::comphelper::getString(xProp->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE))) == ::rtl::OUString::createFromAscii("VIEW")))) // here we have a view
            aSql += ::rtl::OUString::createFromAscii("VIEW ");
        else
            aSql += ::rtl::OUString::createFromAscii("TABLE ");

        ::rtl::OUString sComposedName(
            ::dbtools::composeTableName( m_xMetaData, sCatalog, sSchema, sTable, sal_True, ::dbtools::eInDataManipulation ) );
        aSql += sComposedName;
        Reference< XStatement > xStmt = xConnection->createStatement(  );
        if ( xStmt.is() )
        {
            xStmt->execute(aSql);
            ::comphelper::disposeComponent(xStmt);
        }
        // if no exception was thrown we must delete it from the views
        if ( bIsView )
        {
            OViews* pViews = static_cast<OViews*>(static_cast<OHCatalog&>(m_rParent).getPrivateViews());
            if ( pViews && pViews->hasByName(_sElementName) )
                pViews->dropByNameImpl(_sElementName);
        }
    }
}
// -------------------------------------------------------------------------
void OTables::createTable( const Reference< XPropertySet >& descriptor )
{
    Reference< XConnection > xConnection = static_cast<OHCatalog&>(m_rParent).getConnection();
    ::rtl::OUString aSql = ::dbtools::createSqlCreateTableStatement(descriptor,xConnection);

    Reference< XStatement > xStmt = xConnection->createStatement(  );
    if ( xStmt.is() )
    {
        xStmt->execute(aSql);
        ::comphelper::disposeComponent(xStmt);
    }
}
// -----------------------------------------------------------------------------
void OTables::appendNew(const ::rtl::OUString& _rsNewTable)
{
    insertElement(_rsNewTable,NULL);

    // notify our container listeners
    ContainerEvent aEvent(static_cast<XContainer*>(this), makeAny(_rsNewTable), Any(), Any());
    OInterfaceIteratorHelper aListenerLoop(m_aContainerListeners);
    while (aListenerLoop.hasMoreElements())
        static_cast<XContainerListener*>(aListenerLoop.next())->elementInserted(aEvent);
}
// -----------------------------------------------------------------------------
::rtl::OUString OTables::getNameForObject(const sdbcx::ObjectType& _xObject)
{
    OSL_ENSURE(_xObject.is(),"OTables::getNameForObject: Object is NULL!");
    return ::dbtools::composeTableName( m_xMetaData, _xObject, ::dbtools::eInDataManipulation, false, false, false );
}
// -----------------------------------------------------------------------------

<commit_msg>INTEGRATION: CWS pchfix02 (1.7.34); FILE MERGED 2006/09/01 17:22:16 kaib 1.7.34.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: HTables.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 02:41:26 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_connectivity.hxx"

#ifndef CONNECTIVITY_HSQLDB_TABLES_HXX
#include "hsqldb/HTables.hxx"
#endif
#ifndef _CONNECTIVITY_HSQLDB_VIEWS_HXX_
#include "hsqldb/HViews.hxx"
#endif
#ifndef CONNECTIVITY_HSQLDB_TABLE_HXX
#include "hsqldb/HTable.hxx"
#endif
#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
#include <com/sun/star/sdbc/XRow.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XRESULTSET_HPP_
#include <com/sun/star/sdbc/XResultSet.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_COLUMNVALUE_HPP_
#include <com/sun/star/sdbc/ColumnValue.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_PRIVILEGE_HPP_
#include <com/sun/star/sdbcx/Privilege.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_KEYRULE_HPP_
#include <com/sun/star/sdbc/KeyRule.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_KEYTYPE_HPP_
#include <com/sun/star/sdbcx/KeyType.hpp>
#endif
#ifndef CONNECTIVITY_HSQLDB_CATALOG_HXX
#include "hsqldb/HCatalog.hxx"
#endif
#ifndef _COMPHELPER_EXTRACT_HXX_
#include <comphelper/extract.hxx>
#endif
#ifndef _CONNECTIVITY_DBTOOLS_HXX_
#include "connectivity/dbtools.hxx"
#endif
#ifndef _DBHELPER_DBEXCEPTION_HXX_
#include "connectivity/dbexception.hxx"
#endif
#ifndef _CPPUHELPER_INTERFACECONTAINER_H_
#include <cppuhelper/interfacecontainer.h>
#endif
#ifndef _COMPHELPER_TYPES_HXX_
#include <comphelper/types.hxx>
#endif
#ifndef CONNECTIVITY_CONNECTION_HXX
#include "TConnection.hxx"
#endif

using namespace ::comphelper;
using namespace connectivity;
using namespace ::cppu;
using namespace connectivity::hsqldb;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::lang;
using namespace dbtools;
typedef connectivity::sdbcx::OCollection OCollection_TYPE;

sdbcx::ObjectType OTables::createObject(const ::rtl::OUString& _rName)
{
    ::rtl::OUString sCatalog,sSchema,sTable;
    ::dbtools::qualifiedNameComponents(m_xMetaData,_rName,sCatalog,sSchema,sTable,::dbtools::eInDataManipulation);

    static const ::rtl::OUString s_sTableTypeView(RTL_CONSTASCII_USTRINGPARAM("VIEW"));
    static const ::rtl::OUString s_sTableTypeTable(RTL_CONSTASCII_USTRINGPARAM("TABLE"));
    static const ::rtl::OUString s_sAll(RTL_CONSTASCII_USTRINGPARAM("%"));

    Sequence< ::rtl::OUString > sTableTypes(3);
    sTableTypes[0] = s_sTableTypeView;
    sTableTypes[1] = s_sTableTypeTable;
    sTableTypes[2] = s_sAll;    // just to be sure to include anything else ....

    Any aCatalog;
    if ( sCatalog.getLength() )
        aCatalog <<= sCatalog;
    Reference< XResultSet > xResult = m_xMetaData->getTables(aCatalog,sSchema,sTable,sTableTypes);

    sdbcx::ObjectType xRet = NULL;
    if ( xResult.is() )
    {
        Reference< XRow > xRow(xResult,UNO_QUERY);
        if ( xResult->next() ) // there can be only one table with this name
        {
            sal_Int32 nPrivileges = ::dbtools::getTablePrivileges( m_xMetaData, sCatalog, sSchema, sTable );
            if ( m_xMetaData->isReadOnly() )
                nPrivileges &= ~( Privilege::INSERT | Privilege::UPDATE | Privilege::DELETE | Privilege::CREATE | Privilege::ALTER | Privilege::DROP );

            // obtain privileges
            OHSQLTable* pRet = new OHSQLTable( this
                                                ,static_cast<OHCatalog&>(m_rParent).getConnection()
                                                ,sTable
                                                ,xRow->getString(4)
                                                ,xRow->getString(5)
                                                ,sSchema
                                                ,sCatalog
                                                ,nPrivileges);
            xRet = pRet;
        }
        ::comphelper::disposeComponent(xResult);
    }

    return xRet;
}
// -------------------------------------------------------------------------
void OTables::impl_refresh(  ) throw(RuntimeException)
{
    static_cast<OHCatalog&>(m_rParent).refreshTables();
}
// -------------------------------------------------------------------------
void OTables::disposing(void)
{
    m_xMetaData = NULL;
    OCollection::disposing();
}
// -------------------------------------------------------------------------
Reference< XPropertySet > OTables::createDescriptor()
{
    return new OHSQLTable(this,static_cast<OHCatalog&>(m_rParent).getConnection());
}
// -------------------------------------------------------------------------
// XAppend
sdbcx::ObjectType OTables::appendObject( const ::rtl::OUString& _rForName, const Reference< XPropertySet >& descriptor )
{
    createTable(descriptor);
    return createObject( _rForName );
}
// -------------------------------------------------------------------------
// XDrop
void OTables::dropObject(sal_Int32 _nPos,const ::rtl::OUString _sElementName)
{
    Reference< XInterface > xObject( getObject( _nPos ) );
    sal_Bool bIsNew = connectivity::sdbcx::ODescriptor::isNew( xObject );
    if (!bIsNew)
    {
        Reference< XConnection > xConnection = static_cast<OHCatalog&>(m_rParent).getConnection();

        ::rtl::OUString sCatalog,sSchema,sTable;
        ::dbtools::qualifiedNameComponents(m_xMetaData,_sElementName,sCatalog,sSchema,sTable,::dbtools::eInDataManipulation);

        ::rtl::OUString aSql = ::rtl::OUString::createFromAscii("DROP ");

        Reference<XPropertySet> xProp(xObject,UNO_QUERY);
        sal_Bool bIsView;
        if((bIsView = (xProp.is() && ::comphelper::getString(xProp->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE))) == ::rtl::OUString::createFromAscii("VIEW")))) // here we have a view
            aSql += ::rtl::OUString::createFromAscii("VIEW ");
        else
            aSql += ::rtl::OUString::createFromAscii("TABLE ");

        ::rtl::OUString sComposedName(
            ::dbtools::composeTableName( m_xMetaData, sCatalog, sSchema, sTable, sal_True, ::dbtools::eInDataManipulation ) );
        aSql += sComposedName;
        Reference< XStatement > xStmt = xConnection->createStatement(  );
        if ( xStmt.is() )
        {
            xStmt->execute(aSql);
            ::comphelper::disposeComponent(xStmt);
        }
        // if no exception was thrown we must delete it from the views
        if ( bIsView )
        {
            OViews* pViews = static_cast<OViews*>(static_cast<OHCatalog&>(m_rParent).getPrivateViews());
            if ( pViews && pViews->hasByName(_sElementName) )
                pViews->dropByNameImpl(_sElementName);
        }
    }
}
// -------------------------------------------------------------------------
void OTables::createTable( const Reference< XPropertySet >& descriptor )
{
    Reference< XConnection > xConnection = static_cast<OHCatalog&>(m_rParent).getConnection();
    ::rtl::OUString aSql = ::dbtools::createSqlCreateTableStatement(descriptor,xConnection);

    Reference< XStatement > xStmt = xConnection->createStatement(  );
    if ( xStmt.is() )
    {
        xStmt->execute(aSql);
        ::comphelper::disposeComponent(xStmt);
    }
}
// -----------------------------------------------------------------------------
void OTables::appendNew(const ::rtl::OUString& _rsNewTable)
{
    insertElement(_rsNewTable,NULL);

    // notify our container listeners
    ContainerEvent aEvent(static_cast<XContainer*>(this), makeAny(_rsNewTable), Any(), Any());
    OInterfaceIteratorHelper aListenerLoop(m_aContainerListeners);
    while (aListenerLoop.hasMoreElements())
        static_cast<XContainerListener*>(aListenerLoop.next())->elementInserted(aEvent);
}
// -----------------------------------------------------------------------------
::rtl::OUString OTables::getNameForObject(const sdbcx::ObjectType& _xObject)
{
    OSL_ENSURE(_xObject.is(),"OTables::getNameForObject: Object is NULL!");
    return ::dbtools::composeTableName( m_xMetaData, _xObject, ::dbtools::eInDataManipulation, false, false, false );
}
// -----------------------------------------------------------------------------

<|endoftext|>


<commit_before>#include <sstream>
#include "CorrectionPattern.h"
#include "moses/Phrase.h"
#include "moses/TargetPhrase.h"
#include "moses/InputPath.h"
#include "moses/Hypothesis.h"
#include "moses/ChartHypothesis.h"
#include "moses/ScoreComponentCollection.h"
#include "moses/TranslationOption.h"
#include "util/string_piece_hash.hh"
#include "util/exception.hh"

#include <functional>
#include <algorithm>

#include <boost/foreach.hpp>
#include <boost/algorithm/string.hpp>

#include "Diffs.h"

namespace Moses
{

using namespace std;

std::string MakePair(const std::string &s1, const std::string &s2, bool general)
{
  std::vector<std::string> sourceList;
  std::vector<std::string> targetList;

  if(general) {
    Diffs diffs = CreateDiff(s1, s2);

    size_t i = 0, j = 0;
    char lastType = 'm';

    std::string source, target;
    std::string match;

    int count = 1;

    BOOST_FOREACH(Diff type, diffs) {
      if(type == 'm') {
        if(lastType != 'm') {
          sourceList.push_back(source);
          targetList.push_back(target);
        }
        source.clear();
        target.clear();

        if(s1[i] == '+') {
          if(match.size() >= 3) {
            sourceList.push_back("(\\w{3,})·");
            std::string temp = "1";
            sprintf((char*)temp.c_str(), "%d", count);
            targetList.push_back("\\" + temp + "·");
            count++;
          } else {
            sourceList.push_back(match + "·");
            targetList.push_back(match + "·");
          }
          match.clear();
        } else
          match.push_back(s1[i]);

        i++;
        j++;
      } else if(type == 'd') {
        if(s1[i] == '+')
          source += "·";
        else
          source.push_back(s1[i]);
        i++;
      } else if(type == 'i') {
        if(s2[j] == '+')
          target += "·";
        else
          target.push_back(s2[j]);
        j++;
      }
      if(type != 'm' && !match.empty()) {
        if(match.size() >= 3) {
          sourceList.push_back("(\\w{3,})");
          std::string temp = "1";
          sprintf((char*)temp.c_str(), "%d", count);
          targetList.push_back("\\" + temp);
          count++;
        } else {
          sourceList.push_back(match);
          targetList.push_back(match);
        }

        match.clear();
      }

      lastType = type;
    }
    if(lastType != 'm') {
      sourceList.push_back(source);
      targetList.push_back(target);
    }

    if(!match.empty()) {
      if(match.size() >= 3) {
        sourceList.push_back("(\\w{3,})");
        std::string temp = "1";
        sprintf((char*)temp.c_str(), "%d", count);
        targetList.push_back("\\"+ temp);
        count++;
      } else {
        sourceList.push_back(match);
        targetList.push_back(match);
      }
    }
    match.clear();
  } else {
    std::string cs1 = s1;
    std::string cs2 = s2;
    boost::replace_all(cs1, "+", "·");
    boost::replace_all(cs2, "+", "·");

    sourceList.push_back(cs1);
    targetList.push_back(cs2);
  }

  std::stringstream out;
  out << "sub(«";
  out << boost::join(sourceList, "");
  out << "»,«";
  out << boost::join(targetList, "");
  out << "»)";

  return out.str();
}

std::string CorrectionPattern::CreateSinglePattern(const Tokens &s1, const Tokens &s2) const
{
  std::stringstream out;
  if(s1.empty()) {
    out << "ins(«" << boost::join(s2, "·") << "»)";
    return out.str();
  } else if(s2.empty()) {
    out << "del(«" << boost::join(s1, "·") << "»)";
    return out.str();
  } else {
    typename Tokens::value_type v1 = boost::join(s1, "+");
    typename Tokens::value_type v2 = boost::join(s2, "+");
    out << MakePair(v1, v2, m_general);
    return out.str();
  }
}

std::vector<std::string> GetContext(size_t pos,
                                    size_t len,
                                    size_t window,
                                    const InputType &input,
                                    const InputPath &inputPath,
                                    const std::vector<FactorType>& factorTypes,
                                    bool isRight)
{

  const Sentence& sentence = static_cast<const Sentence&>(input);
  const Range& range = inputPath.GetWordsRange();

  int leftPos  = range.GetStartPos() + pos - len - 1;
  int rightPos = range.GetStartPos() + pos;

  std::vector<std::string> contexts;

  for(int length = 1; length <= (int)window; ++length) {
    std::vector<std::string> current;
    if(!isRight) {
      for(int i = 0; i < length; i++) {
        if(leftPos - i >= 0) {
          current.push_back(sentence.GetWord(leftPos - i).GetString(factorTypes, false));
        } else {
          current.push_back("<s>");
        }
      }

      if(current.back() == "<s>" && current.size() >= 2 && current[current.size()-2] == "<s>")
        continue;

      std::reverse(current.begin(), current.end());
      contexts.push_back("left(«" + boost::join(current, "·") + "»)_");
    }
    if(isRight) {
      for(int i = 0; i < length; i++) {
        if(rightPos + i < (int)sentence.GetSize()) {
          current.push_back(sentence.GetWord(rightPos + i).GetString(factorTypes, false));
        } else {
          current.push_back("</s>");
        }
      }

      if(current.back() == "</s>" && current.size() >= 2 && current[current.size()-2] == "</s>")
        continue;

      contexts.push_back("_right(«" + boost::join(current, "·") + "»)");
    }
  }
  return contexts;
}

std::vector<std::string>
CorrectionPattern::CreatePattern(const Tokens &s1,
                                 const Tokens &s2,
                                 const InputType &input,
                                 const InputPath &inputPath) const
{

  Diffs diffs = CreateDiff(s1, s2);
  size_t i = 0, j = 0;
  char lastType = 'm';
  std::vector<std::string> patternList;
  Tokens source, target;
  BOOST_FOREACH(Diff type, diffs) {
    if(type == 'm') {
      if(lastType != 'm') {
        std::string pattern = CreateSinglePattern(source, target);
        patternList.push_back(pattern);

        if(m_context > 0) {
          std::vector<std::string> leftContexts =  GetContext(i, source.size(), m_context, input, inputPath, m_contextFactors, false);
          std::vector<std::string> rightContexts = GetContext(i, source.size(), m_context, input, inputPath, m_contextFactors, true);

          BOOST_FOREACH(std::string left, leftContexts)
          patternList.push_back(left + pattern);

          BOOST_FOREACH(std::string right, rightContexts)
          patternList.push_back(pattern + right);

          BOOST_FOREACH(std::string left, leftContexts)
          BOOST_FOREACH(std::string right, rightContexts)
          patternList.push_back(left + pattern + right);
        }
      }
      source.clear();
      target.clear();
      if(s1[i] != s2[j]) {
        source.push_back(s1[i]);
        target.push_back(s2[j]);
      }
      i++;
      j++;
    } else if(type == 'd') {
      source.push_back(s1[i]);
      i++;
    } else if(type == 'i') {
      target.push_back(s2[j]);
      j++;
    }
    lastType = type;
  }
  if(lastType != 'm') {
    std::string pattern = CreateSinglePattern(source, target);
    patternList.push_back(pattern);

    if(m_context > 0) {
      std::vector<std::string> leftContexts =  GetContext(i, source.size(), m_context, input, inputPath, m_contextFactors, false);
      std::vector<std::string> rightContexts = GetContext(i, source.size(), m_context, input, inputPath, m_contextFactors, true);

      BOOST_FOREACH(std::string left, leftContexts)
      patternList.push_back(left + pattern);

      BOOST_FOREACH(std::string right, rightContexts)
      patternList.push_back(pattern + right);

      BOOST_FOREACH(std::string left, leftContexts)
      BOOST_FOREACH(std::string right, rightContexts)
      patternList.push_back(left + pattern + right);
    }
  }

  return patternList;
}

CorrectionPattern::CorrectionPattern(const std::string &line)
  : StatelessFeatureFunction(0, line), m_factors(1, 0), m_general(false),
    m_context(0), m_contextFactors(1, 0)
{
  std::cerr << "Initializing correction pattern feature.." << std::endl;
  ReadParameters();
}

void CorrectionPattern::SetParameter(const std::string& key, const std::string& value)
{
  if (key == "factor") {
    m_factors = std::vector<FactorType>(1, Scan<FactorType>(value));
  } else if (key == "context-factor") {
    m_contextFactors = std::vector<FactorType>(1, Scan<FactorType>(value));
  } else if (key == "general") {
    m_general = Scan<bool>(value);
  } else if (key == "context") {
    m_context = Scan<size_t>(value);
  } else {
    StatelessFeatureFunction::SetParameter(key, value);
  }
}

void CorrectionPattern::EvaluateWithSourceContext(const InputType &input
    , const InputPath &inputPath
    , const TargetPhrase &targetPhrase
    , const StackVec *stackVec
    , ScoreComponentCollection &scoreBreakdown
    , ScoreComponentCollection *estimatedFutureScore) const
{
  ComputeFeatures(input, inputPath, targetPhrase, &scoreBreakdown);
}

void CorrectionPattern::ComputeFeatures(
  const InputType &input,
  const InputPath &inputPath,
  const TargetPhrase& target,
  ScoreComponentCollection* accumulator) const
{
  const Phrase &source = inputPath.GetPhrase();

  std::vector<std::string> sourceTokens;
  for(size_t i = 0; i < source.GetSize(); ++i)
    sourceTokens.push_back(source.GetWord(i).GetString(m_factors, false));

  std::vector<std::string> targetTokens;
  for(size_t i = 0; i < target.GetSize(); ++i)
    targetTokens.push_back(target.GetWord(i).GetString(m_factors, false));

  std::vector<std::string> patternList = CreatePattern(sourceTokens, targetTokens, input, inputPath);
  for(size_t i = 0; i < patternList.size(); ++i)
    accumulator->PlusEquals(this, patternList[i], 1);

  /*
  BOOST_FOREACH(std::string w, sourceTokens)
    std::cerr << w << " ";
  std::cerr << std::endl;
  BOOST_FOREACH(std::string w, targetTokens)
    std::cerr << w << " ";
  std::cerr << std::endl;
  BOOST_FOREACH(std::string w, patternList)
    std::cerr << w << " ";
  std::cerr << std::endl << std::endl;
  */
}

bool CorrectionPattern::IsUseable(const FactorMask &mask) const
{
  bool ret = true;
  for(size_t i = 0; i < m_factors.size(); ++i)
    ret = ret && mask[m_factors[i]];
  for(size_t i = 0; i < m_contextFactors.size(); ++i)
    ret = ret && mask[m_contextFactors[i]];
  return ret;
}

}
<commit_msg>compile error with gcc 4.4.7<commit_after>#include <sstream>
#include "CorrectionPattern.h"
#include "moses/Phrase.h"
#include "moses/TargetPhrase.h"
#include "moses/InputPath.h"
#include "moses/Hypothesis.h"
#include "moses/ChartHypothesis.h"
#include "moses/ScoreComponentCollection.h"
#include "moses/TranslationOption.h"
#include "util/string_piece_hash.hh"
#include "util/exception.hh"

#include <functional>
#include <algorithm>

#include <boost/foreach.hpp>
#include <boost/algorithm/string.hpp>

#include "Diffs.h"

namespace Moses
{

using namespace std;

std::string MakePair(const std::string &s1, const std::string &s2, bool general)
{
  std::vector<std::string> sourceList;
  std::vector<std::string> targetList;

  if(general) {
    Diffs diffs = CreateDiff(s1, s2);

    size_t i = 0, j = 0;
    char lastType = 'm';

    std::string source, target;
    std::string match;

    int count = 1;

    BOOST_FOREACH(Diff type, diffs) {
      if(type == 'm') {
        if(lastType != 'm') {
          sourceList.push_back(source);
          targetList.push_back(target);
        }
        source.clear();
        target.clear();

        if(s1[i] == '+') {
          if(match.size() >= 3) {
            sourceList.push_back("(\\w{3,})·");
            std::string temp = "1";
            sprintf((char*)temp.c_str(), "%d", count);
            targetList.push_back("\\" + temp + "·");
            count++;
          } else {
            sourceList.push_back(match + "·");
            targetList.push_back(match + "·");
          }
          match.clear();
        } else
          match.push_back(s1[i]);

        i++;
        j++;
      } else if(type == 'd') {
        if(s1[i] == '+')
          source += "·";
        else
          source.push_back(s1[i]);
        i++;
      } else if(type == 'i') {
        if(s2[j] == '+')
          target += "·";
        else
          target.push_back(s2[j]);
        j++;
      }
      if(type != 'm' && !match.empty()) {
        if(match.size() >= 3) {
          sourceList.push_back("(\\w{3,})");
          std::string temp = "1";
          sprintf((char*)temp.c_str(), "%d", count);
          targetList.push_back("\\" + temp);
          count++;
        } else {
          sourceList.push_back(match);
          targetList.push_back(match);
        }

        match.clear();
      }

      lastType = type;
    }
    if(lastType != 'm') {
      sourceList.push_back(source);
      targetList.push_back(target);
    }

    if(!match.empty()) {
      if(match.size() >= 3) {
        sourceList.push_back("(\\w{3,})");
        std::string temp = "1";
        sprintf((char*)temp.c_str(), "%d", count);
        targetList.push_back("\\"+ temp);
        count++;
      } else {
        sourceList.push_back(match);
        targetList.push_back(match);
      }
    }
    match.clear();
  } else {
    std::string cs1 = s1;
    std::string cs2 = s2;
    boost::replace_all(cs1, "+", "·");
    boost::replace_all(cs2, "+", "·");

    sourceList.push_back(cs1);
    targetList.push_back(cs2);
  }

  std::stringstream out;
  out << "sub(«";
  out << boost::join(sourceList, "");
  out << "»,«";
  out << boost::join(targetList, "");
  out << "»)";

  return out.str();
}

std::string CorrectionPattern::CreateSinglePattern(const Tokens &s1, const Tokens &s2) const
{
  std::stringstream out;
  if(s1.empty()) {
    out << "ins(«" << boost::join(s2, "·") << "»)";
    return out.str();
  } else if(s2.empty()) {
    out << "del(«" << boost::join(s1, "·") << "»)";
    return out.str();
  } else {
    Tokens::value_type v1 = boost::join(s1, "+");
    Tokens::value_type v2 = boost::join(s2, "+");
    out << MakePair(v1, v2, m_general);
    return out.str();
  }
}

std::vector<std::string> GetContext(size_t pos,
                                    size_t len,
                                    size_t window,
                                    const InputType &input,
                                    const InputPath &inputPath,
                                    const std::vector<FactorType>& factorTypes,
                                    bool isRight)
{

  const Sentence& sentence = static_cast<const Sentence&>(input);
  const Range& range = inputPath.GetWordsRange();

  int leftPos  = range.GetStartPos() + pos - len - 1;
  int rightPos = range.GetStartPos() + pos;

  std::vector<std::string> contexts;

  for(int length = 1; length <= (int)window; ++length) {
    std::vector<std::string> current;
    if(!isRight) {
      for(int i = 0; i < length; i++) {
        if(leftPos - i >= 0) {
          current.push_back(sentence.GetWord(leftPos - i).GetString(factorTypes, false));
        } else {
          current.push_back("<s>");
        }
      }

      if(current.back() == "<s>" && current.size() >= 2 && current[current.size()-2] == "<s>")
        continue;

      std::reverse(current.begin(), current.end());
      contexts.push_back("left(«" + boost::join(current, "·") + "»)_");
    }
    if(isRight) {
      for(int i = 0; i < length; i++) {
        if(rightPos + i < (int)sentence.GetSize()) {
          current.push_back(sentence.GetWord(rightPos + i).GetString(factorTypes, false));
        } else {
          current.push_back("</s>");
        }
      }

      if(current.back() == "</s>" && current.size() >= 2 && current[current.size()-2] == "</s>")
        continue;

      contexts.push_back("_right(«" + boost::join(current, "·") + "»)");
    }
  }
  return contexts;
}

std::vector<std::string>
CorrectionPattern::CreatePattern(const Tokens &s1,
                                 const Tokens &s2,
                                 const InputType &input,
                                 const InputPath &inputPath) const
{

  Diffs diffs = CreateDiff(s1, s2);
  size_t i = 0, j = 0;
  char lastType = 'm';
  std::vector<std::string> patternList;
  Tokens source, target;
  BOOST_FOREACH(Diff type, diffs) {
    if(type == 'm') {
      if(lastType != 'm') {
        std::string pattern = CreateSinglePattern(source, target);
        patternList.push_back(pattern);

        if(m_context > 0) {
          std::vector<std::string> leftContexts =  GetContext(i, source.size(), m_context, input, inputPath, m_contextFactors, false);
          std::vector<std::string> rightContexts = GetContext(i, source.size(), m_context, input, inputPath, m_contextFactors, true);

          BOOST_FOREACH(std::string left, leftContexts)
          patternList.push_back(left + pattern);

          BOOST_FOREACH(std::string right, rightContexts)
          patternList.push_back(pattern + right);

          BOOST_FOREACH(std::string left, leftContexts)
          BOOST_FOREACH(std::string right, rightContexts)
          patternList.push_back(left + pattern + right);
        }
      }
      source.clear();
      target.clear();
      if(s1[i] != s2[j]) {
        source.push_back(s1[i]);
        target.push_back(s2[j]);
      }
      i++;
      j++;
    } else if(type == 'd') {
      source.push_back(s1[i]);
      i++;
    } else if(type == 'i') {
      target.push_back(s2[j]);
      j++;
    }
    lastType = type;
  }
  if(lastType != 'm') {
    std::string pattern = CreateSinglePattern(source, target);
    patternList.push_back(pattern);

    if(m_context > 0) {
      std::vector<std::string> leftContexts =  GetContext(i, source.size(), m_context, input, inputPath, m_contextFactors, false);
      std::vector<std::string> rightContexts = GetContext(i, source.size(), m_context, input, inputPath, m_contextFactors, true);

      BOOST_FOREACH(std::string left, leftContexts)
      patternList.push_back(left + pattern);

      BOOST_FOREACH(std::string right, rightContexts)
      patternList.push_back(pattern + right);

      BOOST_FOREACH(std::string left, leftContexts)
      BOOST_FOREACH(std::string right, rightContexts)
      patternList.push_back(left + pattern + right);
    }
  }

  return patternList;
}

CorrectionPattern::CorrectionPattern(const std::string &line)
  : StatelessFeatureFunction(0, line), m_factors(1, 0), m_general(false),
    m_context(0), m_contextFactors(1, 0)
{
  std::cerr << "Initializing correction pattern feature.." << std::endl;
  ReadParameters();
}

void CorrectionPattern::SetParameter(const std::string& key, const std::string& value)
{
  if (key == "factor") {
    m_factors = std::vector<FactorType>(1, Scan<FactorType>(value));
  } else if (key == "context-factor") {
    m_contextFactors = std::vector<FactorType>(1, Scan<FactorType>(value));
  } else if (key == "general") {
    m_general = Scan<bool>(value);
  } else if (key == "context") {
    m_context = Scan<size_t>(value);
  } else {
    StatelessFeatureFunction::SetParameter(key, value);
  }
}

void CorrectionPattern::EvaluateWithSourceContext(const InputType &input
    , const InputPath &inputPath
    , const TargetPhrase &targetPhrase
    , const StackVec *stackVec
    , ScoreComponentCollection &scoreBreakdown
    , ScoreComponentCollection *estimatedFutureScore) const
{
  ComputeFeatures(input, inputPath, targetPhrase, &scoreBreakdown);
}

void CorrectionPattern::ComputeFeatures(
  const InputType &input,
  const InputPath &inputPath,
  const TargetPhrase& target,
  ScoreComponentCollection* accumulator) const
{
  const Phrase &source = inputPath.GetPhrase();

  std::vector<std::string> sourceTokens;
  for(size_t i = 0; i < source.GetSize(); ++i)
    sourceTokens.push_back(source.GetWord(i).GetString(m_factors, false));

  std::vector<std::string> targetTokens;
  for(size_t i = 0; i < target.GetSize(); ++i)
    targetTokens.push_back(target.GetWord(i).GetString(m_factors, false));

  std::vector<std::string> patternList = CreatePattern(sourceTokens, targetTokens, input, inputPath);
  for(size_t i = 0; i < patternList.size(); ++i)
    accumulator->PlusEquals(this, patternList[i], 1);

  /*
  BOOST_FOREACH(std::string w, sourceTokens)
    std::cerr << w << " ";
  std::cerr << std::endl;
  BOOST_FOREACH(std::string w, targetTokens)
    std::cerr << w << " ";
  std::cerr << std::endl;
  BOOST_FOREACH(std::string w, patternList)
    std::cerr << w << " ";
  std::cerr << std::endl << std::endl;
  */
}

bool CorrectionPattern::IsUseable(const FactorMask &mask) const
{
  bool ret = true;
  for(size_t i = 0; i < m_factors.size(); ++i)
    ret = ret && mask[m_factors[i]];
  for(size_t i = 0; i < m_contextFactors.size(); ++i)
    ret = ret && mask[m_contextFactors[i]];
  return ret;
}

}
<|endoftext|>


<commit_before>#include <fstream>
#include <iostream>
#include <string>
#include <cstring>
#include <vector>

#include "mugen_item_content.h"
#include "mugen_section.h"
#include "mugen_reader.h"
#include "globals.h"

using namespace std;

// Check for Clsn
static bool checkClsn( const std::string &clsn ){
  return ( clsn.find("Clsn") != std::string::npos );
}

MugenReader::MugenReader( const char * file ){
    Global::debug(1) << "[mugen reader] Opening file '" << file << "'" << endl;
    ifile.open( file );
    if (!ifile){
        perror("cant open file");
    }
    myfile = string( file );
}

MugenReader::MugenReader( const string & file ){
    Global::debug(1) << "[mugen reader] Opening file '" << file << "'" << endl;
    ifile.open( file.c_str() );
    if (!ifile){
        perror("cant open file");
    }
    myfile = file;
}

MugenReader::~MugenReader(){
    ifile.close();

    for( std::vector< MugenSection * >::iterator i = collection.begin() ; i != collection.end() ; ++i ){
        if(*i)delete (*i);
    }

}

const std::vector< MugenSection * > & MugenReader::getCollection() throw(MugenException){

  if ( !ifile ){
      throw MugenException( std::string("Could not open file: ") + myfile );
  }

  std::string line;

  const char openbracket = '[';
  const char closebracket = ']';
  const char comment = ';';
  const char seperator = ',';
  const char colon = ':';
  const char equal = '=';
  const char quote = '"';
  const char * ignored = "\r\n";

  SearchState state = Section;
  // Our section and items
  MugenSection * sectionHolder = 0;
  // Marker for areas
  bool beginSection = false;

  while( !ifile.eof() ){
      getline( ifile, line );
      // Use to hold section or content in the options
      std::string contentHolder = "";
      // Place holder to put back all the grabbed content
      MugenItemContent *itemHolder = new MugenItemContent();
      // Needed to kill loop
      bool breakLoop = false;
      bool inQuote = false;
      bool getExpression = false;

      for( unsigned int i = 0; i < line.size(); ++i ){
	    // Go to work
	    switch( state ){
	      case Section:{
		// Done with this
		if( line[i] == comment ){
		  breakLoop = true;
		  break;
		}
		else if ( line[i] == ' ' && !beginSection )continue;
		//Start grabbing our section
		else if( line[i] == openbracket){
		  beginSection = true;
		}
		//End of our section store and go to ContentGet
		else if( line[i] == closebracket){
		  sectionHolder = new MugenSection();
		  sectionHolder->setHeader( contentHolder );
		  state = ContentGet;
		  beginSection = false;
		  breakLoop = true;
		  break;
		}
		else if( beginSection )contentHolder += line[i];
	      }
	      break;
	      case ContentGet:
	      default:{
		// Done with this
		if( line[i] == comment ){
		  if( itemHolder->hasItems() ){
		    if( !contentHolder.empty() ){
		      *itemHolder << contentHolder;
		    }
		    *sectionHolder << itemHolder;
		  }
		  breakLoop = true;
		  break;
		}
		// Check if we are near the end to kill it
		if( i+1 == line.size() && !contentHolder.empty() ){
		    if (line[i] != ' ' && !strchr(ignored, line[i])){
                        contentHolder += line[i];
                    }
		    *itemHolder << contentHolder;
		    *sectionHolder << itemHolder;
		    breakLoop = true;
		    break;
		}
		// Buh bye spaces
		if( line[i] == ' ' && !inQuote ){
		  continue;
		}
		// Start getting expression
		if( line[i] != ' ' && getExpression ){
		  inQuote = true;
		}
		// Check if this section is done, push it on the stack and reset everything
		if( line[i] == openbracket && !checkClsn( contentHolder ) && !itemHolder->hasItems() ){
		  addSection( sectionHolder );
		  beginSection = true;
		  state = Section;
		  contentHolder = "";
		  break;
		}
		// We got one push back the other and reset the holder to get the next
		else if( line[i] == colon || line[i] == seperator ){
		  if( !contentHolder.empty() ) *itemHolder << contentHolder;
		  contentHolder = "";
		}
		// Equal
		else if(line[i] == equal && !inQuote ){
		  if( !contentHolder.empty() ) *itemHolder << contentHolder;
		  getExpression = true;
		  contentHolder = "";
		}
		// We has a quote begin or end it
		else if( line[i] == quote ){
		  inQuote = !inQuote;
		}
		//Start grabbing our item
		else if (! strchr(ignored, line[i])){
                    contentHolder += line[i];
                }
	      }
	      break;
	    }
	    if( breakLoop )break;
      }
  }
  // Add in last section
  addSection( sectionHolder );

  return collection;
}

void MugenReader::addSection( MugenSection * section ){
  collection.push_back ( section );
}

<commit_msg>Updated reader to not skip lines in windows.<commit_after>#include <fstream>
#include <iostream>
#include <string>
#include <cstring>
#include <vector>

#include "mugen_item_content.h"
#include "mugen_section.h"
#include "mugen_reader.h"
#include "globals.h"

using namespace std;

// Check for Clsn
static bool checkClsn( const std::string &clsn ){
  return ( clsn.find("Clsn") != std::string::npos );
}

MugenReader::MugenReader( const char * file ){
    Global::debug(1) << "[mugen reader] Opening file '" << file << "'" << endl;
    ifile.open( file );
    if (!ifile){
        perror("cant open file");
    }
    myfile = string( file );
}

MugenReader::MugenReader( const string & file ){
    Global::debug(1) << "[mugen reader] Opening file '" << file << "'" << endl;
    ifile.open( file.c_str() );
    if (!ifile){
        perror("cant open file");
    }
    myfile = file;
}

MugenReader::~MugenReader(){
    ifile.close();

    for( std::vector< MugenSection * >::iterator i = collection.begin() ; i != collection.end() ; ++i ){
        if(*i)delete (*i);
    }

}

const std::vector< MugenSection * > & MugenReader::getCollection() throw(MugenException){

  if ( !ifile ){
      throw MugenException( std::string("Could not open file: ") + myfile );
  }

  std::string line;

  const char openbracket = '[';
  const char closebracket = ']';
  const char comment = ';';
  const char seperator = ',';
  const char colon = ':';
  const char equal = '=';
  const char quote = '"';
  const char * ignored = "\r\n";

  SearchState state = Section;
  // Our section and items
  MugenSection * sectionHolder = 0;
  // Marker for areas
  bool beginSection = false;

  while( !ifile.eof() ){
      getline( ifile, line );
      // Use to hold section or content in the options
      std::string contentHolder = "";
      // Place holder to put back all the grabbed content
      MugenItemContent *itemHolder = new MugenItemContent();
      // Needed to kill loop
      bool breakLoop = false;
      bool inQuote = false;
      bool getExpression = false;
      bool startComment = false;

      Global::debug(0) << line << endl;

      for( unsigned int i = 0; i < line.size(); ++i ){
	    // Go to work
	    switch( state ){
	      case Section:{
		// Done with this
		if( line[i] == comment ){
		  breakLoop = true;
		  break;
		}
		else if ( line[i] == ' ' && !beginSection )continue;
		//Start grabbing our section
		else if( line[i] == openbracket){
		  beginSection = true;
		}
		//End of our section store and go to ContentGet
		else if( line[i] == closebracket){
		  sectionHolder = new MugenSection();
		  sectionHolder->setHeader( contentHolder );
		  state = ContentGet;
		  beginSection = false;
		  breakLoop = true;
		  break;
		}
		else if( beginSection )contentHolder += line[i];
	      }
	      break;
	      case ContentGet:
	      default:{
		// Done with this
		if( line[i] == comment ){
		  startComment = true;
		}
		// Check if we are near the end to kill it
		if( i+1 == line.size() && !contentHolder.empty() ){
		    if (line[i] != ' ' && !strchr(ignored, line[i])){
                        contentHolder += line[i];
                    }
		    *itemHolder << contentHolder;
		    *sectionHolder << itemHolder;
		    breakLoop = true;
		    break;
		}
		// Buh bye spaces
		if( line[i] == ' ' && !inQuote ){
		  continue;
		}
		// Start getting expression
		if( line[i] != ' ' && getExpression ){
		  inQuote = true;
		}
		// Check if this section is done, push it on the stack and reset everything
		if( line[i] == openbracket && !checkClsn( contentHolder ) && !itemHolder->hasItems() ){
		  addSection( sectionHolder );
		  beginSection = true;
		  state = Section;
		  contentHolder = "";
		  break;
		}
		// We got one push back the other and reset the holder to get the next
		else if( line[i] == colon || line[i] == seperator ){
		  if( !contentHolder.empty() && !strchr(ignored, contentHolder[0]) ){
		      *itemHolder << contentHolder;
		  }
		  contentHolder = "";
		}
		// Equal
		else if(line[i] == equal && !inQuote ){
		  if( !contentHolder.empty() ) *itemHolder << contentHolder;
		  getExpression = true;
		  contentHolder = "";
		}
		// We has a quote begin or end it
		else if( line[i] == quote ){
		  inQuote = !inQuote;
		}
		//Start grabbing our item
		else if (!startComment && !strchr(ignored, line[i])){
                    contentHolder += line[i];
                }
	      }
	      break;
	    }
	    if( breakLoop )break;
      }
      if (state == ContentGet){
	    if( itemHolder->hasItems() ){
		if( !contentHolder.empty() && !strchr(ignored, contentHolder[0]) ){
		    *itemHolder << contentHolder;
		}
		*sectionHolder << itemHolder;
	    }
	}
  }
  // Add in last section
  addSection( sectionHolder );

  return collection;
}

void MugenReader::addSection( MugenSection * section ){
  collection.push_back ( section );
}

<|endoftext|>