<commit_before>#include "apps/ELFLoader/elf_loader.h"
#include "libs/base/filesystem.h"
#include "libs/base/reset.h"
#include "libs/base/tasks.h"
#include "libs/nxp/rt1176-sdk/board_hardware.h"
#include "libs/tasks/UsbDeviceTask/usb_device_task.h"
#include "libs/usb/descriptors.h"
#include "third_party/freertos_kernel/include/FreeRTOS.h"
#include "third_party/freertos_kernel/include/task.h"
#include "third_party/freertos_kernel/include/timers.h"
#include "third_party/nxp/rt1176-sdk/devices/MIMXRT1176/drivers/fsl_soc_src.h"
#include <elf.h>
#include <memory>

/* Function definitions */
static void elfloader_main(void *param);
static void elfloader_recv(const uint8_t *buffer, uint32_t length);
static void usb_timer_callback(TimerHandle_t timer);
static bool elfloader_HandleEvent(uint32_t event, void *param);
static void elfloader_SetClassHandle(class_handle_t class_handle);
static usb_status_t elfloader_Handler(class_handle_t class_handle, uint32_t event, void *param);
void usb_device_task(void *param);

extern "C" uint32_t vPortGetRunTimeCounterValue(void) {
    return 0;
}

/* Static data definitions */
TimerHandle_t usb_timer;
static uint8_t* elfloader_recv_image = nullptr;
static char* elfloader_recv_path = nullptr;
static uint8_t elfloader_data[64];
static class_handle_t elfloader_class_handle;
static ElfloaderTarget elfloader_target = ElfloaderTarget::Ram;
static lfs_file_t file_handle;

static void elfloader_recv(const uint8_t *buffer, uint32_t length) {
    ElfloaderCommand cmd = static_cast<ElfloaderCommand>(buffer[0]);
    const ElfloaderSetSize *set_size = reinterpret_cast<const ElfloaderSetSize*>(&buffer[1]);
    const ElfloaderBytes *bytes = reinterpret_cast<const ElfloaderBytes*>(&buffer[1]);
    const ElfloaderTarget *target = reinterpret_cast<const ElfloaderTarget*>(&buffer[1]);
    xTimerStop(usb_timer, 0);
    switch (cmd) {
        case ElfloaderCommand::SetSize:
            assert(length == sizeof(ElfloaderSetSize) + 1);
            switch (elfloader_target) {
                case ElfloaderTarget::Filesystem:
                    break;
                case ElfloaderTarget::Ram:
                    elfloader_recv_image = (uint8_t*)malloc(set_size->size);
                    break;
                case ElfloaderTarget::Path:
                    elfloader_recv_path = (char*)malloc(set_size->size + 1);
                    memset(elfloader_recv_path, 0, set_size->size + 1);
                    break;
            }
            break;
        case ElfloaderCommand::Bytes:
            assert(length >= sizeof(ElfloaderBytes) + 1);
            switch (elfloader_target) {
                case ElfloaderTarget::Ram:
                    memcpy(elfloader_recv_image + bytes->offset, &buffer[1] + sizeof(ElfloaderBytes), bytes->size);
                    break;
                case ElfloaderTarget::Path:
                    memcpy(elfloader_recv_path + bytes->offset, &buffer[1] + sizeof(ElfloaderBytes), bytes->size);
                    break;
                case ElfloaderTarget::Filesystem:
                    valiant::filesystem::Write(&file_handle, &buffer[1] + sizeof(ElfloaderBytes), bytes->size);
                    break;
            }
            break;
        case ElfloaderCommand::Done:
            switch (elfloader_target) {
                case ElfloaderTarget::Ram:
                    xTaskCreate(elfloader_main, "elfloader_main", configMINIMAL_STACK_SIZE * 10, elfloader_recv_image, APP_TASK_PRIORITY, NULL);
                    break;
                case ElfloaderTarget::Path: {
                        // TODO(atv): This stuff can fail. We should propagate errors back to the Python side if possible.
                        auto dir = valiant::filesystem::Dirname(elfloader_recv_path);
                        valiant::filesystem::MakeDirs(dir.get());
                        valiant::filesystem::Open(&file_handle, elfloader_recv_path, true);
                        free(elfloader_recv_path);
                        elfloader_recv_path = nullptr;
                    }
                    break;
                case ElfloaderTarget::Filesystem:
                    valiant::filesystem::Close(&file_handle);
                    break;
            }
            break;
        case ElfloaderCommand::Reset:
            valiant::ResetToBootloader();
            break;
        case ElfloaderCommand::Target:
            elfloader_target = *target;
            break;
    }
}

static bool elfloader_HandleEvent(uint32_t event, void *param) {
    bool ret = true;
    usb_device_get_hid_descriptor_struct_t* get_hid_descriptor =
        static_cast<usb_device_get_hid_descriptor_struct_t*>(param);
    switch (event) {
        case kUSB_DeviceEventSetConfiguration:
            USB_DeviceHidRecv(elfloader_class_handle, elfloader_hid_endpoints[kRxEndpoint].endpointAddress, elfloader_data, sizeof(elfloader_data));
            break;
        case kUSB_DeviceEventGetHidReportDescriptor:
            get_hid_descriptor->buffer = elfloader_hid_report;
            get_hid_descriptor->length = elfloader_hid_report_size;
            get_hid_descriptor->interfaceNumber = elfloader_interfaces[0].interfaceNumber;
            break;
        default:
            ret = false;
            break;
    }
    return ret;
}

static void elfloader_SetClassHandle(class_handle_t class_handle) {
    elfloader_class_handle = class_handle;
}

static usb_status_t elfloader_Handler(class_handle_t class_handle, uint32_t event, void *param) {
    uint8_t dummy = 0;
    usb_status_t ret = kStatus_USB_Success;
    usb_device_endpoint_callback_message_struct_t *message =
        static_cast<usb_device_endpoint_callback_message_struct_t*>(param);
    switch (event) {
        case kUSB_DeviceHidEventRecvResponse:
            if (message->length != USB_UNINITIALIZED_VAL_32) {
                elfloader_recv(message->buffer, message->length);
            }
            USB_DeviceHidSend(elfloader_class_handle, elfloader_hid_endpoints[kTxEndpoint].endpointAddress, &dummy, 1);
            USB_DeviceHidRecv(elfloader_class_handle, elfloader_hid_endpoints[kRxEndpoint].endpointAddress, elfloader_data, sizeof(elfloader_data));
            break;
        case kUSB_DeviceHidEventGetReport:
            ret = kStatus_USB_InvalidRequest;
            break;
        case kUSB_DeviceHidEventSendResponse:
        case kUSB_DeviceHidEventSetIdle:
            break;
        default:
            ret = kStatus_USB_Error;
            break;
    }
    return ret;
}

static usb_device_class_config_struct_t elfloader_config_data_ = {
    elfloader_Handler, nullptr, &elfloader_class_struct,
};

typedef void (*entry_point)(void);
static void elfloader_main(void *param) {
    size_t elf_size;
    std::unique_ptr<uint8_t> application_elf;
    if (!param) {
        application_elf.reset(valiant::filesystem::ReadToMemory("/default.elf", &elf_size));
    } else {
        application_elf.reset(reinterpret_cast<uint8_t*>(param));
    }

    Elf32_Ehdr* elf_header = reinterpret_cast<Elf32_Ehdr*>(application_elf.get());
    assert(EF_ARM_EABI_VERSION(elf_header->e_flags) == EF_ARM_EABI_VER5);
    assert(elf_header->e_phentsize == sizeof(Elf32_Phdr));

    for (int i = 0; i < elf_header->e_phnum; ++i) {
        Elf32_Phdr *program_header = reinterpret_cast<Elf32_Phdr*>(application_elf.get() + elf_header->e_phoff + sizeof(Elf32_Phdr) * i);
        if (program_header->p_type != PT_LOAD) {
            continue;
        }
        if (program_header->p_filesz == 0) {
            continue;
        }
        memcpy(reinterpret_cast<void*>(program_header->p_paddr), application_elf.get() + program_header->p_offset, program_header->p_filesz);
    }

    entry_point entry_point_fn = reinterpret_cast<entry_point>(elf_header->e_entry);
    entry_point_fn();

    vTaskSuspend(NULL);
}

void usb_device_task(void *param) {
    while (true) {
        valiant::UsbDeviceTask::GetSingleton()->UsbDeviceTaskFn();
        taskYIELD();
    }
}

static void usb_timer_callback(TimerHandle_t timer) {
    vTaskSuspend(reinterpret_cast<TaskHandle_t>(pvTimerGetTimerID(timer)));
    xTaskCreate(elfloader_main, "elfloader_main", configMINIMAL_STACK_SIZE * 10, nullptr, APP_TASK_PRIORITY, NULL);
}

extern "C" int main(int argc, char **argv) {
    BOARD_InitHardware(false);
    valiant::filesystem::Init();

    TaskHandle_t usb_task;
    xTaskCreate(usb_device_task, "usb_device_task", configMINIMAL_STACK_SIZE * 10, NULL, USB_DEVICE_TASK_PRIORITY, &usb_task);
    usb_timer = xTimerCreate("usb_timer", pdMS_TO_TICKS(1000), pdFALSE, usb_task, usb_timer_callback);

    // See TRM chapter 10.3.1 for boot mode choices.
    // If boot mode is *not* the serial downloader, start the boot timer.
    if (SRC_GetBootMode(SRC) != kSerialDownloader) {
        xTimerStart(usb_timer, 0);
    }

    elfloader_hid_endpoints[0].endpointAddress =
        valiant::UsbDeviceTask::GetSingleton()->next_descriptor_value() | (USB_IN << 7);
    elfloader_hid_endpoints[1].endpointAddress =
        valiant::UsbDeviceTask::GetSingleton()->next_descriptor_value() | (USB_OUT << 7);
    elfloader_descriptor_data.in_ep.endpoint_address = elfloader_hid_endpoints[0].endpointAddress;
    elfloader_descriptor_data.out_ep.endpoint_address = elfloader_hid_endpoints[1].endpointAddress;
    elfloader_interfaces[0].interfaceNumber =
        valiant::UsbDeviceTask::GetSingleton()->next_interface_value();
    valiant::UsbDeviceTask::GetSingleton()->AddDevice(
        &elfloader_config_data_,
        elfloader_SetClassHandle,
        elfloader_HandleEvent,
        &elfloader_descriptor_data,
        sizeof(elfloader_descriptor_data)
    );

    valiant::UsbDeviceTask::GetSingleton()->Init();

    vTaskStartScheduler();
    return 0;
}
<commit_msg>Have ELFLoader halt loading if the ELF is missing<commit_after>#include "apps/ELFLoader/elf_loader.h"
#include "libs/base/filesystem.h"
#include "libs/base/reset.h"
#include "libs/base/tasks.h"
#include "libs/nxp/rt1176-sdk/board_hardware.h"
#include "libs/tasks/UsbDeviceTask/usb_device_task.h"
#include "libs/usb/descriptors.h"
#include "third_party/freertos_kernel/include/FreeRTOS.h"
#include "third_party/freertos_kernel/include/task.h"
#include "third_party/freertos_kernel/include/timers.h"
#include "third_party/nxp/rt1176-sdk/devices/MIMXRT1176/drivers/fsl_soc_src.h"
#include <elf.h>
#include <memory>

