<commit_before>// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <fstream>
#include <iostream>
#include <map>

#include <spii/auto_diff_term.h>
#include <spii/function.h>
#include <spii/solver.h>
#include <spii/term.h>

#include "simhashweightslossfunctor.hpp"

using namespace std;

// String split functionality.
template<typename Out>
void split(const std::string &s, char delim, Out result) {
  std::stringstream ss;
  ss.str(s);
  std::string item;
  while (std::getline(ss, item, delim)) {
    *(result++) = item;
  }
}

// The code expects the following files to be present inside the data directory
// (which is passed in as first argument):
//
//  functions.txt - a text file formed by concatenating the output of the
//                  functionfingerprints tool in verbose mode. Each line starts
//                  with [file_id]:[address], and is followed by the various
//                  features that make up the function.
//  attract.txt   - a file with pairs of [file_id]:[address] [file_id]:[address]
//                  indicating which functions should be the same.
//  repulse.txt   - a file with pairs of [file_id]:[address] [file_id]:[address]
//                  indicating which functions should NOT be the same
//

int main(int argc, char** argv) {
  if (argc != 2) {
    printf("Use labelled and unlablled data to train a weights.txt file.\n");
    printf("Usage: %s <data directory>\n", argv[0]);
    printf("Refer to the source code of this utility for detailed usage.\n");
    return -1;
  }

  // The code will perform two iterations over functions.txt, the first to
  // extract all the features, the second to build the data structures required
  // for the SimHashWeightLossFunction.

  std::string directory(argv[1]);
  std::ifstream functionsfile(directory + "/functions.txt");
  if (!functionsfile) {
    printf("Failed to open functions.txt in data directory.\n");
    return -1;
  }

  // We want features sorted and de-duplicated in the end, so use a set.
  std::set<FeatureHash> all_features;
  std::string line;
  while (std::getline(functionsfile, line)) {
    std::vector<std::string> tokens;
    split(line, ' ', std::back_inserter(tokens));
    for (uint32_t index = 1; index < tokens.size(); ++index) {
      std::string& token = tokens[index];
      std::string first_half_string;
      std::string second_half_string;
      if (token.c_str()[2] == '.') {
        std::string first_half_string = token.substr(3, 16+3);
        std::string second_half_string = token.substr(16+3, string::npos);
      } else {
        std::string first_half_string = token.substr(0, 16);
        std::string second_half_string = token.substr(16, string::npos);
      }
      const char* first_half = first_half_string.c_str();
      const char* second_half = second_half_string.c_str();
      uint64_t hashA = strtoull(first_half, nullptr, 16);
      uint64_t hashB = strtoull(second_half, nullptr, 16);
      printf("%s - %16.16lx%16.16lx\n", token.c_str(), hashA, hashB);
    }
  }
}
<commit_msg>Code to parse all the data into the needed format<commit_after>// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <fstream>
#include <iostream>
#include <map>

#include <spii/auto_diff_term.h>
#include <spii/function.h>
#include <spii/solver.h>
#include <spii/term.h>

#include "simhashweightslossfunctor.hpp"

using namespace std;

// String split functionality.
template<typename Out>
void split(const std::string &s, char delim, Out result) {
  std::stringstream ss;
  ss.str(s);
  std::string item;
  while (std::getline(ss, item, delim)) {
    *(result++) = item;
  }
}

bool FileToLineTokens(const std::string& filename,
  std::vector<std::vector<std::string>>* tokenized_lines) {
  std::ifstream inputfile(filename);
  if (!inputfile) {
    printf("Failed to open inputfile %s.\n", filename.c_str());
    return false;
  }

  uint32_t line_index = 0;
  // We want features sorted and de-duplicated in the end, so use a set.
  std::string line;
  while (std::getline(functionsfile, line)) {
    std::vector<std::string> tokens;
    split(line, ' ', std::back_inserter(tokens));
    tokenized_lines->push_back(tokens);
  }
  return true;
}

FeatureHash StringToFeatureHash(const std::string& hash_as_string) {
  const std::string& token = hash_as_string;
  std::string first_half_string;
  std::string second_half_string;
  if (token.c_str()[2] == '.') {
    std::string first_half_string = token.substr(3, 16+3);
    std::string second_half_string = token.substr(16+3, string::npos);
  } else {
     std::string first_half_string = token.substr(0, 16);
     std::string second_half_string = token.substr(16, string::npos);
  }
  const char* first_half = first_half_string.c_str();
  const char* second_half = second_half_string.c_str();
  uint64_t hashA = strtoull(first_half, nullptr, 16);
  uint64_t hashB = strtoull(second_half, nullptr, 16);
  return std::make_pair(hashA, hashB);
}