/* Function definitions */
static void elfloader_main(void *param);
static void elfloader_recv(const uint8_t *buffer, uint32_t length);
static void usb_timer_callback(TimerHandle_t timer);
static bool elfloader_HandleEvent(uint32_t event, void *param);
static void elfloader_SetClassHandle(class_handle_t class_handle);
static usb_status_t elfloader_Handler(class_handle_t class_handle, uint32_t event, void *param);
void usb_device_task(void *param);

extern "C" uint32_t vPortGetRunTimeCounterValue(void) {
    return 0;
}

/* Static data definitions */
TimerHandle_t usb_timer;
static uint8_t* elfloader_recv_image = nullptr;
static char* elfloader_recv_path = nullptr;
static uint8_t elfloader_data[64];
static class_handle_t elfloader_class_handle;
static ElfloaderTarget elfloader_target = ElfloaderTarget::Ram;
static lfs_file_t file_handle;

static void elfloader_recv(const uint8_t *buffer, uint32_t length) {
    ElfloaderCommand cmd = static_cast<ElfloaderCommand>(buffer[0]);
    const ElfloaderSetSize *set_size = reinterpret_cast<const ElfloaderSetSize*>(&buffer[1]);
    const ElfloaderBytes *bytes = reinterpret_cast<const ElfloaderBytes*>(&buffer[1]);
    const ElfloaderTarget *target = reinterpret_cast<const ElfloaderTarget*>(&buffer[1]);
    xTimerStop(usb_timer, 0);
    switch (cmd) {
        case ElfloaderCommand::SetSize:
            assert(length == sizeof(ElfloaderSetSize) + 1);
            switch (elfloader_target) {
                case ElfloaderTarget::Filesystem:
                    break;
                case ElfloaderTarget::Ram:
                    elfloader_recv_image = (uint8_t*)malloc(set_size->size);
                    break;
                case ElfloaderTarget::Path:
                    elfloader_recv_path = (char*)malloc(set_size->size + 1);
                    memset(elfloader_recv_path, 0, set_size->size + 1);
                    break;
            }
            break;
        case ElfloaderCommand::Bytes:
            assert(length >= sizeof(ElfloaderBytes) + 1);
            switch (elfloader_target) {
                case ElfloaderTarget::Ram:
                    memcpy(elfloader_recv_image + bytes->offset, &buffer[1] + sizeof(ElfloaderBytes), bytes->size);
                    break;
                case ElfloaderTarget::Path:
                    memcpy(elfloader_recv_path + bytes->offset, &buffer[1] + sizeof(ElfloaderBytes), bytes->size);
                    break;
                case ElfloaderTarget::Filesystem:
                    valiant::filesystem::Write(&file_handle, &buffer[1] + sizeof(ElfloaderBytes), bytes->size);
                    break;
            }
            break;
        case ElfloaderCommand::Done:
            switch (elfloader_target) {
                case ElfloaderTarget::Ram:
                    xTaskCreate(elfloader_main, "elfloader_main", configMINIMAL_STACK_SIZE * 10, elfloader_recv_image, APP_TASK_PRIORITY, NULL);
                    break;
                case ElfloaderTarget::Path: {
                        // TODO(atv): This stuff can fail. We should propagate errors back to the Python side if possible.
                        auto dir = valiant::filesystem::Dirname(elfloader_recv_path);
                        valiant::filesystem::MakeDirs(dir.get());
                        valiant::filesystem::Open(&file_handle, elfloader_recv_path, true);
                        free(elfloader_recv_path);
                        elfloader_recv_path = nullptr;
                    }
                    break;
                case ElfloaderTarget::Filesystem:
                    valiant::filesystem::Close(&file_handle);
                    break;
            }
            break;
        case ElfloaderCommand::Reset:
            valiant::ResetToBootloader();
            break;
        case ElfloaderCommand::Target:
            elfloader_target = *target;
            break;
    }
}

static bool elfloader_HandleEvent(uint32_t event, void *param) {
    bool ret = true;
    usb_device_get_hid_descriptor_struct_t* get_hid_descriptor =
        static_cast<usb_device_get_hid_descriptor_struct_t*>(param);
    switch (event) {
        case kUSB_DeviceEventSetConfiguration:
            USB_DeviceHidRecv(elfloader_class_handle, elfloader_hid_endpoints[kRxEndpoint].endpointAddress, elfloader_data, sizeof(elfloader_data));
            break;
        case kUSB_DeviceEventGetHidReportDescriptor:
            get_hid_descriptor->buffer = elfloader_hid_report;
            get_hid_descriptor->length = elfloader_hid_report_size;
            get_hid_descriptor->interfaceNumber = elfloader_interfaces[0].interfaceNumber;
            break;
        default:
            ret = false;
            break;
    }
    return ret;
}

static void elfloader_SetClassHandle(class_handle_t class_handle) {
    elfloader_class_handle = class_handle;
}

static usb_status_t elfloader_Handler(class_handle_t class_handle, uint32_t event, void *param) {
    uint8_t dummy = 0;
    usb_status_t ret = kStatus_USB_Success;
    usb_device_endpoint_callback_message_struct_t *message =
        static_cast<usb_device_endpoint_callback_message_struct_t*>(param);
    switch (event) {
        case kUSB_DeviceHidEventRecvResponse:
            if (message->length != USB_UNINITIALIZED_VAL_32) {
                elfloader_recv(message->buffer, message->length);
            }
            USB_DeviceHidSend(elfloader_class_handle, elfloader_hid_endpoints[kTxEndpoint].endpointAddress, &dummy, 1);
            USB_DeviceHidRecv(elfloader_class_handle, elfloader_hid_endpoints[kRxEndpoint].endpointAddress, elfloader_data, sizeof(elfloader_data));
            break;
        case kUSB_DeviceHidEventGetReport:
            ret = kStatus_USB_InvalidRequest;
            break;
        case kUSB_DeviceHidEventSendResponse:
        case kUSB_DeviceHidEventSetIdle:
            break;
        default:
            ret = kStatus_USB_Error;
            break;
    }
    return ret;
}

static usb_device_class_config_struct_t elfloader_config_data_ = {
    elfloader_Handler, nullptr, &elfloader_class_struct,
};

typedef void (*entry_point)(void);
static void elfloader_main(void *param) {
    size_t elf_size = 0;
    std::unique_ptr<uint8_t> application_elf;
    if (!param) {
        application_elf.reset(valiant::filesystem::ReadToMemory("/default.elf", &elf_size));
    } else {
        application_elf.reset(reinterpret_cast<uint8_t*>(param));
    }

    // If we do not have an application for any reason, suspend this thread.
    // Otherwise, suspend the USB thread so that the host cannot try to talk to us
    // and cause confusion.
    if (!application_elf || (!param && elf_size == 0)) {
        vTaskSuspend(NULL);
    } else {
        vTaskSuspend(reinterpret_cast<TaskHandle_t>(pvTimerGetTimerID(usb_timer)));
    }

    Elf32_Ehdr* elf_header = reinterpret_cast<Elf32_Ehdr*>(application_elf.get());
    assert(EF_ARM_EABI_VERSION(elf_header->e_flags) == EF_ARM_EABI_VER5);
    assert(elf_header->e_phentsize == sizeof(Elf32_Phdr));

    for (int i = 0; i < elf_header->e_phnum; ++i) {
        Elf32_Phdr *program_header = reinterpret_cast<Elf32_Phdr*>(application_elf.get() + elf_header->e_phoff + sizeof(Elf32_Phdr) * i);
        if (program_header->p_type != PT_LOAD) {
            continue;
        }
        if (program_header->p_filesz == 0) {
            continue;
        }
        memcpy(reinterpret_cast<void*>(program_header->p_paddr), application_elf.get() + program_header->p_offset, program_header->p_filesz);
    }

    entry_point entry_point_fn = reinterpret_cast<entry_point>(elf_header->e_entry);
    entry_point_fn();

    vTaskSuspend(NULL);
}

void usb_device_task(void *param) {
    while (true) {
        valiant::UsbDeviceTask::GetSingleton()->UsbDeviceTaskFn();
        taskYIELD();
    }
}

static void usb_timer_callback(TimerHandle_t timer) {
    xTaskCreate(elfloader_main, "elfloader_main", configMINIMAL_STACK_SIZE * 10, nullptr, APP_TASK_PRIORITY, NULL);
}

extern "C" int main(int argc, char **argv) {
    BOARD_InitHardware(false);
    valiant::filesystem::Init();

    TaskHandle_t usb_task;
    xTaskCreate(usb_device_task, "usb_device_task", configMINIMAL_STACK_SIZE * 10, NULL, USB_DEVICE_TASK_PRIORITY, &usb_task);
    usb_timer = xTimerCreate("usb_timer", pdMS_TO_TICKS(1000), pdFALSE, usb_task, usb_timer_callback);

    // See TRM chapter 10.3.1 for boot mode choices.
    // If boot mode is *not* the serial downloader, start the boot timer.
    if (SRC_GetBootMode(SRC) != kSerialDownloader) {
        xTimerStart(usb_timer, 0);
    }

    elfloader_hid_endpoints[0].endpointAddress =
        valiant::UsbDeviceTask::GetSingleton()->next_descriptor_value() | (USB_IN << 7);
    elfloader_hid_endpoints[1].endpointAddress =
        valiant::UsbDeviceTask::GetSingleton()->next_descriptor_value() | (USB_OUT << 7);
    elfloader_descriptor_data.in_ep.endpoint_address = elfloader_hid_endpoints[0].endpointAddress;
    elfloader_descriptor_data.out_ep.endpoint_address = elfloader_hid_endpoints[1].endpointAddress;
    elfloader_interfaces[0].interfaceNumber =
        valiant::UsbDeviceTask::GetSingleton()->next_interface_value();
    valiant::UsbDeviceTask::GetSingleton()->AddDevice(
        &elfloader_config_data_,
        elfloader_SetClassHandle,
        elfloader_HandleEvent,
        &elfloader_descriptor_data,
        sizeof(elfloader_descriptor_data)
    );

    valiant::UsbDeviceTask::GetSingleton()->Init();

    vTaskStartScheduler();
    return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright deipi.com LLC and contributors. All rights reserved.
 *
 * 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 <assert.h>
#include <sys/socket.h>
#include <unistd.h>

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

const int WRITE_QUEUE_SIZE = 10;

BaseClient::BaseClient(XapiandServer *server_, ev::loop_ref *loop, int sock_, DatabasePool *database_pool_, ThreadPool *thread_pool_, double active_timeout_, double idle_timeout_)
	: server(server_),
	  iterator(server->attach_client(this)),
	  io_read(*loop),
	  io_write(*loop),
	  async_write(*loop),
	  closed(false),
	  sock(sock_),
	  database_pool(database_pool_),
	  thread_pool(thread_pool_),
	  write_queue(WRITE_QUEUE_SIZE)
{
	inc_ref();

	pthread_mutexattr_init(&qmtx_attr);
	pthread_mutexattr_settype(&qmtx_attr, PTHREAD_MUTEX_RECURSIVE);
	pthread_mutex_init(&qmtx, &qmtx_attr);

	pthread_mutex_lock(&XapiandServer::static_mutex);
	int total_clients = ++XapiandServer::total_clients;
	pthread_mutex_unlock(&XapiandServer::static_mutex);

	async_write.set<BaseClient, &BaseClient::async_write_cb>(this);
	async_write.start();

	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);

	LOG_OBJ(this, "CREATED CLIENT! (%d clients)\n", total_clients);
}

BaseClient::~BaseClient()
{
	destroy();

	while(!write_queue.empty()) {
		Buffer *buffer;
		if (write_queue.pop(buffer, 0)) {
			delete buffer;
		}
	}

	server->detach_client(this);

	pthread_mutex_lock(&XapiandServer::static_mutex);
	int total_clients = --XapiandServer::total_clients;
	pthread_mutex_unlock(&XapiandServer::static_mutex);

	pthread_mutex_destroy(&qmtx);
	pthread_mutexattr_destroy(&qmtx_attr);

	LOG_OBJ(this, "DELETED CLIENT! (%d clients left)\n", total_clients);
	assert(total_clients >= 0);
}

void BaseClient::destroy()
{
	close();

	pthread_mutex_lock(&qmtx);
	if (sock == -1) {
		pthread_mutex_unlock(&qmtx);
		return;
	}

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

	::close(sock);
	sock = -1;
	pthread_mutex_unlock(&qmtx);

	write_queue.clear();

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

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

	closed = true;
	LOG_OBJ(this, "CLOSED CLIENT!\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) {
		rel_ref();
	}

}

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 (sock != -1 && !write_queue.empty()) {
		Buffer* buffer = write_queue.front();

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

		LOG_CONN_WIRE(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) {
				if(write_queue.pop(buffer)) {
					delete buffer;
				}
			}
		}
	}
}

void BaseClient::read_cb()
{
	if (sock != -1) {
		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_WIRE(this, "(sock=%d) -->> '%s'\n", sock, repr(buf, received).c_str());
			on_read(buf, received);
		}
	}
}

void BaseClient::async_write_cb(ev::async &watcher, int revents)
{
	io_update();
}

bool BaseClient::write(const char *buf, size_t buf_size)
{
	LOG_CONN_WIRE(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);

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

	async_write.send();

	return true;
}

void BaseClient::shutdown()
{
	if (server->manager->shutdown_now) {
		LOG_EV(this, "Signaled destroy!!\n");
		destroy();
		rel_ref();
	}
}
<commit_msg>Don´t destroy if socket is invalid<commit_after>/*
 * Copyright deipi.com LLC and contributors. All rights reserved.
 *
 * 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 <assert.h>
#include <sys/socket.h>
#include <unistd.h>

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

const int WRITE_QUEUE_SIZE = 10;

BaseClient::BaseClient(XapiandServer *server_, ev::loop_ref *loop, int sock_, DatabasePool *database_pool_, ThreadPool *thread_pool_, double active_timeout_, double idle_timeout_)
	: server(server_),
	  iterator(server->attach_client(this)),
	  io_read(*loop),
	  io_write(*loop),
	  async_write(*loop),
	  closed(false),
	  sock(sock_),
	  database_pool(database_pool_),
	  thread_pool(thread_pool_),
	  write_queue(WRITE_QUEUE_SIZE)
{
	inc_ref();

	pthread_mutexattr_init(&qmtx_attr);
	pthread_mutexattr_settype(&qmtx_attr, PTHREAD_MUTEX_RECURSIVE);
	pthread_mutex_init(&qmtx, &qmtx_attr);

	pthread_mutex_lock(&XapiandServer::static_mutex);
	int total_clients = ++XapiandServer::total_clients;
	pthread_mutex_unlock(&XapiandServer::static_mutex);

	async_write.set<BaseClient, &BaseClient::async_write_cb>(this);
	async_write.start();

	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);

	LOG_OBJ(this, "CREATED CLIENT! (%d clients)\n", total_clients);
}

BaseClient::~BaseClient()
{
	destroy();

	while(!write_queue.empty()) {
		Buffer *buffer;
		if (write_queue.pop(buffer, 0)) {
			delete buffer;
		}
	}

	server->detach_client(this);

	pthread_mutex_lock(&XapiandServer::static_mutex);
	int total_clients = --XapiandServer::total_clients;
	pthread_mutex_unlock(&XapiandServer::static_mutex);

	pthread_mutex_destroy(&qmtx);
	pthread_mutexattr_destroy(&qmtx_attr);

	LOG_OBJ(this, "DELETED CLIENT! (%d clients left)\n", total_clients);
	assert(total_clients >= 0);
}

void BaseClient::destroy()
{
	close();

	pthread_mutex_lock(&qmtx);
	if (sock == -1) {
		pthread_mutex_unlock(&qmtx);
		return;
	}

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

	::close(sock);
	sock = -1;
	pthread_mutex_unlock(&qmtx);

	write_queue.clear();

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

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

	closed = true;
	LOG_OBJ(this, "CLOSED CLIENT!\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) {
		rel_ref();
	}

}

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 (sock != -1 && !write_queue.empty()) {
		Buffer* buffer = write_queue.front();

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

		LOG_CONN_WIRE(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 && sock != -1) {
				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) {
				if(write_queue.pop(buffer)) {
					delete buffer;
				}
			}
		}
	}
}

void BaseClient::read_cb()
{
	if (sock != -1) {
		char buf[1024];

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

		if (received < 0) {
			if (errno != EAGAIN && sock != -1) {
				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_WIRE(this, "(sock=%d) -->> '%s'\n", sock, repr(buf, received).c_str());
			on_read(buf, received);
		}
	}
}

void BaseClient::async_write_cb(ev::async &watcher, int revents)
{
	io_update();
}

bool BaseClient::write(const char *buf, size_t buf_size)
{
	LOG_CONN_WIRE(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);

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

	async_write.send();

	return true;
}

void BaseClient::shutdown()
{
	if (server->manager->shutdown_now) {
		LOG_EV(this, "Signaled destroy!!\n");
		destroy();
		rel_ref();
	}
}
<|endoftext|>


<commit_before>/**
 * @author: Jeff Thompson
 * See COPYING for copyright and distribution information.
 */

#ifndef NDN_BLOB_HPP
#define	NDN_BLOB_HPP

#include "../common.hpp"

namespace ndn {

/**
 * A Blob holds a pointer to an immutable byte array.
 */
class Blob {
public:
  /**
   * Create a new Blob with an immutable copy of the given array.
   * @param value A pointer to the byte array which is copied.
   * @param valueLength The length of value.
   */
  Blob(const unsigned char* value, unsigned int valueLength)
  : value_(new std::vector<unsigned char>(value, value + valueLength))
  {
  }

  /**
   * Create a new Blob with an immutable copy of the array in the given vector.
   * @param value A reference to a vector which is copied.
   */
  Blob(const std::vector<unsigned char> &value)
  : value_(new std::vector<unsigned char>(value))
  {
  }

  /**
   * Create a new Blob to point to an existing byte array.  IMPORTANT: After calling this constructor,
   * you must treat the array as immutable and promise not to change it.
   * @param value A pointer to a vector with the byte array.  This takes another reference and does not copy the bytes.
   */
  Blob(const ptr_lib::shared_ptr<std::vector<unsigned char> > &value)
  : value_(value)
  {
  }

  /**
   * Return a const reference to the immutable byte array.
   */
  const std::vector<unsigned char>& getValue() const
  {
    return *value_;
  }

  /**
   * Return the length of the immutable byte array.
   */
  unsigned int size() const
  {
    return value_->size();
  }

  /**
   * Get const pointer to the first byte of the immutable byte array.
   */
  const unsigned char* buffer() const
  {
    return &value_->front ();
  }

private:
  ptr_lib::shared_ptr<std::vector<unsigned char> > value_;
};

}

#endif
<commit_msg>Update documentation.<commit_after>/**
 * @author: Jeff Thompson
 * See COPYING for copyright and distribution information.
 */

#ifndef NDN_BLOB_HPP
#define	NDN_BLOB_HPP

#include "../common.hpp"

namespace ndn {

/**
 * A Blob holds a pointer to an immutable byte array.  This is like a JavaScript string which is a pointer
 * to an immutable string.  It is OK to pass a pointer to the string because the new owner can't change the bytes
 * of the string.  However, like a JavaScript string, it is possible to change the pointer, and so this does allow
 * the copy constructor and assignment to change the pointer.
 */
class Blob {
public:
  /**
   * Create a new Blob with an immutable copy of the given array.
   * @param value A pointer to the byte array which is copied.
   * @param valueLength The length of value.
   */
  Blob(const unsigned char* value, unsigned int valueLength)
  : value_(new std::vector<unsigned char>(value, value + valueLength))
  {
  }

  /**
   * Create a new Blob with an immutable copy of the array in the given vector.
   * If you want to transfer the array without copying, the the vector has to start as a
   * ptr_lib::shared_ptr<std::vector<unsigned char> > and you can use the Blob constructor with this type.
   * @param value A reference to a vector which is copied.
   */
  Blob(const std::vector<unsigned char> &value)
  : value_(new std::vector<unsigned char>(value))
  {
  }

  /**
   * Create a new Blob to point to an existing byte array.  IMPORTANT: After calling this constructor,
   * you must treat the array as immutable and promise not to change it.
   * @param value A pointer to a vector with the byte array.  This takes another reference and does not copy the bytes.
   */
  Blob(const ptr_lib::shared_ptr<std::vector<unsigned char> > &value)
  : value_(value)
  {
  }

  /**
   * Return a const reference to the immutable byte array.
   */
  const std::vector<unsigned char>& getValue() const
  {
    return *value_;
  }

  /**
   * Return the length of the immutable byte array.
   */
  unsigned int size() const
  {
    return value_->size();
  }