void ReadFeatureSet(const std::vector<std::vector<std::string>>& inputlines,
  std::set<FeatureHash>* result) {
  for (const std::vector<std::string>& line : inputlines) {
    for (uint32_t index = 1; index < line.size(); ++index) {
      result->insert(StringToFeatureHash(tokens[index]);
    }
  }
}

// The code expects the following files to be present inside the data directory
// (which is passed in as first argument):
//
//  functions.txt - a text file formed by concatenating the output of the
//                  functionfingerprints tool in verbose mode. Each line starts
//                  with [file_id]:[address], and is followed by the various
//                  features that make up the function.
//  attract.txt   - a file with pairs of [file_id]:[address] [file_id]:[address]
//                  indicating which functions should be the same.
//  repulse.txt   - a file with pairs of [file_id]:[address] [file_id]:[address]
//                  indicating which functions should NOT be the same
//

int main(int argc, char** argv) {
  if (argc != 2) {
    printf("Use labelled and unlablled data to train a weights.txt file.\n");
    printf("Usage: %s <data directory>\n", argv[0]);
    printf("Refer to the source code of this utility for detailed usage.\n");
    return -1;
  }

  // Read the contents of functions.txt.
  std::string functionsfilename = directory + "/functions.txt";
  std::vector<std::vector<std::string>> file_contents;
  if (!FileToLineTokens(functionsfilename, &file_contents)) {
    return -1;
  }

  // Read all the features, place them in a vector, and populate a map that maps
  // FeatureHash to vector index.
  std::set<FeatureHash> result;
  ReadFeatureSet(file_contents, &result);
  std::vector<FeatureHash> all_features_vector;
  std::map<FeatureHash, uint32_t> feature_to_vector_index;
  uint32_t index = 0;
  for (const FeatureHash& feature : all_features) {
    all_features_vector.push_back(feauture);
    feature_to_vector_index[feature] = index;
    ++index;
  }

  // FunctionFeatures are a vector of uint32_t.
  std::vector<FunctionFeatures> all_functions;
  std::map<std::string, uint32_t> function_to_index;
  index = 0;
  all_functions.resize(file_contents.size());
  for (const std::vector<std::string>& line : file_contents) {
    function_to_index[line[0]] = index;
    for (uint32_t i = 1; i < line.size(); ++i) {
      FeatureHash hash = StringToFeatureHash(line[i]);
      all_functions[index].push_back(feature_to_vector_index[hash]);
    }
    ++index;
  }
  // Feature vector and function vector have been loaded. Now load the attraction
  // and repulsion set.
  std::vector<std::vector<std::string>> attract_file_contents;
  if (!FileToLineTokens(directory + "/attract.txt", &attract_file_contents)) {
    return -1;
  }

  std::vector<std::vector<std::string>> repulse_file_contents;
  if (!FileToLineTokens(directory + "/repulse.txt", &attract_file_contents)) {
    return -1;
  }

  std::vector<std::pair<uint32_t, uint32_t>> attractionset;
  for (const std::vector<std::string>& line : attract_file_contents) {
    attractionset.push_back(std::make_pair(
      function_to_index[line[0]],
      function_to_index[line[1]]));
  }

  for (const std::vector<std::string>& line : repulse_file_contents) {
    repulsionset.push_back(std::make_pair(
      function_to_index[line[0]],
      function_to_index[line[1]]));
  }
}

<|endoftext|>


<commit_before>// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

<commit_msg>Delete dllmain.cpp<commit_after><|endoftext|>


<commit_before>/*
Copyright (c) 2013 Stijn "tcpie" Hinterding (contact: contact at tcpie dot eu)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "stdafx.h"
#include "Thread.h"
#include "Process.h"
#include "MemoryRegion.h"

#define PROCESS_TINKER (PROCESS_VM_OPERATION | PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_WRITE | PROCESS_VM_READ)
#define THREAD_TINKER (THREAD_GET_CONTEXT    | THREAD_SET_CONTEXT	 | THREAD_SUSPEND_RESUME)

#define QUERY_WIN32_START_ADDR 9

namespace tcpie { namespace wincore {

typedef int (WINAPI *NTQUERYINFORMATIONTHREAD)(HANDLE, LONG, PVOID, ULONG, PULONG);

std::map<DWORD, Thread*>* Thread::thread_pool = new std::map<DWORD, Thread*>();

Thread::Thread(THREADENTRY32 ThreadInfo)
{
	this->thread_info = ThreadInfo;
	this->id = ThreadInfo.th32ThreadID;
	this->handle = OpenThread(THREAD_TINKER, false, this->id);
	this->start_address = NULL;
	this->owner = NULL;
	this->owner_id = ThreadInfo.th32OwnerProcessID;
}

Thread::~Thread()
{
	CloseHandle(this->handle);

	if (this->owner != NULL)
	{
		delete this->owner;
	}
}

bool Thread::HasTerminated() const
{
	DWORD result = WaitForSingleObject(this->handle, 0);

	if (result == WAIT_OBJECT_0)
	{
		return true;
	}

	return false;
}

const Process* Thread::GetOwningProcess()
{
	if (this->owner == NULL)
	{
		this->owner = Process::FindProcessById(this->owner_id);
	}

	return this->owner;
}

void Thread::PushToStack(const std::vector<void*>* Args)
{
	CONTEXT curr_context = this->GetContext();
	curr_context.ContextFlags = CONTEXT_ALL | CONTEXT_DEBUG_REGISTERS;

	curr_context.Esp -= Args->size() * sizeof(DWORD*);

	if (this->GetOwningProcess()->GetId() == Process::GetCurrentProcessId())
	{
		void** stack = (void**)curr_context.Esp;
		DWORD old_prot = 0;

		bool success = VirtualProtect((void*)stack, Args->size(), PAGE_READWRITE, &old_prot) != 0;

		for (size_t i = 0; i < Args->size(); i++) // We push right-to-left
		{
			stack[i] = Args->at(i);
		}
	}
	else
	{
		MemoryRegion* mem_region = this->GetOwningProcess()->WriteMemory((void*)&(*Args)[0], Args->size() * sizeof(DWORD*), (void*)curr_context.Esp);
	}

	curr_context.Esp -= sizeof(DWORD*);

	this->SetContext(curr_context);
}

void Thread::Suspend() const
{
	SuspendThread(this->handle);
}

void Thread::Resume() const
{
	ResumeThread(this->handle);
}

CONTEXT Thread::GetContext() const
{
	CONTEXT ret;
	ret.ContextFlags = CONTEXT_ALL | CONTEXT_DEBUG_REGISTERS;
	GetThreadContext(this->handle, &ret);

	return ret;
}

bool Thread::SetContext(CONTEXT value) const
{
	return SetThreadContext(this->handle, &value) != 0;
}

DWORD Thread::GetCurrentThreadId()
{
	HANDLE curr_handle = ::GetCurrentThread();
	DWORD id = GetThreadId(curr_handle);
	CloseHandle(curr_handle);

	return id;
}

Thread* Thread::GetCurrentThread()
{
	HANDLE curr_handle = ::GetCurrentThread();
	DWORD id = GetThreadId(curr_handle);
	CloseHandle(curr_handle);

	return Thread::FindThreadById(id);
}

Thread* Thread::FindOldest(const std::vector<Thread*>* Threads)
{
	Thread* oldest_thread = NULL;
	FILETIME oldest_time;

	for (unsigned int i = 0; i < Threads->size(); i++)
	{
		FILETIME creation_time;
		FILETIME exit_time;
		FILETIME kernel_time;
		FILETIME user_time;

		bool success = GetThreadTimes((HANDLE)Threads->at(i)->GetId(), &creation_time, &exit_time, &kernel_time, &user_time) != 0;

		if (oldest_thread == NULL || CompareFileTime(&oldest_time, &creation_time) == 1)
		{
			oldest_time = creation_time;
			oldest_thread = Threads->at(i);
		}
	}

	return oldest_thread;
}

Thread* Thread::FindThreadById(DWORD ThreadId)
{
	Thread* ret_thread = NULL;

	if (Thread::thread_pool->size() != 0)
	{
		try
		{
			ret_thread = Thread::thread_pool->at(ThreadId);

			return ret_thread;
		}
		catch (...)
		{
		}
	}

	std::vector<Thread*>* threads = Thread::GetSystemThreads();
	Thread::thread_pool->clear();

	for (size_t i = 0; i < threads->size(); i++)
	{
		Thread::thread_pool->insert(std::pair<DWORD, Thread*>(threads->at(i)->GetId(), threads->at(i)));
	}

	delete threads;

	try
	{
		ret_thread = Thread::thread_pool->at(ThreadId);

		return ret_thread;
	}
	catch (...)
	{
	}

	return NULL;
}

std::vector<Thread*>* Thread::GetSystemThreads()
{
	std::vector<Thread*>* ret = new std::vector<Thread*>();

	THREADENTRY32 te;
    HANDLE thSnapshot;
    int returnValue, procFound = 0;

    thSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);

    if(thSnapshot == INVALID_HANDLE_VALUE)
    {
        return NULL;
    }

    te.dwSize = sizeof(THREADENTRY32);

    returnValue = Thread32First(thSnapshot, &te);

    while(returnValue)
    {
		ret->push_back(new Thread(te));

        returnValue =  Thread32Next(thSnapshot,&te);
        te.dwSize = sizeof(THREADENTRY32);
    }

    CloseHandle(thSnapshot);

	return ret;
}

void* Thread::GetStartAddress()
{
	if (this->start_address != NULL)
	{
		return this->start_address;
	}

	HANDLE ThreadHandle = OpenThread(THREAD_QUERY_INFORMATION, false, this->id);
	int ntStatus;
    void* startAddr = NULL;
    HANDLE currProc, newThreadHandle;

	// NtQueryInformationThread is not documented, so we have to do it the hard way...
    NTQUERYINFORMATIONTHREAD NtQueryInformationThread = (NTQUERYINFORMATIONTHREAD)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQueryInformationThread");

    if (NtQueryInformationThread == INVALID_HANDLE_VALUE)
    {
		return 0;
	}

    currProc = GetCurrentProcess();

    if (DuplicateHandle(currProc, ThreadHandle, currProc, &newThreadHandle, THREAD_QUERY_INFORMATION, FALSE, 0))
    {
        ntStatus = NtQueryInformationThread(newThreadHandle, QUERY_WIN32_START_ADDR, &startAddr, sizeof(void*), NULL);

        if (ntStatus != 0)
        {
            CloseHandle(newThreadHandle);

            return 0;
		}

        CloseHandle(newThreadHandle);
    }

    return startAddr;
}

Thread* Thread::Create(const Process* HostProcess, void* StartAddress, void* Parameter)
{
	DWORD thread_id = 0;

	if (HostProcess != Process::GetCurrentProcess())
	{
		HANDLE proc_handle = OpenProcess(PROCESS_TINKER, false, HostProcess->GetId());

		CreateRemoteThread(proc_handle, NULL, 0, (LPTHREAD_START_ROUTINE)StartAddress, (LPVOID)Parameter, 0, &thread_id);
	}
	else
	{
		CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)StartAddress, (LPVOID)Parameter, 0, &thread_id);
	}

	return Thread::FindThreadById(thread_id);
}

} }
<commit_msg>small changes to FindThreadById()<commit_after>/*
Copyright (c) 2013 Stijn "tcpie" Hinterding (contact: contact at tcpie dot eu)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "stdafx.h"
#include "Thread.h"
#include "Process.h"
#include "MemoryRegion.h"

#define PROCESS_TINKER (PROCESS_VM_OPERATION | PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_WRITE | PROCESS_VM_READ)
#define THREAD_TINKER (THREAD_GET_CONTEXT    | THREAD_SET_CONTEXT	 | THREAD_SUSPEND_RESUME)

#define QUERY_WIN32_START_ADDR 9

namespace tcpie { namespace wincore {

typedef int (WINAPI *NTQUERYINFORMATIONTHREAD)(HANDLE, LONG, PVOID, ULONG, PULONG);

std::map<DWORD, Thread*>* Thread::thread_pool = new std::map<DWORD, Thread*>();

Thread::Thread(THREADENTRY32 ThreadInfo)
{
	this->thread_info = ThreadInfo;
	this->id = ThreadInfo.th32ThreadID;
	this->handle = OpenThread(THREAD_TINKER, false, this->id);
	this->start_address = NULL;
	this->owner = NULL;
	this->owner_id = ThreadInfo.th32OwnerProcessID;
}

Thread::~Thread()
{
	CloseHandle(this->handle);

	if (this->owner != NULL)
	{
		delete this->owner;
	}
}

bool Thread::HasTerminated() const
{
	DWORD result = WaitForSingleObject(this->handle, 0);

	if (result == WAIT_OBJECT_0)
	{
		return true;
	}

	return false;
}

const Process* Thread::GetOwningProcess()
{
	if (this->owner == NULL)
	{
		this->owner = Process::FindProcessById(this->owner_id);
	}

	return this->owner;
}

void Thread::PushToStack(const std::vector<void*>* Args)
{
	CONTEXT curr_context = this->GetContext();
	curr_context.ContextFlags = CONTEXT_ALL | CONTEXT_DEBUG_REGISTERS;

	curr_context.Esp -= Args->size() * sizeof(DWORD*);

	if (this->GetOwningProcess()->GetId() == Process::GetCurrentProcessId())
	{
		void** stack = (void**)curr_context.Esp;
		DWORD old_prot = 0;

		bool success = VirtualProtect((void*)stack, Args->size(), PAGE_READWRITE, &old_prot) != 0;

		for (size_t i = 0; i < Args->size(); i++) // We push right-to-left
		{
			stack[i] = Args->at(i);
		}
	}
	else
	{
		MemoryRegion* mem_region = this->GetOwningProcess()->WriteMemory((void*)&(*Args)[0], Args->size() * sizeof(DWORD*), (void*)curr_context.Esp);
	}

	curr_context.Esp -= sizeof(DWORD*);

	this->SetContext(curr_context);
}

void Thread::Suspend() const
{
	SuspendThread(this->handle);
}

void Thread::Resume() const
{
	ResumeThread(this->handle);
}

CONTEXT Thread::GetContext() const
{
	CONTEXT ret;
	ret.ContextFlags = CONTEXT_ALL | CONTEXT_DEBUG_REGISTERS;
	GetThreadContext(this->handle, &ret);

	return ret;
}

bool Thread::SetContext(CONTEXT value) const
{
	return SetThreadContext(this->handle, &value) != 0;
}

DWORD Thread::GetCurrentThreadId()
{
	HANDLE curr_handle = ::GetCurrentThread();
	DWORD id = GetThreadId(curr_handle);
	CloseHandle(curr_handle);

	return id;
}

Thread* Thread::GetCurrentThread()
{
	HANDLE curr_handle = ::GetCurrentThread();
	DWORD id = GetThreadId(curr_handle);
	CloseHandle(curr_handle);

	return Thread::FindThreadById(id);
}

Thread* Thread::FindOldest(const std::vector<Thread*>* Threads)
{
	Thread* oldest_thread = NULL;
	FILETIME oldest_time;

	for (unsigned int i = 0; i < Threads->size(); i++)
	{
		FILETIME creation_time;
		FILETIME exit_time;
		FILETIME kernel_time;
		FILETIME user_time;

		bool success = GetThreadTimes((HANDLE)Threads->at(i)->GetId(), &creation_time, &exit_time, &kernel_time, &user_time) != 0;

		if (oldest_thread == NULL || CompareFileTime(&oldest_time, &creation_time) == 1)
		{
			oldest_time = creation_time;
			oldest_thread = Threads->at(i);
		}
	}

	return oldest_thread;
}

Thread* Thread::FindThreadById(DWORD ThreadId)
{
	Thread* ret_thread = NULL;

	try
	{
		ret_thread = Thread::thread_pool->at(ThreadId);

		return ret_thread;
	}
	catch (...)
	{
	}

	std::vector<Thread*>* threads = Thread::GetSystemThreads();
	Thread::thread_pool->clear();

	for (size_t i = 0; i < threads->size(); i++)
	{
		Thread::thread_pool->insert(std::pair<DWORD, Thread*>(threads->at(i)->GetId(), threads->at(i)));
	}

	delete threads;

	try
	{
		ret_thread = Thread::thread_pool->at(ThreadId);

		return ret_thread;
	}
	catch (...)
	{
	}

	return NULL;
}

std::vector<Thread*>* Thread::GetSystemThreads()
{
	std::vector<Thread*>* ret = new std::vector<Thread*>();

	THREADENTRY32 te;
    HANDLE thSnapshot;
    int returnValue, procFound = 0;

    thSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);

    if(thSnapshot == INVALID_HANDLE_VALUE)
    {
        return NULL;
    }

    te.dwSize = sizeof(THREADENTRY32);

    returnValue = Thread32First(thSnapshot, &te);

    while(returnValue)
    {
		ret->push_back(new Thread(te));

        returnValue =  Thread32Next(thSnapshot,&te);
        te.dwSize = sizeof(THREADENTRY32);
    }

    CloseHandle(thSnapshot);

	return ret;
}

void* Thread::GetStartAddress()
{
	if (this->start_address != NULL)
	{
		return this->start_address;
	}

	HANDLE ThreadHandle = OpenThread(THREAD_QUERY_INFORMATION, false, this->id);
	int ntStatus;
    void* startAddr = NULL;
    HANDLE currProc, newThreadHandle;

	// NtQueryInformationThread is not documented, so we have to do it the hard way...
    NTQUERYINFORMATIONTHREAD NtQueryInformationThread = (NTQUERYINFORMATIONTHREAD)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQueryInformationThread");

    if (NtQueryInformationThread == INVALID_HANDLE_VALUE)
    {
		return 0;
	}

    currProc = GetCurrentProcess();

    if (DuplicateHandle(currProc, ThreadHandle, currProc, &newThreadHandle, THREAD_QUERY_INFORMATION, FALSE, 0))
    {
        ntStatus = NtQueryInformationThread(newThreadHandle, QUERY_WIN32_START_ADDR, &startAddr, sizeof(void*), NULL);

        if (ntStatus != 0)
        {
            CloseHandle(newThreadHandle);

            return 0;
		}

        CloseHandle(newThreadHandle);
    }

    return startAddr;
}

Thread* Thread::Create(const Process* HostProcess, void* StartAddress, void* Parameter)
{
	DWORD thread_id = 0;

	if (HostProcess != Process::GetCurrentProcess())
	{
		HANDLE proc_handle = OpenProcess(PROCESS_TINKER, false, HostProcess->GetId());

		CreateRemoteThread(proc_handle, NULL, 0, (LPTHREAD_START_ROUTINE)StartAddress, (LPVOID)Parameter, 0, &thread_id);
	}
	else
	{
		CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)StartAddress, (LPVOID)Parameter, 0, &thread_id);
	}

	return Thread::FindThreadById(thread_id);
}

} }
<|endoftext|>


<commit_before>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 1999-2009 Soeren Sonnenburg
 * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
 */

#include <shogun/classifier/svm/LibSVM.h>
#include <shogun/io/SGIO.h>
#include <shogun/labels/BinaryLabels.h>

using namespace shogun;

CLibSVM::CLibSVM()
: CSVM(), model(NULL), solver_type(LIBSVM_C_SVC)
{
}

CLibSVM::CLibSVM(LIBSVM_SOLVER_TYPE st)
: CSVM(), model(NULL), solver_type(st)
{
}

CLibSVM::CLibSVM(float64_t C, CKernel* k, CLabels* lab, LIBSVM_SOLVER_TYPE st)
: CSVM(C, k, lab), model(NULL), solver_type(st)
{
	problem = svm_problem();
}

CLibSVM::~CLibSVM()
{
}

bool CLibSVM::train_machine(CFeatures* data)
{
	struct svm_node* x_space;

	ASSERT(m_labels && m_labels->get_num_labels())
	ASSERT(m_labels->get_label_type() == LT_BINARY)

	if (data)
	{
		if (m_labels->get_num_labels() != data->get_num_vectors())
		{
			SG_ERROR("%s::train_machine(): Number of training vectors (%d) does"
					" not match number of labels (%d)\n", get_name(),
					data->get_num_vectors(), m_labels->get_num_labels());
		}
		kernel->init(data, data);
	}

	problem.l=m_labels->get_num_labels();
	SG_INFO("%d trainlabels\n", problem.l)

	// set linear term
	if (m_linear_term.vlen>0)
	{
		if (m_labels->get_num_labels()!=m_linear_term.vlen)
            SG_ERROR("Number of training vectors does not match length of linear term\n")

		// set with linear term from base class
		problem.pv = get_linear_term_array();
	}
	else
	{
		// fill with minus ones
		problem.pv = SG_MALLOC(float64_t, problem.l);

		for (int i=0; i!=problem.l; i++)
			problem.pv[i] = -1.0;
	}

	problem.y=SG_MALLOC(float64_t, problem.l);
	problem.x=SG_MALLOC(struct svm_node*, problem.l);
    problem.C=SG_MALLOC(float64_t, problem.l);

	x_space=SG_MALLOC(struct svm_node, 2*problem.l);

	for (int32_t i=0; i<problem.l; i++)
	{
		problem.y[i]=((CBinaryLabels*) m_labels)->get_label(i);
		problem.x[i]=&x_space[2*i];
		x_space[2*i].index=i;
		x_space[2*i+1].index=-1;
	}

	int32_t weights_label[2]={-1,+1};
	float64_t weights[2]={1.0,get_C2()/get_C1()};

	ASSERT(kernel && kernel->has_features())
	ASSERT(kernel->get_num_vec_lhs()==problem.l)

	switch (solver_type)
	{
	case LIBSVM_C_SVC:
		param.svm_type=C_SVC;
		break;
	case LIBSVM_NU_SVC:
		param.svm_type=NU_SVC;
		break;
	default:
		SG_ERROR("%s::train_machine(): Unknown solver type!\n", get_name());
		break;
	}

	param.kernel_type = LINEAR;
	param.degree = 3;
	param.gamma = 0;	// 1/k
	param.coef0 = 0;
	param.nu = get_nu();
	param.kernel=kernel;
	param.cache_size = kernel->get_cache_size();
	param.max_train_time = m_max_train_time;
	param.C = get_C1();
	param.eps = epsilon;
	param.p = 0.1;
	param.shrinking = 1;
	param.nr_weight = 2;
	param.weight_label = weights_label;
	param.weight = weights;
	param.use_bias = get_bias_enabled();

	const char* error_msg = svm_check_parameter(&problem, &param);

	if(error_msg)
		SG_ERROR("Error: %s\n",error_msg)

	model = svm_train(&problem, &param);

	if (model)
	{
		ASSERT(model->nr_class==2)
		ASSERT((model->l==0) || (model->l>0 && model->SV && model->sv_coef && model->sv_coef[0]))

		int32_t num_sv=model->l;

		create_new_model(num_sv);
		CSVM::set_objective(model->objective);

		float64_t sgn=model->label[0];

		set_bias(-sgn*model->rho[0]);

		for (int32_t i=0; i<num_sv; i++)
		{
			set_support_vector(i, (model->SV[i])->index);
			set_alpha(i, sgn*model->sv_coef[0][i]);
		}

		SG_FREE(problem.x);
		SG_FREE(problem.y);
		SG_FREE(problem.pv);
        SG_FREE(problem.C);

		SG_FREE(x_space);

		svm_destroy_model(model);
		model=NULL;
		return true;
	}
	else
		return false;
}
<commit_msg>Minor formating<commit_after>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 1999-2009 Soeren Sonnenburg
 * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
 */

#include <shogun/classifier/svm/LibSVM.h>
#include <shogun/io/SGIO.h>
#include <shogun/labels/BinaryLabels.h>

using namespace shogun;

CLibSVM::CLibSVM()
: CSVM(), model(NULL), solver_type(LIBSVM_C_SVC)
{
}

CLibSVM::CLibSVM(LIBSVM_SOLVER_TYPE st)
: CSVM(), model(NULL), solver_type(st)
{
}

CLibSVM::CLibSVM(float64_t C, CKernel* k, CLabels* lab, LIBSVM_SOLVER_TYPE st)
: CSVM(C, k, lab), model(NULL), solver_type(st)
{
	problem = svm_problem();
}

CLibSVM::~CLibSVM()
{
}

bool CLibSVM::train_machine(CFeatures* data)
{
	struct svm_node* x_space;

	ASSERT(m_labels && m_labels->get_num_labels())
	ASSERT(m_labels->get_label_type() == LT_BINARY)

	if (data)
	{
		if (m_labels->get_num_labels() != data->get_num_vectors())
		{
			SG_ERROR("%s::train_machine(): Number of training vectors (%d) does"
					" not match number of labels (%d)\n", get_name(),
					data->get_num_vectors(), m_labels->get_num_labels());
		}
		kernel->init(data, data);
	}

	problem.l=m_labels->get_num_labels();
	SG_INFO("%d trainlabels\n", problem.l)

	// set linear term
	if (m_linear_term.vlen>0)
	{
		if (m_labels->get_num_labels()!=m_linear_term.vlen)
			SG_ERROR("Number of training vectors does not match length of linear term\n")

		// set with linear term from base class
		problem.pv = get_linear_term_array();
	}
	else
	{
		// fill with minus ones
		problem.pv = SG_MALLOC(float64_t, problem.l);

		for (int i=0; i!=problem.l; i++)
			problem.pv[i] = -1.0;
	}

	problem.y=SG_MALLOC(float64_t, problem.l);
	problem.x=SG_MALLOC(struct svm_node*, problem.l);
	problem.C=SG_MALLOC(float64_t, problem.l);

	x_space=SG_MALLOC(struct svm_node, 2*problem.l);

	for (int32_t i=0; i<problem.l; i++)
	{
		problem.y[i]=((CBinaryLabels*) m_labels)->get_label(i);
		problem.x[i]=&x_space[2*i];
		x_space[2*i].index=i;
		x_space[2*i+1].index=-1;
	}

	int32_t weights_label[2]={-1,+1};
	float64_t weights[2]={1.0,get_C2()/get_C1()};

	ASSERT(kernel && kernel->has_features())
	ASSERT(kernel->get_num_vec_lhs()==problem.l)

	switch (solver_type)
	{
	case LIBSVM_C_SVC:
		param.svm_type=C_SVC;
		break;
	case LIBSVM_NU_SVC:
		param.svm_type=NU_SVC;
		break;
	default:
		SG_ERROR("%s::train_machine(): Unknown solver type!\n", get_name());
		break;
	}

	param.kernel_type = LINEAR;
	param.degree = 3;
	param.gamma = 0;	// 1/k
	param.coef0 = 0;
	param.nu = get_nu();
	param.kernel=kernel;
	param.cache_size = kernel->get_cache_size();
	param.max_train_time = m_max_train_time;
	param.C = get_C1();
	param.eps = epsilon;
	param.p = 0.1;
	param.shrinking = 1;
	param.nr_weight = 2;
	param.weight_label = weights_label;
	param.weight = weights;
	param.use_bias = get_bias_enabled();

	const char* error_msg = svm_check_parameter(&problem, &param);

	if(error_msg)
		SG_ERROR("Error: %s\n",error_msg)

	model = svm_train(&problem, &param);

	if (model)
	{
		ASSERT(model->nr_class==2)
		ASSERT((model->l==0) || (model->l>0 && model->SV && model->sv_coef && model->sv_coef[0]))

		int32_t num_sv=model->l;

		create_new_model(num_sv);
		CSVM::set_objective(model->objective);

		float64_t sgn=model->label[0];

		set_bias(-sgn*model->rho[0]);

		for (int32_t i=0; i<num_sv; i++)
		{
			set_support_vector(i, (model->SV[i])->index);
			set_alpha(i, sgn*model->sv_coef[0][i]);
		}

		SG_FREE(problem.x);
		SG_FREE(problem.y);
		SG_FREE(problem.pv);
		SG_FREE(problem.C);

		SG_FREE(x_space);

		svm_destroy_model(model);
		model=NULL;
		return true;
	}
	else
		return false;
}
<|endoftext|>


<commit_before>/***************************************************************************
 *  The Kernel-Machine Library                                             *
 *  Copyright (C) 2004--2006 by Rutger W. ter Borg                         *
 *                                                                         *
 *  This library is free software; you can redistribute it and/or          *
 *  modify it under the terms of the GNU Lesser General Public             *
 *  License as published by the Free Software Foundation; either           *
 *  version 2.1 of the License, or (at your option) any later version.     *
 *                                                                         *
 *  This library is distributed in the hope that it will be useful,        *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU      *
 *  Lesser General Public License for more details.                        *
 *                                                                         *
 *  You should have received a copy of the GNU Lesser General Public       *
 *  License along with this library; if not, write to the Free Software    *
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  *
 ***************************************************************************/

#ifndef KERNEL_MACHINE_HPP
#define KERNEL_MACHINE_HPP

#include <boost/lambda/bind.hpp>
#include <boost/utility/enable_if.hpp>
#include <kml/regression.hpp>
#include <kml/classification.hpp>
#include <kml/ranking.hpp>
#include <vector>

#include <boost/serialization/access.hpp>
#include <boost/serialization/tracking.hpp>

//#include <kml/determinate.hpp>

// for the property traits
#include <boost/property_map.hpp>

namespace lambda = boost::lambda;

namespace kml {

template< typename Problem, typename Kernel, typename PropertyMap, class Enable=void >
class kernel_machine {}
;

/*! \brief Regression kernel machine

	This is used as a base for various regression kernel machines, for example kml::rvm.

	\param Problem a regression problem type, for example kml::regression
	\param Kernel kernel to be used by the machine

	\ingroup kernel_machines
*/
template< typename Problem, typename Kernel, typename PropertyMap >
class kernel_machine< Problem, Kernel, PropertyMap, typename boost::enable_if< is_regression<Problem> >::type>:
    public std::unary_function< typename Problem::input_type, typename Problem::output_type > {

public:
    typedef Kernel kernel_type;
    typedef typename Problem::input_type input_type;
    typedef typename Problem::output_type output_type;
    typedef typename boost::property_traits<PropertyMap>::key_type key_type;
    typedef typename boost::property_traits<PropertyMap>::value_type object_type;

    friend class boost::serialization::access;

    // FIXME make this something else...
    typedef double scalar_type;

    // Bug fixed: use call_traits instead of const&, so can be called with both reference and non-reference
    /*! \brief Initializes the kernel
    	\param k parameter used to initialize the kernel
    */
    kernel_machine( typename boost::call_traits<kernel_type>::param_type k,
                    typename boost::call_traits<PropertyMap>::param_type map ):
    kernel_function(k), data(&map) {}

    void set_data( PropertyMap const &map ) {
        data = ↦
    }

    void set_kernel( kernel_type const &k ) {
        kernel_function = k;
    }

    typename kernel_type::return_type kernel( key_type const i, key_type const j ) {
                                    return kernel_function( (*data)[i].get<0>(), (*data)[j].get<0>() );
                                }

                                typename kernel_type::return_type kernel( input_type const &x, key_type const j ) {
                                                                return kernel_function( x, (*data)[j].get<0>() );
                                                            }

                                                            template<typename KeyIterator, typename OutputIterator>
    void fill_kernel( input_type const &x,
                      KeyIterator const begin, KeyIterator const end, OutputIterator out ) {
        KeyIterator i(begin);
        OutputIterator j(out);
        while (i!=end) {
            *j = kernel_function( x, (*data)[*i].get<0>() );
            ++i;
            ++j;
        }
    }

    template<typename KeyIterator, typename OutputIterator>
    void fill_kernel( key_type const key,
                      KeyIterator const begin, KeyIterator const end, OutputIterator out ) {
        KeyIterator i(begin);
        OutputIterator j(out);
        while (i!=end) {
            *j = kernel_function( (*data)[key].get<0>(), (*data)[*i].get<0>() );
            ++i;
            ++j;
        }
    }

    // to fill e.g. a column of H, use fill_kernel
    // from boost documentation:
    // An algorithm that iterates through the range [m.begin1 (), m.end1 ()) will
    // pass through every row of m , an algorithm that iterates through the range [m.begin2 (), m.end2 ())
    // will pass through every column of m .
    template<typename KeyIterator, typename Matrix>
    void design_matrix( KeyIterator const begin, KeyIterator const end, Matrix &out ) {

        // row by row filling
        KeyIterator i(begin);
        std::size_t row = 0;
        while( i != end ) {
            out( row, 0 ) = 1.0;
            std::size_t col = 0;
            KeyIterator j(begin);
            while( j != end ) {
                out( row, ++col ) = kernel_function( (*data)[*i].get<0>(), (*data)[*j].get<0>() );
                ++j;
            }
            ++row;
            ++i;
        }
    }

    // loading and saving capabilities
    template<class Archive>
    void serialize( Archive &archive, unsigned int const version ) {

        // here we store whatever we want to store...
        archive & kernel_function;

    }

    /// Clears the machine (operator() it will always returns 0).
    //     void clear() {
    //         bias = 0.0;
    //         weight.clear();
    //     }

    /// kernel_function used by the machine
    kernel_type kernel_function;

    /// pointer to data container used by the machine
    PropertyMap const *data;

    /// to translate to a sequential view
    //     std::map< key_type, std::size_t > key_mapping;

    typedef typename std::vector< key_type >::size_type index_type;
    //std::vector< key_type > key_lookup;

    /// bias of the machine
    //double bias;
    /// weights of the support vectors
    /// weight[i] is associated with key_lookup[i]
    //std::vector<double> weight;

};

/*! \brief Classification kernel machine

	This is used as a base for various classification kernel machines.

	\param Problem a classification problem type, for example kml::classification
	\param Kernel kernel to be used by the machine

	\ingroup kernel_machines
*/
template< typename Problem, typename Kernel, typename PropertyMap >
class kernel_machine<Problem, Kernel, PropertyMap, typename boost::enable_if< is_classification<Problem> >::type >:
    public std::unary_function< typename Problem::input_type, typename Problem::output_type > {

public:
    typedef Kernel kernel_type;
    typedef typename Problem::input_type input_type;
    typedef typename Problem::output_type output_type;
    typedef typename boost::property_traits<PropertyMap>::key_type key_type;
    typedef typename boost::property_traits<PropertyMap>::value_type object_type;

    // FIXME make this something else...
    typedef double scalar_type;

    kernel_machine( typename boost::call_traits<kernel_type>::param_type k,
                    typename boost::call_traits<PropertyMap>::param_type map ):
    kernel_function(k), data(&map) {}

    typename kernel_type::return_type kernel( key_type const i, key_type const j ) {
                                    return kernel_function( (*data)[i].get<0>(), (*data)[j].get<0>() );
                                }

                                typename kernel_type::return_type kernel( input_type const &x, key_type const j ) {
                                                                return kernel_function( x, (*data)[j].get<0>() );
                                                            }

                                                            template<typename KeyIterator, typename OutputIterator>
    void fill_kernel( input_type const &x,
                      KeyIterator const begin, KeyIterator const end, OutputIterator out ) {
        KeyIterator i(begin);
        OutputIterator j(out);
        while (i!=end) {
            if ( (*data)[*i].get<1>() )
                *j = kernel_function( x, (*data)[*i].get<0>() );
            else
                *j = -kernel_function( x, (*data)[*i].get<0>() );
            ++i;
            ++j;
        }
    }

    template<typename KeyIterator, typename OutputIterator>
    void fill_kernel( key_type const key,
                      KeyIterator const begin, KeyIterator const end, OutputIterator out ) {
        KeyIterator i(begin);
        OutputIterator j(out);
        if ( (*data)[key].get<1>() ) {
            while (i!=end) {
                if ( (*data)[*i].get<1>() )
                    *j = kernel_function( (*data)[key].get<0>(), (*data)[*i].get<0>() );
                else
                    *j = -kernel_function( (*data)[key].get<0>(), (*data)[*i].get<0>() );
                ++i;
                ++j;
            }
        } else {
            while (i!=end) {
                if ( (*data)[*i].get<1>() )
                    *j = -kernel_function( (*data)[key].get<0>(), (*data)[*i].get<0>() );
                else
                    *j = kernel_function( (*data)[key].get<0>(), (*data)[*i].get<0>() );
                ++i;
                ++j;
            }
        }
    }

    // FIXME optimal return type (by value, return value, i.e. see boost call_traits)
    //     output_type operator()( typename boost::call_traits<input_type>::param_type x ) {
    //
    // 	// this must be convertable to bool
    //         return std::inner_product( weight.begin(),
    // 	                           weight.end(),
    // 				   support_vector.begin(),
    // 				   bias,
    //                                    std::plus<output_type>(), boost::lambda::bind(detail::multiplies<double,output_type>(), boost::lambda::_1,
    //                                                              boost::lambda::bind(kernel,x,boost::lambda::_2)) ) >= 0.0;
    //     }

    void set_data( PropertyMap const &map ) {
        data = ↦
    }

    // loading and saving capabilities
    template<class Archive>
    void serialize( Archive &archive, unsigned int const version ) {

        // here we store whatever we want to store...
        archive & kernel_function;

    }

    //     void clear() {
    //         bias = 0.0;
    //         weight.clear();
    //     }

    /// kernel_function used by the machine
    kernel_type kernel_function;

    /// pointer to data container used by the machine
    PropertyMap const *data;

    /// to translate to a sequential view
    //     std::map< key_type, std::size_t > key_mapping;
    //     std::vector< key_type > key_lookup;

    //     double bias;

    // the weight should have the sign of the corresponding output sample!
    // w_i = a_i * y_i
    /*    std::vector<double> weight;*/
};

} // namespace kml

// set tracking to track never

namespace boost {
namespace serialization {

template< typename Problem, typename Kernel, typename PropertyMap, typename Enable >
struct tracking_level< kml::kernel_machine<Problem,Kernel,PropertyMap,Enable> > {
    typedef mpl::integral_c_tag tag;
    typedef mpl::int_<track_never> type;
    BOOST_STATIC_CONSTANT(
        int,
        value = tracking_level::type::value
    );
};

} // namespace serialization
} // namespace boost

#endif
<commit_msg>added an overload of kernel() which I needed<commit_after>/***************************************************************************
 *  The Kernel-Machine Library                                             *
 *  Copyright (C) 2004--2006 by Rutger W. ter Borg                         *
 *                                                                         *
 *  This library is free software; you can redistribute it and/or          *
 *  modify it under the terms of the GNU Lesser General Public             *
 *  License as published by the Free Software Foundation; either           *
 *  version 2.1 of the License, or (at your option) any later version.     *
 *                                                                         *
 *  This library is distributed in the hope that it will be useful,        *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU      *
 *  Lesser General Public License for more details.                        *
 *                                                                         *
 *  You should have received a copy of the GNU Lesser General Public       *
 *  License along with this library; if not, write to the Free Software    *
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  *
 ***************************************************************************/

#ifndef KERNEL_MACHINE_HPP
#define KERNEL_MACHINE_HPP

#include <boost/lambda/bind.hpp>
#include <boost/utility/enable_if.hpp>
#include <kml/regression.hpp>
#include <kml/classification.hpp>
#include <kml/ranking.hpp>
#include <vector>

#include <boost/serialization/access.hpp>
#include <boost/serialization/tracking.hpp>

//#include <kml/determinate.hpp>

// for the property traits
#include <boost/property_map.hpp>

namespace lambda = boost::lambda;

namespace kml {

template< typename Problem, typename Kernel, typename PropertyMap, class Enable=void >
class kernel_machine {}
;

/*! \brief Regression kernel machine

	This is used as a base for various regression kernel machines, for example kml::rvm.

	\param Problem a regression problem type, for example kml::regression
	\param Kernel kernel to be used by the machine

	\ingroup kernel_machines
*/
template< typename Problem, typename Kernel, typename PropertyMap >
class kernel_machine< Problem, Kernel, PropertyMap, typename boost::enable_if< is_regression<Problem> >::type>:
    public std::unary_function< typename Problem::input_type, typename Problem::output_type > {

public:
    typedef Kernel kernel_type;
    typedef typename Problem::input_type input_type;
    typedef typename Problem::output_type output_type;
    typedef typename boost::property_traits<PropertyMap>::key_type key_type;
    typedef typename boost::property_traits<PropertyMap>::value_type object_type;

    friend class boost::serialization::access;

    // FIXME make this something else...
    typedef double scalar_type;

    // Bug fixed: use call_traits instead of const&, so can be called with both reference and non-reference
    /*! \brief Initializes the kernel
    	\param k parameter used to initialize the kernel
    */
    kernel_machine( typename boost::call_traits<kernel_type>::param_type k,
                    typename boost::call_traits<PropertyMap>::param_type map ):
    kernel_function(k), data(&map) {}

    void set_data( PropertyMap const &map ) {
        data = ↦
    }

    void set_kernel( kernel_type const &k ) {
        kernel_function = k;
    }

    typename kernel_type::return_type kernel( key_type const i, key_type const j ) {
                                    return kernel_function( (*data)[i].get<0>(), (*data)[j].get<0>() );
                                }

                                typename kernel_type::return_type kernel( input_type const &x, key_type const j ) {
                                                                return kernel_function( x, (*data)[j].get<0>() );
                                                            }

                                                            template<typename KeyIterator, typename OutputIterator>
    void fill_kernel( input_type const &x,
                      KeyIterator const begin, KeyIterator const end, OutputIterator out ) {
        KeyIterator i(begin);
        OutputIterator j(out);
        while (i!=end) {
            *j = kernel_function( x, (*data)[*i].get<0>() );
            ++i;
            ++j;
        }
    }

    template<typename KeyIterator, typename OutputIterator>
    void fill_kernel( key_type const key,
                      KeyIterator const begin, KeyIterator const end, OutputIterator out ) {
        KeyIterator i(begin);
        OutputIterator j(out);
        while (i!=end) {
            *j = kernel_function( (*data)[key].get<0>(), (*data)[*i].get<0>() );
            ++i;
            ++j;
        }
    }

    // to fill e.g. a column of H, use fill_kernel
    // from boost documentation:
    // An algorithm that iterates through the range [m.begin1 (), m.end1 ()) will
    // pass through every row of m , an algorithm that iterates through the range [m.begin2 (), m.end2 ())
    // will pass through every column of m .
    template<typename KeyIterator, typename Matrix>
    void design_matrix( KeyIterator const begin, KeyIterator const end, Matrix &out ) {

        // row by row filling
        KeyIterator i(begin);
        std::size_t row = 0;
        while( i != end ) {
            out( row, 0 ) = 1.0;
            std::size_t col = 0;
            KeyIterator j(begin);
            while( j != end ) {
                out( row, ++col ) = kernel_function( (*data)[*i].get<0>(), (*data)[*j].get<0>() );
                ++j;
            }
            ++row;
            ++i;
        }
    }

    // loading and saving capabilities
    template<class Archive>
    void serialize( Archive &archive, unsigned int const version ) {

        // here we store whatever we want to store...
        archive & kernel_function;

    }

    /// Clears the machine (operator() it will always returns 0).
    //     void clear() {
    //         bias = 0.0;
    //         weight.clear();
    //     }

    /// kernel_function used by the machine
    kernel_type kernel_function;

    /// pointer to data container used by the machine
    PropertyMap const *data;

    /// to translate to a sequential view
    //     std::map< key_type, std::size_t > key_mapping;

    typedef typename std::vector< key_type >::size_type index_type;
    //std::vector< key_type > key_lookup;

    /// bias of the machine
    //double bias;
    /// weights of the support vectors
    /// weight[i] is associated with key_lookup[i]
    //std::vector<double> weight;

};

/*! \brief Classification kernel machine

	This is used as a base for various classification kernel machines.

	\param Problem a classification problem type, for example kml::classification
	\param Kernel kernel to be used by the machine

	\ingroup kernel_machines
*/
template< typename Problem, typename Kernel, typename PropertyMap >
class kernel_machine<Problem, Kernel, PropertyMap, typename boost::enable_if< is_classification<Problem> >::type >:
    public std::unary_function< typename Problem::input_type, typename Problem::output_type > {

public:
    typedef Kernel kernel_type;
    typedef typename Problem::input_type input_type;
    typedef typename Problem::output_type output_type;
    typedef typename boost::property_traits<PropertyMap>::key_type key_type;
    typedef typename boost::property_traits<PropertyMap>::value_type object_type;

    // FIXME make this something else...
    typedef double scalar_type;

    kernel_machine( typename boost::call_traits<kernel_type>::param_type k,
                    typename boost::call_traits<PropertyMap>::param_type map ):
    kernel_function(k), data(&map) {}

    typename kernel_type::return_type kernel( key_type const i, key_type const j ) {
                                    return kernel_function( (*data)[i].get<0>(), (*data)[j].get<0>() );
                                }

                                typename kernel_type::return_type kernel( input_type const &x, key_type const j ) {
                                                                return kernel_function( x, (*data)[j].get<0>() );
                                                            }

  typename kernel_type::return_type kernel(key_type const i, input_type const &x) {
    return kernel_function((*data)[i].get<0>(), x);
  }

                                                            template<typename KeyIterator, typename OutputIterator>
    void fill_kernel( input_type const &x,
                      KeyIterator const begin, KeyIterator const end, OutputIterator out ) {
        KeyIterator i(begin);
        OutputIterator j(out);
        while (i!=end) {
            if ( (*data)[*i].get<1>() )
                *j = kernel_function( x, (*data)[*i].get<0>() );
            else
                *j = -kernel_function( x, (*data)[*i].get<0>() );
            ++i;
            ++j;
        }
    }

    template<typename KeyIterator, typename OutputIterator>
    void fill_kernel( key_type const key,
                      KeyIterator const begin, KeyIterator const end, OutputIterator out ) {
        KeyIterator i(begin);
        OutputIterator j(out);
        if ( (*data)[key].get<1>() ) {
            while (i!=end) {
                if ( (*data)[*i].get<1>() )
                    *j = kernel_function( (*data)[key].get<0>(), (*data)[*i].get<0>() );
                else
                    *j = -kernel_function( (*data)[key].get<0>(), (*data)[*i].get<0>() );
                ++i;
                ++j;
            }
        } else {
            while (i!=end) {
                if ( (*data)[*i].get<1>() )
                    *j = -kernel_function( (*data)[key].get<0>(), (*data)[*i].get<0>() );
                else
                    *j = kernel_function( (*data)[key].get<0>(), (*data)[*i].get<0>() );
                ++i;
                ++j;
            }
        }
    }

    // FIXME optimal return type (by value, return value, i.e. see boost call_traits)
    //     output_type operator()( typename boost::call_traits<input_type>::param_type x ) {
    //
    // 	// this must be convertable to bool
    //         return std::inner_product( weight.begin(),
    // 	                           weight.end(),
    // 				   support_vector.begin(),
    // 				   bias,
    //                                    std::plus<output_type>(), boost::lambda::bind(detail::multiplies<double,output_type>(), boost::lambda::_1,
    //                                                              boost::lambda::bind(kernel,x,boost::lambda::_2)) ) >= 0.0;
    //     }

    void set_data( PropertyMap const &map ) {
        data = ↦
    }

    // loading and saving capabilities
    template<class Archive>
    void serialize( Archive &archive, unsigned int const version ) {

        // here we store whatever we want to store...
        archive & kernel_function;

    }

    //     void clear() {
    //         bias = 0.0;
    //         weight.clear();
    //     }

    /// kernel_function used by the machine
    kernel_type kernel_function;

    /// pointer to data container used by the machine
    PropertyMap const *data;

    /// to translate to a sequential view
    //     std::map< key_type, std::size_t > key_mapping;
    //     std::vector< key_type > key_lookup;

    //     double bias;

    // the weight should have the sign of the corresponding output sample!
    // w_i = a_i * y_i
    /*    std::vector<double> weight;*/
};

} // namespace kml

// set tracking to track never

namespace boost {
namespace serialization {

template< typename Problem, typename Kernel, typename PropertyMap, typename Enable >
struct tracking_level< kml::kernel_machine<Problem,Kernel,PropertyMap,Enable> > {
    typedef mpl::integral_c_tag tag;
    typedef mpl::int_<track_never> type;
    BOOST_STATIC_CONSTANT(
        int,
        value = tracking_level::type::value
    );
};

} // namespace serialization
} // namespace boost

#endif
<|endoftext|>


<commit_before>//===--- MutexWin32.cpp - -------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Mutex, ConditionVariable, Read/Write lock, and Scoped lock implementations
// using Windows Slim Reader/Writer Locks and Conditional Variables.
//
//===----------------------------------------------------------------------===//

#include "swift/Runtime/Mutex.h"
#include "swift/Runtime/Debug.h"

using namespace swift;

void ConditionPlatformHelper::wait(CONDITION_VARIABLE &condition,
                                   SRWLOCK &mutex) {
  BOOL result = SleepConditionVariableSRW(&condition, &mutex, INFINITE, 0);
  if (result == FALSE) {
    DWORD errorcode = GetLastError();
    fatalError(/* flags = */ 0,
               "'SleepConditionVariableSRW()' failed with error code %d\n",
               errorcode);
  }
}
<commit_msg>[gardening] Don't compare with FALSE.<commit_after>//===--- MutexWin32.cpp - -------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Mutex, ConditionVariable, Read/Write lock, and Scoped lock implementations
// using Windows Slim Reader/Writer Locks and Conditional Variables.
//
//===----------------------------------------------------------------------===//

#include "swift/Runtime/Mutex.h"
#include "swift/Runtime/Debug.h"

using namespace swift;

void ConditionPlatformHelper::wait(CONDITION_VARIABLE &condition,
                                   SRWLOCK &mutex) {
  BOOL result = SleepConditionVariableSRW(&condition, &mutex, INFINITE, 0);
  if (!result) {
    DWORD errorcode = GetLastError();
    fatalError(/* flags = */ 0,
               "'SleepConditionVariableSRW()' failed with error code %d\n",
               errorcode);
  }
}
<|endoftext|>


<commit_before>

class Solution {
public:
    /**
     * @param heights: a vector of integers
     * @return: an integer
     */
    int maxArea(vector<int> &height) {
        int max = 0, area;
        int start = 0, end = height.size() - 1;
        while (start < end) {
            if (height[start] > height[end]) {
                area = height[end] * (end - start);
                end --;
            } else {
                area = height[start] * (end - start);
                start ++;
            }
            if (area > max) {
                max = area;
            }
        }
        return max;
    }
};<commit_msg>Considering 393<commit_after>
class Solution {
public:
    /**
     * @param heights: a vector of integers
     * @return: an integer
     */
    int maxArea(vector<int> &height) {
        int max = 0, area;
        int start = 0, end = height.size() - 1;

        // sub
        while (start < end) {
            if (height[start] > height[end]) {
                area = height[end] * (end - start);
                end --;
            } else {
                area = height[start] * (end - start);
                start ++;
            }

            if (area > max) {
                max = area;
            }
        }

        return max;
    }
};<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: maildispatcher.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 22:44:35 $
 *
 *  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_sw.hxx"

#ifndef INCLUDED_MAILDISPATCHER_HXX
#include "maildispatcher.hxx"
#endif

#ifndef INCLUDED_IMAILDSPLISTENER_HXX
#include "imaildsplistener.hxx"
#endif

#include <algorithm>

using namespace ::com::sun::star;
using ::rtl::OUString;

typedef std::list< uno::Reference<mail::XMailMessage> > MailMessageContainer_t;
typedef std::list< ::rtl::Reference<IMailDispatcherListener> > MailDispatcherListenerContainer_t;

namespace /* private */
{
    /* Generic event notifier for started,
       stopped, and idle events which are
       very similary */
    class GenericEventNotifier
    {
    public:
        // pointer to virtual function typedef
        typedef void (IMailDispatcherListener::*GenericNotificationFunc_t)(::rtl::Reference<MailDispatcher>);

        GenericEventNotifier(
            GenericNotificationFunc_t notification_function,
            ::rtl::Reference<MailDispatcher> mail_dispatcher) :
            notification_function_(notification_function),
            mail_dispatcher_(mail_dispatcher)
        {}

        void operator() (::rtl::Reference<IMailDispatcherListener> listener) const
        { (listener.get()->*notification_function_)(mail_dispatcher_); }

    private:
        GenericNotificationFunc_t notification_function_;
        ::rtl::Reference<MailDispatcher> mail_dispatcher_;
    };

    class MailDeliveryNotifier
    {
    public:
        MailDeliveryNotifier(::rtl::Reference<MailDispatcher> xMailDispatcher, uno::Reference<mail::XMailMessage> message) :
            mail_dispatcher_(xMailDispatcher),
            message_(message)
        {}

        void operator() (::rtl::Reference<IMailDispatcherListener> listener) const
        { listener->mailDelivered(mail_dispatcher_, message_); }

    private:
        ::rtl::Reference<MailDispatcher> mail_dispatcher_;
        uno::Reference<mail::XMailMessage> message_;
    };

    class MailDeliveryErrorNotifier
    {
    public:
        MailDeliveryErrorNotifier(
            ::rtl::Reference<MailDispatcher> xMailDispatcher,
            uno::Reference<mail::XMailMessage> message,
            const ::rtl::OUString& error_message) :
            mail_dispatcher_(xMailDispatcher),
            message_(message),
            error_message_(error_message)
        {}

        void operator() (::rtl::Reference<IMailDispatcherListener> listener) const
        { listener->mailDeliveryError(mail_dispatcher_, message_, error_message_); }

    private:
        ::rtl::Reference<MailDispatcher> mail_dispatcher_;
        uno::Reference<mail::XMailMessage> message_;
        ::rtl::OUString error_message_;
    };

} // namespace private

MailDispatcher::MailDispatcher(uno::Reference<mail::XSmtpService> mailserver) :
    mailserver_ (mailserver),
    run_(false),
    shutdown_requested_(false),
    bIsInRun(false)
{
    wakening_call_.reset();
    mail_dispatcher_active_.reset();

    if (!create())
        throw uno::RuntimeException();

    // wait until the mail dispatcher thread is really alive
    // and has aquired a reference to this instance of the
    // class
    mail_dispatcher_active_.wait();
}

MailDispatcher::~MailDispatcher()
{
}

void MailDispatcher::enqueueMailMessage(uno::Reference<mail::XMailMessage> message)
{
    ::osl::MutexGuard thread_status_guard(thread_status_mutex_);
    ::osl::MutexGuard message_container_guard(message_container_mutex_);

    OSL_PRECOND(!shutdown_requested_, "MailDispatcher thread is shuting down already");

    messages_.push_back(message);
    if (run_)
        wakening_call_.set();
}

uno::Reference<mail::XMailMessage> MailDispatcher::dequeueMailMessage()
{
    ::osl::MutexGuard guard(message_container_mutex_);
    uno::Reference<mail::XMailMessage> message;
    if(!messages_.empty())
    {
        message = messages_.front();
        messages_.pop_front();
    }
    return message;
}

void MailDispatcher::start()
{
    OSL_PRECOND(!isStarted(), "MailDispatcher is already started!");

    ::osl::ClearableMutexGuard thread_status_guard(thread_status_mutex_);

    OSL_PRECOND(!shutdown_requested_, "MailDispatcher thread is shuting down already");

    if (!shutdown_requested_)
    {
        run_ = true;
        wakening_call_.set();
        thread_status_guard.clear();

        MailDispatcherListenerContainer_t listeners_cloned(cloneListener());
        std::for_each(listeners_cloned.begin(), listeners_cloned.end(), GenericEventNotifier(&IMailDispatcherListener::started, this));
    }
}

void MailDispatcher::stop()
{
    OSL_PRECOND(isStarted(), "MailDispatcher not started!");

    ::osl::ClearableMutexGuard thread_status_guard(thread_status_mutex_);

    OSL_PRECOND(!shutdown_requested_, "MailDispatcher thread is shuting down already");

    if (!shutdown_requested_)
    {
        run_ = false;
        wakening_call_.reset();
        thread_status_guard.clear();

        MailDispatcherListenerContainer_t listeners_cloned(cloneListener());
        std::for_each(listeners_cloned.begin(), listeners_cloned.end(), GenericEventNotifier(&IMailDispatcherListener::stopped, this));
    }
}

void MailDispatcher::shutdown()
{
    ::osl::MutexGuard thread_status_guard(thread_status_mutex_);

    OSL_PRECOND(!shutdown_requested_, "MailDispatcher thread is shuting down already");

    shutdown_requested_ = true;
    wakening_call_.set();
}

bool MailDispatcher::isStarted() const
{
    return run_;
}

bool MailDispatcher::isRunning() const
{
    return bIsInRun;
}

void MailDispatcher::addListener(::rtl::Reference<IMailDispatcherListener> listener)
{
    OSL_PRECOND(!shutdown_requested_, "MailDispatcher thread is shuting down already");

    ::osl::MutexGuard guard(listener_container_mutex_);
    listeners_.push_back(listener);
}

void MailDispatcher::removeListener(::rtl::Reference<IMailDispatcherListener> listener)
{
    OSL_PRECOND(!shutdown_requested_, "MailDispatcher thread is shuting down already");

    ::osl::MutexGuard guard(listener_container_mutex_);
    listeners_.remove(listener);
}

std::list< ::rtl::Reference<IMailDispatcherListener> > MailDispatcher::cloneListener()
{
    ::osl::MutexGuard guard(listener_container_mutex_);
    return listeners_;
}

void MailDispatcher::sendMailMessageNotifyListener(uno::Reference<mail::XMailMessage> message)
{
    try
    {
        mailserver_->sendMailMessage(message);
        MailDispatcherListenerContainer_t listeners_cloned(cloneListener());
        std::for_each(listeners_cloned.begin(), listeners_cloned.end(), MailDeliveryNotifier(this, message));
    }
    catch (mail::MailException& ex)
    {
        MailDispatcherListenerContainer_t listeners_cloned(cloneListener());
        std::for_each(listeners_cloned.begin(), listeners_cloned.end(), MailDeliveryErrorNotifier(this, message, ex.Message));
    }
    catch (uno::RuntimeException& ex)
    {
        MailDispatcherListenerContainer_t listeners_cloned(cloneListener());
        std::for_each(listeners_cloned.begin(), listeners_cloned.end(), MailDeliveryErrorNotifier(this, message, ex.Message));
    }
}

void MailDispatcher::run()
{
    // aquire a self reference in order to avoid race
    // conditions. The last client of this class must
    // call shutdown before releasing his last reference
    // to this class in order to shutdown this thread
    // which will release his (the very last reference
    // to the class and so force their destruction
    m_xSelfReference = this;

    // signal that the mail dispatcher thread is now alive
    mail_dispatcher_active_.set();

    bIsInRun = true;
    for(;;)
    {
        wakening_call_.wait();

        ::osl::ClearableMutexGuard thread_status_guard(thread_status_mutex_);
        if (shutdown_requested_)
           break;

        ::osl::ClearableMutexGuard message_container_guard(message_container_mutex_);

        if (messages_.size())
        {
            thread_status_guard.clear();
            uno::Reference<mail::XMailMessage> message = messages_.front();
            messages_.pop_front();
            message_container_guard.clear();
            sendMailMessageNotifyListener(message);
        }
        else // idle - put ourself to sleep
        {
            wakening_call_.reset();
            message_container_guard.clear();
            thread_status_guard.clear();
            MailDispatcherListenerContainer_t listeners_cloned(cloneListener());
            std::for_each(listeners_cloned.begin(), listeners_cloned.end(), GenericEventNotifier(&IMailDispatcherListener::idle, this));
        }
    } // end for        SSH ALI
    bIsInRun = false;
}
/*-- 27.08.2004 12:04:46---------------------------------------------------

  -----------------------------------------------------------------------*/
void MailDispatcher::onTerminated()
{
    //keep the reference until the end of onTerminated() because of the call order in the
    //_threadFunc() from osl/thread.hxx
    m_xSelfReference = 0;
}
<commit_msg>INTEGRATION: CWS changefileheader (1.5.718); FILE MERGED 2008/04/01 12:55:07 thb 1.5.718.2: #i85898# Stripping all external header guards 2008/03/31 16:57:03 rt 1.5.718.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: maildispatcher.cxx,v $
 * $Revision: 1.6 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

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

#include <algorithm>

using namespace ::com::sun::star;
using ::rtl::OUString;

typedef std::list< uno::Reference<mail::XMailMessage> > MailMessageContainer_t;
typedef std::list< ::rtl::Reference<IMailDispatcherListener> > MailDispatcherListenerContainer_t;

namespace /* private */
{
    /* Generic event notifier for started,
       stopped, and idle events which are
       very similary */
    class GenericEventNotifier
    {
    public:
        // pointer to virtual function typedef
        typedef void (IMailDispatcherListener::*GenericNotificationFunc_t)(::rtl::Reference<MailDispatcher>);

        GenericEventNotifier(
            GenericNotificationFunc_t notification_function,
            ::rtl::Reference<MailDispatcher> mail_dispatcher) :
            notification_function_(notification_function),
            mail_dispatcher_(mail_dispatcher)
        {}

        void operator() (::rtl::Reference<IMailDispatcherListener> listener) const
        { (listener.get()->*notification_function_)(mail_dispatcher_); }

    private:
        GenericNotificationFunc_t notification_function_;
        ::rtl::Reference<MailDispatcher> mail_dispatcher_;
    };

    class MailDeliveryNotifier
    {
    public:
        MailDeliveryNotifier(::rtl::Reference<MailDispatcher> xMailDispatcher, uno::Reference<mail::XMailMessage> message) :
            mail_dispatcher_(xMailDispatcher),
            message_(message)
        {}

        void operator() (::rtl::Reference<IMailDispatcherListener> listener) const
        { listener->mailDelivered(mail_dispatcher_, message_); }

    private:
        ::rtl::Reference<MailDispatcher> mail_dispatcher_;
        uno::Reference<mail::XMailMessage> message_;
    };

    class MailDeliveryErrorNotifier
    {
    public:
        MailDeliveryErrorNotifier(
            ::rtl::Reference<MailDispatcher> xMailDispatcher,
            uno::Reference<mail::XMailMessage> message,
            const ::rtl::OUString& error_message) :
            mail_dispatcher_(xMailDispatcher),
            message_(message),
            error_message_(error_message)
        {}

        void operator() (::rtl::Reference<IMailDispatcherListener> listener) const
        { listener->mailDeliveryError(mail_dispatcher_, message_, error_message_); }

    private:
        ::rtl::Reference<MailDispatcher> mail_dispatcher_;
        uno::Reference<mail::XMailMessage> message_;
        ::rtl::OUString error_message_;
    };

} // namespace private

MailDispatcher::MailDispatcher(uno::Reference<mail::XSmtpService> mailserver) :
    mailserver_ (mailserver),
    run_(false),
    shutdown_requested_(false),
    bIsInRun(false)
{
    wakening_call_.reset();
    mail_dispatcher_active_.reset();

    if (!create())
        throw uno::RuntimeException();

    // wait until the mail dispatcher thread is really alive
    // and has aquired a reference to this instance of the
    // class
    mail_dispatcher_active_.wait();
}

MailDispatcher::~MailDispatcher()
{
}

void MailDispatcher::enqueueMailMessage(uno::Reference<mail::XMailMessage> message)
{
    ::osl::MutexGuard thread_status_guard(thread_status_mutex_);
    ::osl::MutexGuard message_container_guard(message_container_mutex_);

    OSL_PRECOND(!shutdown_requested_, "MailDispatcher thread is shuting down already");

    messages_.push_back(message);
    if (run_)
        wakening_call_.set();
}

uno::Reference<mail::XMailMessage> MailDispatcher::dequeueMailMessage()
{
    ::osl::MutexGuard guard(message_container_mutex_);
    uno::Reference<mail::XMailMessage> message;
    if(!messages_.empty())
    {
        message = messages_.front();
        messages_.pop_front();
    }
    return message;
}

void MailDispatcher::start()
{
    OSL_PRECOND(!isStarted(), "MailDispatcher is already started!");

    ::osl::ClearableMutexGuard thread_status_guard(thread_status_mutex_);

    OSL_PRECOND(!shutdown_requested_, "MailDispatcher thread is shuting down already");

    if (!shutdown_requested_)
    {
        run_ = true;
        wakening_call_.set();
        thread_status_guard.clear();

        MailDispatcherListenerContainer_t listeners_cloned(cloneListener());
        std::for_each(listeners_cloned.begin(), listeners_cloned.end(), GenericEventNotifier(&IMailDispatcherListener::started, this));
    }
}

void MailDispatcher::stop()
{
    OSL_PRECOND(isStarted(), "MailDispatcher not started!");

    ::osl::ClearableMutexGuard thread_status_guard(thread_status_mutex_);

    OSL_PRECOND(!shutdown_requested_, "MailDispatcher thread is shuting down already");

    if (!shutdown_requested_)
    {
        run_ = false;
        wakening_call_.reset();
        thread_status_guard.clear();

        MailDispatcherListenerContainer_t listeners_cloned(cloneListener());
        std::for_each(listeners_cloned.begin(), listeners_cloned.end(), GenericEventNotifier(&IMailDispatcherListener::stopped, this));
    }
}

void MailDispatcher::shutdown()
{
    ::osl::MutexGuard thread_status_guard(thread_status_mutex_);

    OSL_PRECOND(!shutdown_requested_, "MailDispatcher thread is shuting down already");

    shutdown_requested_ = true;
    wakening_call_.set();
}

bool MailDispatcher::isStarted() const
{
    return run_;
}

bool MailDispatcher::isRunning() const
{
    return bIsInRun;
}

void MailDispatcher::addListener(::rtl::Reference<IMailDispatcherListener> listener)
{
    OSL_PRECOND(!shutdown_requested_, "MailDispatcher thread is shuting down already");

    ::osl::MutexGuard guard(listener_container_mutex_);
    listeners_.push_back(listener);
}

void MailDispatcher::removeListener(::rtl::Reference<IMailDispatcherListener> listener)
{
    OSL_PRECOND(!shutdown_requested_, "MailDispatcher thread is shuting down already");

    ::osl::MutexGuard guard(listener_container_mutex_);
    listeners_.remove(listener);
}

std::list< ::rtl::Reference<IMailDispatcherListener> > MailDispatcher::cloneListener()
{
    ::osl::MutexGuard guard(listener_container_mutex_);
    return listeners_;
}

void MailDispatcher::sendMailMessageNotifyListener(uno::Reference<mail::XMailMessage> message)
{
    try
    {
        mailserver_->sendMailMessage(message);
        MailDispatcherListenerContainer_t listeners_cloned(cloneListener());
        std::for_each(listeners_cloned.begin(), listeners_cloned.end(), MailDeliveryNotifier(this, message));
    }
    catch (mail::MailException& ex)
    {
        MailDispatcherListenerContainer_t listeners_cloned(cloneListener());
        std::for_each(listeners_cloned.begin(), listeners_cloned.end(), MailDeliveryErrorNotifier(this, message, ex.Message));
    }
    catch (uno::RuntimeException& ex)
    {
        MailDispatcherListenerContainer_t listeners_cloned(cloneListener());
        std::for_each(listeners_cloned.begin(), listeners_cloned.end(), MailDeliveryErrorNotifier(this, message, ex.Message));
    }
}

void MailDispatcher::run()
{
    // aquire a self reference in order to avoid race
    // conditions. The last client of this class must
    // call shutdown before releasing his last reference
    // to this class in order to shutdown this thread
    // which will release his (the very last reference
    // to the class and so force their destruction
    m_xSelfReference = this;

    // signal that the mail dispatcher thread is now alive
    mail_dispatcher_active_.set();

    bIsInRun = true;
    for(;;)
    {
        wakening_call_.wait();

        ::osl::ClearableMutexGuard thread_status_guard(thread_status_mutex_);
        if (shutdown_requested_)
           break;

        ::osl::ClearableMutexGuard message_container_guard(message_container_mutex_);

        if (messages_.size())
        {
            thread_status_guard.clear();
            uno::Reference<mail::XMailMessage> message = messages_.front();
            messages_.pop_front();
            message_container_guard.clear();
            sendMailMessageNotifyListener(message);
        }
        else // idle - put ourself to sleep
        {
            wakening_call_.reset();
            message_container_guard.clear();
            thread_status_guard.clear();
            MailDispatcherListenerContainer_t listeners_cloned(cloneListener());
            std::for_each(listeners_cloned.begin(), listeners_cloned.end(), GenericEventNotifier(&IMailDispatcherListener::idle, this));
        }
    } // end for        SSH ALI
    bIsInRun = false;
}
/*-- 27.08.2004 12:04:46---------------------------------------------------

  -----------------------------------------------------------------------*/
void MailDispatcher::onTerminated()
{
    //keep the reference until the end of onTerminated() because of the call order in the
    //_threadFunc() from osl/thread.hxx
    m_xSelfReference = 0;
}
<|endoftext|>


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

#ifndef _OBJDLG_HXX
#define _OBJDLG_HXX

#ifndef _SVHEADER_HXX
#include <svheader.hxx>
#endif

#ifndef _SV_FLOATWIN_HXX //autogen
#include <vcl/floatwin.hxx>
#endif

#ifndef _SV_TOOLBOX_HXX //autogen
#include <vcl/toolbox.hxx>
#endif

#ifndef _SV_FIXED_HXX //autogen
#include <vcl/fixed.hxx>
#endif

#ifndef _SV_IMAGE_HXX
#include "vcl/image.hxx"
#endif

#include <bastype2.hxx>

class StarBASIC;

class ObjectTreeListBox : public BasicTreeListBox
{
private:

    virtual void    Command( const CommandEvent& rCEvt );
    virtual void    MouseButtonDown( const MouseEvent& rMEvt );

public:
            ObjectTreeListBox( Window* pParent, const ResId& rRes );
            ~ObjectTreeListBox();
};

class ObjectCatalogToolBox_Impl: public ToolBox
{
public:
    ObjectCatalogToolBox_Impl(Window * pParent, ResId const & rResId,
                              ResId const & rImagesHighContrastId);

private:
    virtual void DataChanged(DataChangedEvent const & rDCEvt);

    void setImages();

    ImageList m_aImagesNormal;
    ImageList m_aImagesHighContrast;
    bool m_bHighContrast;
};

class ObjectCatalog : public FloatingWindow
{
private:
    ObjectTreeListBox   aMacroTreeList;
    ObjectCatalogToolBox_Impl aToolBox;
    FixedText           aMacroDescr;
    Link                aCancelHdl;

protected:
    DECL_LINK( ToolBoxHdl, ToolBox* );
    void                CheckButtons();
    DECL_LINK( TreeListHighlightHdl, SvTreeListBox * );
    void                UpdateFields();
    virtual void        Move();
    virtual BOOL        Close();
    virtual void        Resize();

public:
    ObjectCatalog( Window * pParent );
    virtual ~ObjectCatalog();

    void                ScanBasic( BasicManager* pBasMgr, const String& rName );
    void                UpdateEntries();

//  BYTE                GetSelectedType();
//  BasicManager*       GetSelectedSbx( String& rLib, String& rModOrObj, String& rSubOrProp );

    void                SetCancelHdl( const Link& rLink ) { aCancelHdl = rLink; }
//  void                SetInsertHdl( const Link& rLink ) { aInsertHdl = rLink; }
};

#endif  //_OBJDLG_HXX

<commit_msg>INTEGRATION: CWS tbe11 (1.3.210); FILE MERGED 2004/07/15 17:51:49 tbe 1.3.210.3: #i31315# Rework Basic IDE Macro Chooser and Macro Organizer 2004/07/09 15:56:12 tbe 1.3.210.2: #i31315# Rework Basic IDE Macro Chooser and Macro Organizer 2004/06/21 11:29:49 tbe 1.3.210.1: #99468# Basic IDE cannot handle libraries, which contain dialogs only<commit_after>/*************************************************************************
 *
 *  $RCSfile: objdlg.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: kz $ $Date: 2004-07-23 12:07:50 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _OBJDLG_HXX
#define _OBJDLG_HXX

#ifndef _SVHEADER_HXX
#include <svheader.hxx>
#endif

#ifndef _SV_FLOATWIN_HXX //autogen
#include <vcl/floatwin.hxx>
#endif

#ifndef _SV_TOOLBOX_HXX //autogen
#include <vcl/toolbox.hxx>
#endif

#ifndef _SV_FIXED_HXX //autogen
#include <vcl/fixed.hxx>
#endif

#ifndef _SV_IMAGE_HXX
#include "vcl/image.hxx"
#endif

#include <bastype2.hxx>

class StarBASIC;

class ObjectTreeListBox : public BasicTreeListBox
{
private:

    virtual void    Command( const CommandEvent& rCEvt );
    virtual void    MouseButtonDown( const MouseEvent& rMEvt );

public:
            ObjectTreeListBox( Window* pParent, const ResId& rRes );
            ~ObjectTreeListBox();
};

class ObjectCatalogToolBox_Impl: public ToolBox
{
public:
    ObjectCatalogToolBox_Impl(Window * pParent, ResId const & rResId,
                              ResId const & rImagesHighContrastId);

private:
    virtual void DataChanged(DataChangedEvent const & rDCEvt);

    void setImages();

    ImageList m_aImagesNormal;
    ImageList m_aImagesHighContrast;
    bool m_bHighContrast;
};

class ObjectCatalog : public FloatingWindow
{
private:
    ObjectTreeListBox   aMacroTreeList;
    ObjectCatalogToolBox_Impl aToolBox;
    FixedText           aMacroDescr;
    Link                aCancelHdl;

protected:
    DECL_LINK( ToolBoxHdl, ToolBox* );
    void                CheckButtons();
    DECL_LINK( TreeListHighlightHdl, SvTreeListBox * );
    void                UpdateFields();
    virtual void        Move();
    virtual BOOL        Close();
    virtual void        Resize();

public:
    ObjectCatalog( Window * pParent );
    virtual ~ObjectCatalog();

    void                UpdateEntries();
    void                SetCurrentEntry( BasicEntryDescriptor& rDesc );

    void                SetCancelHdl( const Link& rLink ) { aCancelHdl = rLink; }
};

#endif  //_OBJDLG_HXX

<|endoftext|>