  /**
   * Get const pointer to the first byte of the immutable byte array.
   */
  const unsigned char* buffer() const
  {
    return &value_->front ();
  }

private:
  ptr_lib::shared_ptr<std::vector<unsigned char> > value_;
};

}

#endif
<|endoftext|>


<commit_before>/*
  Copyright(C) 2014 Naoya Murakami <naoya@createfield.com>

  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.

  This file includes the original word2vec's code. https://code.google.com/p/word2vec/
  The following is the header of the file:

    Copyright 2013 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 <stdio.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <string>
#include <stdexcept>
#include <vector>

#include <math.h>
#include <malloc.h>

#include <unicode/normlzr.h>
#include <re2/re2.h>
#include <google/gflags.h>

DEFINE_string(file_path, "", "Input binary file learned by word2vec");
DEFINE_string(input, "", "Input expression string");
DEFINE_int32(output, 1, "1:word,discatnce 2:word 3:split by commma 4:split by tab");
DEFINE_int32(offset, 0, "offset");
DEFINE_int32(limit, -1, "limit -1:all");
DEFINE_double(threshold, 0, "threshold (ex. --threshold 0.75)");
DEFINE_bool(no_normalize, false, "Don't use NFKC normalize");
DEFINE_string(term_filter, "", "Filter by regular expresion pattern to term");
DEFINE_string(output_filter, "", "Cut by regular expresion pattern to term");
DEFINE_bool(server, false, "Server mode");
DEFINE_string(ip, "", "IP address");
DEFINE_string(port, "", "Port number");
DEFINE_bool(h, false, "Help message");

using namespace std;

const long long max_size = 2000;         // max length of strings
const long long N = 40;                  // number of closest words that will be shown
const long long max_w = 50;              // max length of vocabulary entries

long long words, size = 0;
float *M = NULL;
char *vocab = NULL;

string
normalize(const string str)
{
  icu::UnicodeString src;
  icu::UnicodeString dest;
  src = str.c_str();
  UErrorCode status;
  status = U_ZERO_ERROR;
  Normalizer::normalize(src, UNORM_NFKC, 0, dest, status);
  if(U_FAILURE(status)) {
    throw runtime_error("Unicode normalization failed");
  }
  string result;
  dest.toUTF8String(result);
  transform(result.begin(), result.end(), result.begin(), ::tolower);
  return result;
}

bool
word2vec_load(const char *file_name)
{
  FILE *f;
  float len;
  long long a, b;
  char ch;

  f = fopen(file_name, "rb");
  if (f == NULL) {
    printf("Input file not found : %s\n", file_name);
    return false;
  }

  fscanf(f, "%lld", &words);
  fscanf(f, "%lld", &size);
  vocab = (char *)malloc((long long)words * max_w * sizeof(char));
  M = (float *)malloc((long long)words * (long long)size * sizeof(float));
  if (M == NULL) {
    printf("Cannot allocate memory: %lld MB %lld %lld",
           (long long)words * size * sizeof(float) / 1048576, words, size);
    return false;
  }
  for (b = 0; b < words; b++) {
    fscanf(f, "%s%c", &vocab[b * max_w], &ch);
    for (a = 0; a < size; a++) fread(&M[a + b * size], sizeof(float), 1, f);
    len = 0;
    for (a = 0; a < size; a++) len += M[a + b * size] * M[a + b * size];
    len = sqrt(len);
    for (a = 0; a < size; a++) M[a + b * size] /= len;
  }
  fclose(f);

  return true;
}

vector<string>
split(const string &str, char delim){
  vector<string> res;
  size_t current = 0, found;
  while((found = str.find_first_of(delim, current)) != string::npos){
    res.push_back(string(str, current, found - current));
    current = found + 1;
  }
  res.push_back(string(str, current, str.size() - current));
  return res;
}

int
calc(string str, int output, int offset, int limit, double threshold,
     bool no_normalize, const char *term_filter, const char *output_filter){
  char st1[max_size];
  char bestw[N][max_size];
  char st[100][max_size];
  char op[100];
  float dist, len, bestd[N], vec[max_size];
  long long a, b, c, d, cn, bi[100];

  for (a = 0; a < N; a++) bestd[a] = 0;
  for (a = 0; a < N; a++) bestw[a][0] = 0;

  st1[0] = 0;

  for(unsigned int i = 0; i < 100; i++){
    st[i][0] = 0;
    op[i] = '+';
  }

  if(!no_normalize){
    str = normalize(str);
  }
  re2::RE2::GlobalReplace(&str, "　", " ");

  vector<string> result_array;
  result_array = split(str, ' ');
  string result;

  int op_row = 1;
  for(unsigned int i = 0; i < result_array.size(); ++i )
  {
    if(result_array[i] == "+"){
      op[op_row] = '+';
      op_row++;
    }
    else if(result_array[i] == "-"){
      op[op_row] = '-';
      op_row++;
    } else {
      result += result_array[i];
      if ( i < result_array.size() - 1) {
        result += " ";
      }
    }
  }
  strcat(st1, result.c_str());

  cn = 0;
  b = 0;
  c = 0;
  while (1) {
    st[cn][b] = st1[c];
    b++;
    c++;
    st[cn][b] = 0;
    if (st1[c] == 0) break;
    if (st1[c] == ' ') {
      cn++;
      b = 0;
      c++;
    }
  }
  cn++;

  for (a = 0; a < cn; a++) {
    for (b = 0; b < words; b++) if (!strcmp(&vocab[b * max_w], st[a])) break;
    if (b == words) b = 0;
    bi[a] = b;
    if (output == 1) {
      printf("\nWord: %s  Position in vocabulary: %lld\n", st[a], bi[a]);
    }
    if (b == 0) {
      if (output == 1 || output == 2) {
        printf("Out of dictionary word!\n");
      }
      break;
    }
  }
  if (b == 0) return -1;
  if(cn == 1) {
    for (a = 0; a < size; a++) vec[a] = 0;
    for (b = 0; b < cn; b++) {
      if (bi[b] == -1) continue;
      for (a = 0; a < size; a++) vec[a] += M[a + bi[b] * size];
    }
  } else {
    for (a = 0; a < size; a++) vec[a] = 0;
    for (a = 0; a < size; a++) {
      for (b = 0; b < cn; b++) {
        if(op[b] == '-') {
          vec[a] -= M[a + bi[b] * size];
        } else {
          vec[a] += M[a + bi[b] * size];
        }
      }
    }
  }

  len = 0;
  for (a = 0; a < size; a++) len += vec[a] * vec[a];
  len = sqrt(len);
  for (a = 0; a < size; a++) vec[a] /= len;
  for (a = 0; a < N; a++) bestd[a] = 0;
  for (a = 0; a < N; a++) bestw[a][0] = 0;
  for (c = 0; c < words; c++) {
    a = 0;
    for (b = 0; b < cn; b++) if (bi[b] == c) a = 1;
    if (a == 1) continue;
    dist = 0;
    for (a = 0; a < size; a++) dist += vec[a] * M[a + c * size];
    for (a = 0; a < N; a++) {
      if (dist > bestd[a]) {
        if (threshold > 0 && dist < threshold) {
          break;
        }
        if (term_filter != NULL) {
          string s = &load_vocab[c * max_w];
          string t = term_filter;
          if ( RE2::FullMatch(s, t) ) {
            break;
          }
        }
        for (d = N - 1; d > a; d--) {
          bestd[d] = bestd[d - 1];
          strcpy(bestw[d], bestw[d - 1]);
        }
        bestd[a] = dist;
        strcpy(bestw[a], &vocab[c * max_w]);
        break;
      }
    }
  }

  unsigned int max;
  if (offset + limit > N) {
    max = N;
  } else {
    max = offset + limit;
  }

  for (a = offset; a < max; a++) {
    if (output_filter != NULL) {
      string s = bestw[a];
      re2::RE2::GlobalReplace(&s, output_filter, "");
      strcpy(bestw[a],s.c_str());
    }
    if ( a == 0 ) {
        switch(output) {
          case 3 :
            printf("%s", str.c_str());
            printf(",");
            break;
          case 4 :
            printf("%s", str.c_str());
            printf("\t");
            // for Groonga Groongaのシノニムは自身を含める必要あり。
            if(cn == 1) {
              printf("%s", str.c_str());
              printf("\t");
            }
            break;
        }
    }
    if (strlen(bestw[a]) > 0 && bestd[a] != 0) {
      if ( a < max - 1){
        switch(output) {
          case 1 :
            printf("%f\t%s\n", bestd[a], bestw[a]);
            break;
          case 2 :
            printf("%s\n", bestw[a]);
            break;
          case 3 :
            printf("%s", bestw[a]);
            printf(",");
            break;
          case 4 :
            printf("%s", bestw[a]);
            printf("\t");
            break;
        }
      } else {
        switch(output) {
          case 1 :
            printf("%f\t%s\n", bestd[a], bestw[a]);
            break;
          case 2 :
            printf("%s\n", bestw[a]);
            break;
          case 3 :
            printf("%s", bestw[a]);
            break;
          case 4 :
            printf("%s", bestw[a]);
            break;
        }
      }
    } else {
      if (max < N) {
        max++;
      }
    }
  }
  printf("\n");

  return 0;
}

int
main(int argc, char **argv) {
  const char *file_name = "/var/lib/word2vec/learn.bin";
  string str;

  google::ParseCommandLineFlags(&argc, &argv, true);

  if(FLAGS_h == true){
    printf(" --file_path : Input binary file learned by word2vec\n");
    printf(" --iuput : Input expression string\n");
    printf(" --output : 1:word,discatnce 2:word 3:split by commma 4:split by tab\n");
    printf(" --offset : offset\n");
    printf(" --limit : limit -1:all\n");
    printf(" --threshold : threshold (ex. --threshold 0.75)\n");
    printf(" --no_normalize : Don't use NFKC normalize\n");
    printf(" --term_filter : Filter by regular expresion pattern to term\n");
    printf(" --output_filter : Cut by regular expresion pattern to term\n");
    printf(" --server : Server mode\n");
    printf(" --ip : IP address\n");
    printf(" --port : Port number\n");
    exit(0);
  }

  if (FLAGS_file_path != "") {
    file_name = FLAGS_file_path.c_str();
  }

  if(word2vec_load(file_name) == false){
    printf("Load file failed\n");
    return -1;
  }

  int limit;
  if(FLAGS_limit == -1){
    limit = (int)N;
  } else {
    limit = FLAGS_limit;
  }
  if(FLAGS_input == ""){
    if(FLAGS_output == 1){
      printf("> ");
    }
    while(getline(cin, str)){
      if(str == "EXIT"){
        break;
      }
      calc(str, FLAGS_output, FLAGS_offset, limit, FLAGS_threshold,
           FLAGS_no_normalize, FLAGS_term_filter.c_str(),
           FLAGS_output_filter.c_str());
      if(FLAGS_output == 1){
        printf("> ");
      }
    }
  } else {
    if(FLAGS_output == 1){
      printf("> ");
    }
    ifstream ifs(FLAGS_input.c_str());
    if(ifs.fail()) {
      cerr << "File do not exist.\n";
      exit(0);
    }
    while(getline(ifs, str)){
      calc(str, FLAGS_output, FLAGS_offset, limit, FLAGS_threshold,
           FLAGS_no_normalize, FLAGS_term_filter.c_str(),
           FLAGS_output_filter.c_str());
      if(FLAGS_output == 1){
        printf("> ");
      }
    }
  }

  return 0;
}
<commit_msg>Fix wrong variable<commit_after>/*
  Copyright(C) 2014 Naoya Murakami <naoya@createfield.com>

  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.

  This file includes the original word2vec's code. https://code.google.com/p/word2vec/
  The following is the header of the file:

    Copyright 2013 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 <stdio.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <string>
#include <stdexcept>
#include <vector>

#include <math.h>
#include <malloc.h>

#include <unicode/normlzr.h>
#include <re2/re2.h>
#include <google/gflags.h>

DEFINE_string(file_path, "", "Input binary file learned by word2vec");
DEFINE_string(input, "", "Input expression string");
DEFINE_int32(output, 1, "1:word,discatnce 2:word 3:split by commma 4:split by tab");
DEFINE_int32(offset, 0, "offset");
DEFINE_int32(limit, -1, "limit -1:all");
DEFINE_double(threshold, 0, "threshold (ex. --threshold 0.75)");
DEFINE_bool(no_normalize, false, "Don't use NFKC normalize");
DEFINE_string(term_filter, "", "Filter by regular expresion pattern to term");
DEFINE_string(output_filter, "", "Cut by regular expresion pattern to term");
DEFINE_bool(server, false, "Server mode");
DEFINE_string(ip, "", "IP address");
DEFINE_string(port, "", "Port number");
DEFINE_bool(h, false, "Help message");

using namespace std;

const long long max_size = 2000;         // max length of strings
const long long N = 40;                  // number of closest words that will be shown
const long long max_w = 50;              // max length of vocabulary entries

long long words, size = 0;
float *M = NULL;
char *vocab = NULL;

string
normalize(const string str)
{
  icu::UnicodeString src;
  icu::UnicodeString dest;
  src = str.c_str();
  UErrorCode status;
  status = U_ZERO_ERROR;
  Normalizer::normalize(src, UNORM_NFKC, 0, dest, status);
  if(U_FAILURE(status)) {
    throw runtime_error("Unicode normalization failed");
  }
  string result;
  dest.toUTF8String(result);
  transform(result.begin(), result.end(), result.begin(), ::tolower);
  return result;
}

bool
word2vec_load(const char *file_name)
{
  FILE *f;
  float len;
  long long a, b;
  char ch;

  f = fopen(file_name, "rb");
  if (f == NULL) {
    printf("Input file not found : %s\n", file_name);
    return false;
  }

  fscanf(f, "%lld", &words);
  fscanf(f, "%lld", &size);
  vocab = (char *)malloc((long long)words * max_w * sizeof(char));
  M = (float *)malloc((long long)words * (long long)size * sizeof(float));
  if (M == NULL) {
    printf("Cannot allocate memory: %lld MB %lld %lld",
           (long long)words * size * sizeof(float) / 1048576, words, size);
    return false;
  }
  for (b = 0; b < words; b++) {
    fscanf(f, "%s%c", &vocab[b * max_w], &ch);
    for (a = 0; a < size; a++) fread(&M[a + b * size], sizeof(float), 1, f);
    len = 0;
    for (a = 0; a < size; a++) len += M[a + b * size] * M[a + b * size];
    len = sqrt(len);
    for (a = 0; a < size; a++) M[a + b * size] /= len;
  }
  fclose(f);

  return true;
}

vector<string>
split(const string &str, char delim){
  vector<string> res;
  size_t current = 0, found;
  while((found = str.find_first_of(delim, current)) != string::npos){
    res.push_back(string(str, current, found - current));
    current = found + 1;
  }
  res.push_back(string(str, current, str.size() - current));
  return res;
}

int
calc(string str, int output, int offset, int limit, double threshold,
     bool no_normalize, const char *term_filter, const char *output_filter){
  char st1[max_size];
  char bestw[N][max_size];
  char st[100][max_size];
  char op[100];
  float dist, len, bestd[N], vec[max_size];
  long long a, b, c, d, cn, bi[100];

  for (a = 0; a < N; a++) bestd[a] = 0;
  for (a = 0; a < N; a++) bestw[a][0] = 0;

  st1[0] = 0;

  for(unsigned int i = 0; i < 100; i++){
    st[i][0] = 0;
    op[i] = '+';
  }

  if(!no_normalize){
    str = normalize(str);
  }
  re2::RE2::GlobalReplace(&str, "　", " ");

  vector<string> result_array;
  result_array = split(str, ' ');
  string result;

  int op_row = 1;
  for(unsigned int i = 0; i < result_array.size(); ++i )
  {
    if(result_array[i] == "+"){
      op[op_row] = '+';
      op_row++;
    }
    else if(result_array[i] == "-"){
      op[op_row] = '-';
      op_row++;
    } else {
      result += result_array[i];
      if ( i < result_array.size() - 1) {
        result += " ";
      }
    }
  }
  strcat(st1, result.c_str());

  cn = 0;
  b = 0;
  c = 0;
  while (1) {
    st[cn][b] = st1[c];
    b++;
    c++;
    st[cn][b] = 0;
    if (st1[c] == 0) break;
    if (st1[c] == ' ') {
      cn++;
      b = 0;
      c++;
    }
  }
  cn++;

  for (a = 0; a < cn; a++) {
    for (b = 0; b < words; b++) if (!strcmp(&vocab[b * max_w], st[a])) break;
    if (b == words) b = 0;
    bi[a] = b;
    if (output == 1) {
      printf("\nWord: %s  Position in vocabulary: %lld\n", st[a], bi[a]);
    }
    if (b == 0) {
      if (output == 1 || output == 2) {
        printf("Out of dictionary word!\n");
      }
      break;
    }
  }
  if (b == 0) return -1;
  if(cn == 1) {
    for (a = 0; a < size; a++) vec[a] = 0;
    for (b = 0; b < cn; b++) {
      if (bi[b] == -1) continue;
      for (a = 0; a < size; a++) vec[a] += M[a + bi[b] * size];
    }
  } else {
    for (a = 0; a < size; a++) vec[a] = 0;
    for (a = 0; a < size; a++) {
      for (b = 0; b < cn; b++) {
        if(op[b] == '-') {
          vec[a] -= M[a + bi[b] * size];
        } else {
          vec[a] += M[a + bi[b] * size];
        }
      }
    }
  }

  len = 0;
  for (a = 0; a < size; a++) len += vec[a] * vec[a];
  len = sqrt(len);
  for (a = 0; a < size; a++) vec[a] /= len;
  for (a = 0; a < N; a++) bestd[a] = 0;
  for (a = 0; a < N; a++) bestw[a][0] = 0;
  for (c = 0; c < words; c++) {
    a = 0;
    for (b = 0; b < cn; b++) if (bi[b] == c) a = 1;
    if (a == 1) continue;
    dist = 0;
    for (a = 0; a < size; a++) dist += vec[a] * M[a + c * size];
    for (a = 0; a < N; a++) {
      if (dist > bestd[a]) {
        if (threshold > 0 && dist < threshold) {
          break;
        }
        if (term_filter != NULL) {
          string s = &vocab[c * max_w];
          string t = term_filter;
          if ( RE2::FullMatch(s, t) ) {
            break;
          }
        }
        for (d = N - 1; d > a; d--) {
          bestd[d] = bestd[d - 1];
          strcpy(bestw[d], bestw[d - 1]);
        }
        bestd[a] = dist;
        strcpy(bestw[a], &vocab[c * max_w]);
        break;
      }
    }
  }

  unsigned int max;
  if (offset + limit > N) {
    max = N;
  } else {
    max = offset + limit;
  }

  for (a = offset; a < max; a++) {
    if (output_filter != NULL) {
      string s = bestw[a];
      re2::RE2::GlobalReplace(&s, output_filter, "");
      strcpy(bestw[a],s.c_str());
    }
    if ( a == 0 ) {
        switch(output) {
          case 3 :
            printf("%s", str.c_str());
            printf(",");
            break;
          case 4 :
            printf("%s", str.c_str());
            printf("\t");
            // for Groonga Groongaのシノニムは自身を含める必要あり。
            if(cn == 1) {
              printf("%s", str.c_str());
              printf("\t");
            }
            break;
        }
    }
    if (strlen(bestw[a]) > 0 && bestd[a] != 0) {
      if ( a < max - 1){
        switch(output) {
          case 1 :
            printf("%f\t%s\n", bestd[a], bestw[a]);
            break;
          case 2 :
            printf("%s\n", bestw[a]);
            break;
          case 3 :
            printf("%s", bestw[a]);
            printf(",");
            break;
          case 4 :
            printf("%s", bestw[a]);
            printf("\t");
            break;
        }
      } else {
        switch(output) {
          case 1 :
            printf("%f\t%s\n", bestd[a], bestw[a]);
            break;
          case 2 :
            printf("%s\n", bestw[a]);
            break;
          case 3 :
            printf("%s", bestw[a]);
            break;
          case 4 :
            printf("%s", bestw[a]);
            break;
        }
      }
    } else {
      if (max < N) {
        max++;
      }
    }
  }
  printf("\n");

  return 0;
}

int
main(int argc, char **argv) {
  const char *file_name = "/var/lib/word2vec/learn.bin";
  string str;

  google::ParseCommandLineFlags(&argc, &argv, true);

  if(FLAGS_h == true){
    printf(" --file_path : Input binary file learned by word2vec\n");
    printf(" --iuput : Input expression string\n");
    printf(" --output : 1:word,discatnce 2:word 3:split by commma 4:split by tab\n");
    printf(" --offset : offset\n");
    printf(" --limit : limit -1:all\n");
    printf(" --threshold : threshold (ex. --threshold 0.75)\n");
    printf(" --no_normalize : Don't use NFKC normalize\n");
    printf(" --term_filter : Filter by regular expresion pattern to term\n");
    printf(" --output_filter : Cut by regular expresion pattern to term\n");
    printf(" --server : Server mode\n");
    printf(" --ip : IP address\n");
    printf(" --port : Port number\n");
    exit(0);
  }

  if (FLAGS_file_path != "") {
    file_name = FLAGS_file_path.c_str();
  }

  if(word2vec_load(file_name) == false){
    printf("Load file failed\n");
    return -1;
  }

  int limit;
  if(FLAGS_limit == -1){
    limit = (int)N;
  } else {
    limit = FLAGS_limit;
  }
  if(FLAGS_input == ""){
    if(FLAGS_output == 1){
      printf("> ");
    }
    while(getline(cin, str)){
      if(str == "EXIT"){
        break;
      }
      calc(str, FLAGS_output, FLAGS_offset, limit, FLAGS_threshold,
           FLAGS_no_normalize, FLAGS_term_filter.c_str(),
           FLAGS_output_filter.c_str());
      if(FLAGS_output == 1){
        printf("> ");
      }
    }
  } else {
    if(FLAGS_output == 1){
      printf("> ");
    }
    ifstream ifs(FLAGS_input.c_str());
    if(ifs.fail()) {
      cerr << "File do not exist.\n";
      exit(0);
    }
    while(getline(ifs, str)){
      calc(str, FLAGS_output, FLAGS_offset, limit, FLAGS_threshold,
           FLAGS_no_normalize, FLAGS_term_filter.c_str(),
           FLAGS_output_filter.c_str());
      if(FLAGS_output == 1){
        printf("> ");
      }
    }
  }

  return 0;
}
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------------------------------------
//* Copyright  2010-2013 Immersive and Creative Technologies Lab, Cyprus University of Technology           *
//* Link: http://ict.cut.ac.cy                                                                               *
//* Software developer(s): Kyriakos Herakleous                                                               *
//* Researcher(s): Kyriakos Herakleous, Charalambos Poullis                                                  *
//*                                                                                *
//* This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.*
//* Link: http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_US                                        *
//------------------------------------------------------------------------------------------------------------

#include "StdAfx.h"
#include "Projector.h"

int Projector::numOfProjectors=0;

Projector::Projector(int projW,int projH)
{
	Projector::numOfProjectors++;

	projNum=numOfProjectors;

	width=projW;
	height=projH;

	initProjectorWindow();

}

void Projector::initProjectorWindow()
{
	cvNamedWindow("Projector Window",CV_WINDOW_NORMAL);
	cvResizeWindow("Projector Window",width,height);
	cvMoveWindow("Projector Window", width+316, -20);
	cvSetWindowProperty("Projector Window", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
}

void Projector::showImg(IplImage* img)
{
	cvShowImage("Projector Window", img );
}

void Projector::showImg(cv::Mat img)
{
	cv::imshow("Projector Window", img );
}

Projector::~Projector(void)
{
	cvDestroyWindow("Projector Window");
}
<commit_msg>Update Projector.cpp<commit_after>//------------------------------------------------------------------------------------------------------------
//* Copyright © 2010-2015 Immersive and Creative Technologies Lab, Cyprus University of Technology           *
//* Link: http://www.theICTlab.org                                                                           *
//* Software developer(s): Kyriakos Herakleous                                                               *
//* Researcher(s): Kyriakos Herakleous, Charalambos Poullis                                                  *
//*                                                                                *
//* License: Check the file License.md                                                                       *
//------------------------------------------------------------------------------------------------------------

#include "StdAfx.h"
#include "Projector.h"

int Projector::numOfProjectors=0;

Projector::Projector(int projW,int projH)
{
	Projector::numOfProjectors++;

	projNum=numOfProjectors;

	width=projW;
	height=projH;

	initProjectorWindow();

}

void Projector::initProjectorWindow()
{
	cvNamedWindow("Projector Window",CV_WINDOW_NORMAL);
	cvResizeWindow("Projector Window",width,height);
	cvMoveWindow("Projector Window", width+316, -20);
	cvSetWindowProperty("Projector Window", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
}

void Projector::showImg(IplImage* img)
{
	cvShowImage("Projector Window", img );
}

void Projector::showImg(cv::Mat img)
{
	cv::imshow("Projector Window", img );
}

Projector::~Projector(void)
{
	cvDestroyWindow("Projector Window");
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: DBSetupConnectionPages.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: pjunck $ $Date: 2004-10-27 12:59: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 EXPRESS 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): Berend Cornelius
 *
 *
 ************************************************************************/

#ifndef DBAUI_DBSETUPCONNECTIONPAGES_HXX
#define DBAUI_DBSETUPCONNECTIONPAGES_HXX

#ifndef DBAUI_CONNECTIONPAGESETUP_HXX
#include "ConnectionPageSetup.hxx"
#endif

#ifndef _DBAUI_ADMINPAGES_HXX_
#include "adminpages.hxx"
#endif
#ifndef _UCBHELPER_CONTENT_HXX
#include <ucbhelper/content.hxx>
#endif
#ifndef _DBAUI_CURLEDIT_HXX_
#include "curledit.hxx"
#endif
#ifndef SVTOOLS_INC_ROADMAPWIZARD_HXX
#include <svtools/roadmapwizard.hxx>
#endif
#ifndef _SV_FIELD_HXX
#include <vcl/field.hxx>
#endif
#ifndef DBAUI_TEXTCONNECTIONHELPER_HXX
#include "TextConnectionHelper.hxx"
#endif

//.........................................................................
namespace dbaui

{
//.........................................................................

    class IAdminHelper;
//      static  OGenericAdministrationPage* CreateDbaseTabPage( Window* pParent, const SfxItemSet& _rAttrSet );

       //========================================================================
    //= OSpreadSheetConnectionPageSetup
    //========================================================================
    class OSpreadSheetConnectionPageSetup : public OConnectionTabPageSetup
    {
    public:
        virtual BOOL        FillItemSet ( SfxItemSet& _rCoreAttrs );
        static  OGenericAdministrationPage* CreateSpreadSheetTabPage( Window* pParent, const SfxItemSet& _rAttrSet );
        OSpreadSheetConnectionPageSetup(Window* pParent, const SfxItemSet& _rCoreAttrs);

    protected:
        CheckBox m_aCBPasswordrequired;
        virtual ~OSpreadSheetConnectionPageSetup();

    protected:
        virtual void implInitControls(const SfxItemSet& _rSet, sal_Bool _bSaveValue);
        virtual void fillControls(::std::vector< ISaveValueWrapper* >& _rControlList);
        virtual void fillWindows(::std::vector< ISaveValueWrapper* >& _rControlList);

    };

    //========================================================================
    //= OTextConnectionPage
    //========================================================================
    class OTextConnectionPageSetup : public OConnectionTabPageSetup
    {
    public:
        virtual BOOL        FillItemSet ( SfxItemSet& _rCoreAttrs );
           static   OGenericAdministrationPage* CreateTextTabPage( Window* pParent, const SfxItemSet& _rAttrSet );
        OTextConnectionPageSetup( Window* pParent, const SfxItemSet& _rCoreAttrs );
        OTextConnectionHelper*  m_pTextConnectionHelper;
    private:

    protected:
        virtual ~OTextConnectionPageSetup();
        virtual sal_Bool checkItems();
        virtual void implInitControls(const SfxItemSet& _rSet, sal_Bool _bSaveValue);
        virtual void fillControls(::std::vector< ISaveValueWrapper* >& _rControlList);
        virtual void fillWindows(::std::vector< ISaveValueWrapper* >& _rControlList);
        bool    checkTestConnection();

    private:
        DECL_LINK(ImplGetExtensionHdl, OTextConnectionHelper*);
    };

    //========================================================================
    //= OLDAPConnectionPageSetup
    //========================================================================
    class OLDAPConnectionPageSetup : public OGenericAdministrationPage
    {
    public:
        virtual BOOL        FillItemSet ( SfxItemSet& _rCoreAttrs );
        static  OGenericAdministrationPage* CreateLDAPTabPage( Window* pParent, const SfxItemSet& _rAttrSet );
        OLDAPConnectionPageSetup( Window* pParent, const SfxItemSet& _rCoreAttrs );
        virtual Link getControlModifiedLink() { return LINK(this, OLDAPConnectionPageSetup, OnEditModified); }

    protected:
        virtual void implInitControls(const SfxItemSet& _rSet, sal_Bool _bSaveValue);
        virtual void fillControls(::std::vector< ISaveValueWrapper* >& _rControlList);
        virtual void fillWindows(::std::vector< ISaveValueWrapper* >& _rControlList);
        DECL_LINK(OnEditModified,Edit*);

    private:
        FixedText           m_aFTHeaderText;
        FixedText           m_aFTHelpText;
        FixedText           m_aFTHostServer;
        Edit                m_aETHostServer;
        FixedText           m_aFTBaseDN;
        Edit                m_aETBaseDN;
        FixedText           m_aFTPortNumber;
        NumericField        m_aNFPortNumber;
        FixedText           m_aFTDefaultPortNumber;
        CheckBox            m_aCBUseSSL;
    };

    //========================================================================
    //= OGeneralSpecialJDBCConnectionPageSetup
    //========================================================================
    class OGeneralSpecialJDBCConnectionPageSetup : public OGenericAdministrationPage
    {
    public:
        OGeneralSpecialJDBCConnectionPageSetup(   Window* pParent
                                        , USHORT _nResId
                                        , const SfxItemSet& _rCoreAttrs
                                        , USHORT _nPortId
                                        , USHORT _nDefaultPortResId
                                        , char* _pDriverName
                                        , USHORT _nHelpTextResId
                                        , USHORT _nHeaderTextResId
                                        , USHORT _nDriverClassId = -1);
    static  OGenericAdministrationPage* CreateMySQLJDBCTabPage( Window* pParent, const SfxItemSet& _rAttrSet );
    static  OGenericAdministrationPage* CreateOracleJDBCTabPage( Window* pParent, const SfxItemSet& _rAttrSet );
    virtual Link getControlModifiedLink() { return LINK(this, OGeneralSpecialJDBCConnectionPageSetup, OnEditModified); }

    protected:

        virtual BOOL FillItemSet( SfxItemSet& _rCoreAttrs );
        virtual void implInitControls(const SfxItemSet& _rSet, sal_Bool _bSaveValue);
        virtual void fillControls(::std::vector< ISaveValueWrapper* >& _rControlList);
        virtual void fillWindows(::std::vector< ISaveValueWrapper* >& _rControlList);

        DECL_LINK(OnTestJavaClickHdl,PushButton*);
        DECL_LINK(OnEditModified,Edit*);
        FixedText*          m_pFTHeaderText;
        FixedText           m_aFTHelpText;
        FixedText           m_aFTDatabasename;
        Edit                m_aETDatabasename;
        FixedText           m_aFTHostname;
        Edit                m_aETHostname;
        FixedText           m_aFTPortNumber;
        FixedText           m_aFTDefaultPortNumber;
        NumericField        m_aNFPortNumber;

        FixedText           m_aFTDriverClass;
        Edit                m_aETDriverClass;
        PushButton          m_aPBTestJavaDriver;

        String              m_sDefaultJdbcDriverName;
        USHORT              m_nPortId;
    };

    //========================================================================
    //= OJDBCConnectionPageSetup
    //========================================================================
    class OJDBCConnectionPageSetup : public OConnectionTabPageSetup
    {
    public:
        OJDBCConnectionPageSetup(   Window* pParent
                                        , USHORT _nResId
                                        , const SfxItemSet& _rCoreAttrs);
    static  OGenericAdministrationPage* CreateJDBCTabPage( Window* pParent, const SfxItemSet& _rAttrSet );

    protected:
        virtual bool checkTestConnection();

        virtual BOOL FillItemSet( SfxItemSet& _rCoreAttrs );
        virtual void implInitControls(const SfxItemSet& _rSet, sal_Bool _bSaveValue);
        virtual void fillControls(::std::vector< ISaveValueWrapper* >& _rControlList);
        virtual void fillWindows(::std::vector< ISaveValueWrapper* >& _rControlList);

        DECL_LINK(OnTestJavaClickHdl,PushButton*);
        DECL_LINK(OnEditModified,Edit*);
        FixedText           m_aFTDriverClass;
        Edit                m_aETDriverClass;
        PushButton          m_aPBTestJavaDriver;
    };

    //========================================================================
    //= OJDBCConnectionPageSetup
    //========================================================================
    class OMySQLIntroPageSetup : public OGenericAdministrationPage
    {
    public:
        OMySQLIntroPageSetup( Window* pParent, const SfxItemSet& _rCoreAttrs);

        static OMySQLIntroPageSetup*    CreateMySQLIntroTabPage( Window* _pParent, const SfxItemSet& _rAttrSet );
        int getMySQLMode();
        Link                maClickHdl;
        void                SetClickHdl( const Link& rLink ) { maClickHdl = rLink; }
        const Link&         GetClickHdl() const { return maClickHdl; }
        DECL_LINK(ImplClickHdl, OMySQLIntroPageSetup*);

    protected:
        virtual BOOL FillItemSet(SfxItemSet& _rSet);
        virtual void implInitControls(const SfxItemSet& _rSet, sal_Bool _bSaveValue);
        virtual void fillControls(::std::vector< ISaveValueWrapper* >& _rControlList);
        virtual void fillWindows(::std::vector< ISaveValueWrapper* >& _rControlList);
        virtual ~OMySQLIntroPageSetup();

    private:
        RadioButton         m_aRB_ODBCDatabase;
        RadioButton         m_aRB_JDBCDatabase;
        FixedText           m_aFT_ConnectionMode;
        FixedText           m_aFT_Helptext;
        FixedText           m_aFT_Headertext;

        DECL_LINK(OnSetupModeSelected, RadioButton*);

    };

       //========================================================================
    //= OAuthentificationPageSetup
    //========================================================================
    class OAuthentificationPageSetup : public OGenericAdministrationPage
    {
    public:
        virtual BOOL        FillItemSet ( SfxItemSet& _rCoreAttrs );
        static  OGenericAdministrationPage* CreateAuthentificationTabPage( Window* pParent, const SfxItemSet& _rAttrSet );
        OAuthentificationPageSetup(Window* pParent, const SfxItemSet& _rCoreAttrs);

    protected:
        FixedText   m_aFTHelpText;
        FixedText   m_aFTHeaderText;
        FixedText   m_aFTUserName;
        Edit        m_aETUserName;
        CheckBox    m_aCBPasswordRequired;
        PushButton  m_aPBTestConnection;
        virtual ~OAuthentificationPageSetup();

    protected:
        virtual void implInitControls(const SfxItemSet& _rSet, sal_Bool _bSaveValue);
        virtual void fillControls(::std::vector< ISaveValueWrapper* >& _rControlList);
        virtual void fillWindows(::std::vector< ISaveValueWrapper* >& _rControlList);
    };

       //========================================================================
    //= OFinalDBPageSetup
    //========================================================================
    class OFinalDBPageSetup : public OGenericAdministrationPage
    {
    public:
        virtual BOOL        FillItemSet ( SfxItemSet& _rCoreAttrs );
           static   OGenericAdministrationPage* CreateFinalDBTabPageSetup( Window* pParent, const SfxItemSet& _rAttrSet);

        FixedText   m_aFTFinalHeader;
        FixedText   m_aFTFinalHelpText;
        RadioButton m_aRBRegisterDataSource;
        RadioButton m_aRBDontregisterDataSource;
        FixedText   m_aFTAdditionalSettings;
        CheckBox    m_aCBOpenAfterwards;
        CheckBox    m_aCBStartTableWizard;
        FixedText   m_aFTFinalText;

        OFinalDBPageSetup(Window* pParent, const SfxItemSet& _rCoreAttrs);
        sal_Bool IsDatabaseDocumentToBeRegistered();
        sal_Bool IsDatabaseDocumentToBeOpened();
        sal_Bool IsTableWizardToBeStarted();
        void enableTableWizardCheckBox( sal_Bool _bSupportsTableCreation);

        /// may be used in SetXXXHdl calls to controls, is a link to <method>OnControlModified</method>
        Link getControlModifiedLink() { return LINK(this, OGenericAdministrationPage, OnControlModified); }

    protected:
        virtual ~OFinalDBPageSetup();

    protected:
        virtual void implInitControls(const SfxItemSet& _rSet, sal_Bool _bSaveValue);
        virtual void fillControls(::std::vector< ISaveValueWrapper* >& _rControlList);
        virtual void fillWindows(::std::vector< ISaveValueWrapper* >& _rControlList);
    };

//.........................................................................
}   // namespace dbaui
//.........................................................................

#endif
<commit_msg>INTEGRATION: CWS ooo19126 (1.2.174); FILE MERGED 2005/09/05 17:33:34 rt 1.2.174.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: DBSetupConnectionPages.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 14:46:47 $
 *
 *  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 DBAUI_DBSETUPCONNECTIONPAGES_HXX
#define DBAUI_DBSETUPCONNECTIONPAGES_HXX

#ifndef DBAUI_CONNECTIONPAGESETUP_HXX
#include "ConnectionPageSetup.hxx"
#endif

#ifndef _DBAUI_ADMINPAGES_HXX_
#include "adminpages.hxx"
#endif
#ifndef _UCBHELPER_CONTENT_HXX
#include <ucbhelper/content.hxx>
#endif
#ifndef _DBAUI_CURLEDIT_HXX_
#include "curledit.hxx"
#endif
#ifndef SVTOOLS_INC_ROADMAPWIZARD_HXX
#include <svtools/roadmapwizard.hxx>
#endif
#ifndef _SV_FIELD_HXX
#include <vcl/field.hxx>
#endif
#ifndef DBAUI_TEXTCONNECTIONHELPER_HXX
#include "TextConnectionHelper.hxx"
#endif

//.........................................................................
namespace dbaui

{
//.........................................................................

    class IAdminHelper;
//      static  OGenericAdministrationPage* CreateDbaseTabPage( Window* pParent, const SfxItemSet& _rAttrSet );

       //========================================================================
    //= OSpreadSheetConnectionPageSetup
    //========================================================================
    class OSpreadSheetConnectionPageSetup : public OConnectionTabPageSetup
    {
    public:
        virtual BOOL        FillItemSet ( SfxItemSet& _rCoreAttrs );
        static  OGenericAdministrationPage* CreateSpreadSheetTabPage( Window* pParent, const SfxItemSet& _rAttrSet );
        OSpreadSheetConnectionPageSetup(Window* pParent, const SfxItemSet& _rCoreAttrs);

    protected:
        CheckBox m_aCBPasswordrequired;
        virtual ~OSpreadSheetConnectionPageSetup();

    protected:
        virtual void implInitControls(const SfxItemSet& _rSet, sal_Bool _bSaveValue);
        virtual void fillControls(::std::vector< ISaveValueWrapper* >& _rControlList);
        virtual void fillWindows(::std::vector< ISaveValueWrapper* >& _rControlList);

    };

    //========================================================================
    //= OTextConnectionPage
    //========================================================================
    class OTextConnectionPageSetup : public OConnectionTabPageSetup
    {
    public:
        virtual BOOL        FillItemSet ( SfxItemSet& _rCoreAttrs );
           static   OGenericAdministrationPage* CreateTextTabPage( Window* pParent, const SfxItemSet& _rAttrSet );
        OTextConnectionPageSetup( Window* pParent, const SfxItemSet& _rCoreAttrs );
        OTextConnectionHelper*  m_pTextConnectionHelper;
    private:

    protected:
        virtual ~OTextConnectionPageSetup();
        virtual sal_Bool checkItems();
        virtual void implInitControls(const SfxItemSet& _rSet, sal_Bool _bSaveValue);
        virtual void fillControls(::std::vector< ISaveValueWrapper* >& _rControlList);
        virtual void fillWindows(::std::vector< ISaveValueWrapper* >& _rControlList);
        bool    checkTestConnection();

    private:
        DECL_LINK(ImplGetExtensionHdl, OTextConnectionHelper*);
    };

    //========================================================================
    //= OLDAPConnectionPageSetup
    //========================================================================
    class OLDAPConnectionPageSetup : public OGenericAdministrationPage
    {
    public:
        virtual BOOL        FillItemSet ( SfxItemSet& _rCoreAttrs );
        static  OGenericAdministrationPage* CreateLDAPTabPage( Window* pParent, const SfxItemSet& _rAttrSet );
        OLDAPConnectionPageSetup( Window* pParent, const SfxItemSet& _rCoreAttrs );
        virtual Link getControlModifiedLink() { return LINK(this, OLDAPConnectionPageSetup, OnEditModified); }

    protected:
        virtual void implInitControls(const SfxItemSet& _rSet, sal_Bool _bSaveValue);
        virtual void fillControls(::std::vector< ISaveValueWrapper* >& _rControlList);
        virtual void fillWindows(::std::vector< ISaveValueWrapper* >& _rControlList);
        DECL_LINK(OnEditModified,Edit*);

    private:
        FixedText           m_aFTHeaderText;
        FixedText           m_aFTHelpText;
        FixedText           m_aFTHostServer;
        Edit                m_aETHostServer;
        FixedText           m_aFTBaseDN;
        Edit                m_aETBaseDN;
        FixedText           m_aFTPortNumber;
        NumericField        m_aNFPortNumber;
        FixedText           m_aFTDefaultPortNumber;
        CheckBox            m_aCBUseSSL;
    };

    //========================================================================
    //= OGeneralSpecialJDBCConnectionPageSetup
    //========================================================================
    class OGeneralSpecialJDBCConnectionPageSetup : public OGenericAdministrationPage
    {
    public:
        OGeneralSpecialJDBCConnectionPageSetup(   Window* pParent
                                        , USHORT _nResId
                                        , const SfxItemSet& _rCoreAttrs
                                        , USHORT _nPortId
                                        , USHORT _nDefaultPortResId
                                        , char* _pDriverName
                                        , USHORT _nHelpTextResId
                                        , USHORT _nHeaderTextResId
                                        , USHORT _nDriverClassId = -1);
    static  OGenericAdministrationPage* CreateMySQLJDBCTabPage( Window* pParent, const SfxItemSet& _rAttrSet );
    static  OGenericAdministrationPage* CreateOracleJDBCTabPage( Window* pParent, const SfxItemSet& _rAttrSet );
    virtual Link getControlModifiedLink() { return LINK(this, OGeneralSpecialJDBCConnectionPageSetup, OnEditModified); }

    protected:

        virtual BOOL FillItemSet( SfxItemSet& _rCoreAttrs );
        virtual void implInitControls(const SfxItemSet& _rSet, sal_Bool _bSaveValue);
        virtual void fillControls(::std::vector< ISaveValueWrapper* >& _rControlList);
        virtual void fillWindows(::std::vector< ISaveValueWrapper* >& _rControlList);

        DECL_LINK(OnTestJavaClickHdl,PushButton*);
        DECL_LINK(OnEditModified,Edit*);
        FixedText*          m_pFTHeaderText;
        FixedText           m_aFTHelpText;
        FixedText           m_aFTDatabasename;
        Edit                m_aETDatabasename;
        FixedText           m_aFTHostname;
        Edit                m_aETHostname;
        FixedText           m_aFTPortNumber;
        FixedText           m_aFTDefaultPortNumber;
        NumericField        m_aNFPortNumber;

        FixedText           m_aFTDriverClass;
        Edit                m_aETDriverClass;
        PushButton          m_aPBTestJavaDriver;

        String              m_sDefaultJdbcDriverName;
        USHORT              m_nPortId;
    };

    //========================================================================
    //= OJDBCConnectionPageSetup
    //========================================================================
    class OJDBCConnectionPageSetup : public OConnectionTabPageSetup
    {
    public:
        OJDBCConnectionPageSetup(   Window* pParent
                                        , USHORT _nResId
                                        , const SfxItemSet& _rCoreAttrs);
    static  OGenericAdministrationPage* CreateJDBCTabPage( Window* pParent, const SfxItemSet& _rAttrSet );

    protected:
        virtual bool checkTestConnection();

        virtual BOOL FillItemSet( SfxItemSet& _rCoreAttrs );
        virtual void implInitControls(const SfxItemSet& _rSet, sal_Bool _bSaveValue);
        virtual void fillControls(::std::vector< ISaveValueWrapper* >& _rControlList);
        virtual void fillWindows(::std::vector< ISaveValueWrapper* >& _rControlList);

        DECL_LINK(OnTestJavaClickHdl,PushButton*);
        DECL_LINK(OnEditModified,Edit*);
        FixedText           m_aFTDriverClass;
        Edit                m_aETDriverClass;
        PushButton          m_aPBTestJavaDriver;
    };

    //========================================================================
    //= OJDBCConnectionPageSetup
    //========================================================================
    class OMySQLIntroPageSetup : public OGenericAdministrationPage
    {
    public:
        OMySQLIntroPageSetup( Window* pParent, const SfxItemSet& _rCoreAttrs);

        static OMySQLIntroPageSetup*    CreateMySQLIntroTabPage( Window* _pParent, const SfxItemSet& _rAttrSet );
        int getMySQLMode();
        Link                maClickHdl;
        void                SetClickHdl( const Link& rLink ) { maClickHdl = rLink; }
        const Link&         GetClickHdl() const { return maClickHdl; }
        DECL_LINK(ImplClickHdl, OMySQLIntroPageSetup*);

    protected:
        virtual BOOL FillItemSet(SfxItemSet& _rSet);
        virtual void implInitControls(const SfxItemSet& _rSet, sal_Bool _bSaveValue);
        virtual void fillControls(::std::vector< ISaveValueWrapper* >& _rControlList);
        virtual void fillWindows(::std::vector< ISaveValueWrapper* >& _rControlList);
        virtual ~OMySQLIntroPageSetup();

    private:
        RadioButton         m_aRB_ODBCDatabase;
        RadioButton         m_aRB_JDBCDatabase;
        FixedText           m_aFT_ConnectionMode;
        FixedText           m_aFT_Helptext;
        FixedText           m_aFT_Headertext;

        DECL_LINK(OnSetupModeSelected, RadioButton*);

    };

       //========================================================================
    //= OAuthentificationPageSetup
    //========================================================================
    class OAuthentificationPageSetup : public OGenericAdministrationPage
    {
    public:
        virtual BOOL        FillItemSet ( SfxItemSet& _rCoreAttrs );
        static  OGenericAdministrationPage* CreateAuthentificationTabPage( Window* pParent, const SfxItemSet& _rAttrSet );
        OAuthentificationPageSetup(Window* pParent, const SfxItemSet& _rCoreAttrs);

    protected:
        FixedText   m_aFTHelpText;
        FixedText   m_aFTHeaderText;
        FixedText   m_aFTUserName;
        Edit        m_aETUserName;
        CheckBox    m_aCBPasswordRequired;
        PushButton  m_aPBTestConnection;
        virtual ~OAuthentificationPageSetup();

    protected:
        virtual void implInitControls(const SfxItemSet& _rSet, sal_Bool _bSaveValue);
        virtual void fillControls(::std::vector< ISaveValueWrapper* >& _rControlList);
        virtual void fillWindows(::std::vector< ISaveValueWrapper* >& _rControlList);
    };

       //========================================================================
    //= OFinalDBPageSetup
    //========================================================================
    class OFinalDBPageSetup : public OGenericAdministrationPage
    {
    public:
        virtual BOOL        FillItemSet ( SfxItemSet& _rCoreAttrs );
           static   OGenericAdministrationPage* CreateFinalDBTabPageSetup( Window* pParent, const SfxItemSet& _rAttrSet);

        FixedText   m_aFTFinalHeader;
        FixedText   m_aFTFinalHelpText;
        RadioButton m_aRBRegisterDataSource;
        RadioButton m_aRBDontregisterDataSource;
        FixedText   m_aFTAdditionalSettings;
        CheckBox    m_aCBOpenAfterwards;
        CheckBox    m_aCBStartTableWizard;
        FixedText   m_aFTFinalText;

        OFinalDBPageSetup(Window* pParent, const SfxItemSet& _rCoreAttrs);
        sal_Bool IsDatabaseDocumentToBeRegistered();
        sal_Bool IsDatabaseDocumentToBeOpened();
        sal_Bool IsTableWizardToBeStarted();
        void enableTableWizardCheckBox( sal_Bool _bSupportsTableCreation);

        /// may be used in SetXXXHdl calls to controls, is a link to <method>OnControlModified</method>
        Link getControlModifiedLink() { return LINK(this, OGenericAdministrationPage, OnControlModified); }

    protected:
        virtual ~OFinalDBPageSetup();

    protected:
        virtual void implInitControls(const SfxItemSet& _rSet, sal_Bool _bSaveValue);
        virtual void fillControls(::std::vector< ISaveValueWrapper* >& _rControlList);
        virtual void fillWindows(::std::vector< ISaveValueWrapper* >& _rControlList);
    };

//.........................................................................
}   // namespace dbaui
//.........................................................................

#endif
<|endoftext|>


<commit_before>// Time:  O(n)
// Space: O(k), k is size of the alphabet

// array solution (4ms)
class Solution {
public:
    string removeDuplicateLetters(string s) {
        array<int, 26> cnts{0};
        for (const auto& c : s) {
            ++cnts[c - 'a'];
        }

        array<bool, 26> visited{false};
        string stk;
        for (const auto& c : s) {
            if (!visited[c - 'a'] && (stk.empty() || stk.back() != c)) {
                while (!stk.empty() && stk.back() >= c && cnts[stk.back() - 'a'] > 0) {
                    visited[stk.back() - 'a'] = false;
                    stk.pop_back();
                }
                stk.push_back(c);
                visited[c - 'a'] = true;
            }
            --cnts[c - 'a'];
        }
        return stk;
    }
};

// Time:  O(n)
// Space: O(k), k is size of the alphabet
// hash solution (16ms)
class Solution2 {
public:
    string removeDuplicateLetters(string s) {
        unordered_map<char, int> cnts;
        for (const auto& c : s) {
            ++cnts[c];
        }

        unordered_set<char> visited;
        string stk;
        for (const auto& c : s) {
            if (!visited.count(c) && (stk.empty() || stk.back() != c)) {
                while (!stk.empty() && stk.back() >= c && cnts[stk.back()] > 0) {
                    visited.erase(stk.back());
                    stk.pop_back();
                }
                stk.push_back(c);
                visited.emplace(c);
            }
            --cnts[c];
        }
        return stk;
    }
};
<commit_msg>Update remove-duplicate-letters.cpp<commit_after>// Time:  O(n)
// Space: O(k), k is size of the alphabet

// vector solution, need to know size of the alphabet in advace (4ms)
class Solution {
public:
    string removeDuplicateLetters(string s) {
        const int k = 26;
        vector<int> cnts(k);
        for (const auto& c : s) {
            ++cnts[c - 'a'];
        }

        vector<bool> visited(k);
        string stk;
        for (const auto& c : s) {
            if (!visited[c - 'a'] && (stk.empty() || stk.back() != c)) {
                while (!stk.empty() && stk.back() >= c && cnts[stk.back() - 'a'] > 0) {
                    visited[stk.back() - 'a'] = false;
                    stk.pop_back();
                }
                stk.push_back(c);
                visited[c - 'a'] = true;
            }
            --cnts[c - 'a'];
        }
        return stk;
    }
};

// Time:  O(n)
// Space: O(k), k is size of the alphabet
// hash solution, no need to know size of the alphabet in advance (16ms)
class Solution2 {
public:
    string removeDuplicateLetters(string s) {
        unordered_map<char, int> cnts;
        for (const auto& c : s) {
            ++cnts[c];
        }

        unordered_set<char> visited;
        string stk;
        for (const auto& c : s) {
            if (!visited.count(c) && (stk.empty() || stk.back() != c)) {
                while (!stk.empty() && stk.back() >= c && cnts[stk.back()] > 0) {
                    visited.erase(stk.back());
                    stk.pop_back();
                }
                stk.push_back(c);
                visited.emplace(c);
            }
            --cnts[c];
        }
        return stk;
    }
};
<|endoftext|>