<commit_before>//=======================================================================
// Copyright (c) 2014-2015 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

#include <algorithm>

#include "../config.hpp"
#include "../traits_lite.hpp"

#include "std/fft.hpp"
#include "blas/fft.hpp"

namespace etl {

namespace detail {

template<typename A, typename C, typename Enable = void>
struct fft1_impl {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::standard::fft1(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C, typename Enable = void>
struct fft2_impl {
    template<typename AA, typename CC>
    static void apply(A&& a, CC&& c){
        etl::impl::standard::fft2(std::forward<A>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C, typename Enable = void>
struct ifft1_impl {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::standard::ifft1(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C, typename Enable = void>
struct ifft1_real_impl {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::standard::ifft1_real(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C, typename Enable = void>
struct ifft2_impl {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::standard::ifft2(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C, typename Enable = void>
struct ifft2_real_impl {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::standard::ifft2_real(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename B, typename C, typename Enable = void>
struct fft_conv1_full_impl {
    template<typename AA, typename BB, typename CC>
    static void apply(AA&& a, BB&& b, CC&& c){
        etl::impl::standard::fft1_convolve(std::forward<AA>(a), std::forward<BB>(b), std::forward<CC>(c));
    }
};

template<typename A, typename B, typename C, typename Enable = void>
struct fft_conv2_full_impl {
    template<typename AA, typename BB, typename CC>
    static void apply(AA&& a, BB&& b, CC&& c){
        etl::impl::standard::fft2_convolve(std::forward<AA>(a), std::forward<BB>(b), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct is_blas_dfft : cpp::and_c<is_mkl_enabled, is_double_precision<A>, all_dma<A, C>> {};

template<typename A, typename C>
struct is_blas_sfft : cpp::and_c<is_mkl_enabled, is_single_precision<A>, all_dma<A, C>> {};

template<typename A, typename C>
struct is_blas_cfft : cpp::and_c<is_mkl_enabled, is_complex_single_precision<A>, all_dma<A, C>> {};

template<typename A, typename C>
struct is_blas_zfft : cpp::and_c<is_mkl_enabled, is_complex_double_precision<A>, all_dma<A, C>> {};

template<typename A, typename C>
struct fft1_impl<A, C, std::enable_if_t<is_blas_dfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::dfft1(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct fft1_impl<A, C, std::enable_if_t<is_blas_sfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::sfft1(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct fft1_impl<A, C, std::enable_if_t<is_blas_cfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::cfft1(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct fft1_impl<A, C, std::enable_if_t<is_blas_zfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::zfft1(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct ifft1_impl<A, C, std::enable_if_t<is_blas_cfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::cifft1(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct ifft1_impl<A, C, std::enable_if_t<is_blas_zfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::zifft1(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct ifft1_real_impl<A, C, std::enable_if_t<is_blas_cfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::cifft1_real(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct ifft1_real_impl<A, C, std::enable_if_t<is_blas_zfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::zifft1_real(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename B, typename C>
struct is_blas_sfft_convolve : cpp::and_c<is_mkl_enabled, all_single_precision<A,B,C>, all_dma<A, B, C>> {};

template<typename A, typename B, typename C>
struct is_blas_dfft_convolve : cpp::and_c<is_mkl_enabled, all_double_precision<A,B,C>, all_dma<A, B, C>> {};

template<typename A, typename B, typename C>
struct fft_conv1_full_impl<A, B, C, std::enable_if_t<is_blas_sfft_convolve<A,B,C>::value>> {
    template<typename AA, typename BB, typename CC>
    static void apply(AA&& a, BB&& b, CC&& c){
        etl::impl::blas::sfft1_convolve(std::forward<AA>(a), std::forward<BB>(b), std::forward<CC>(c));
    }
};

template<typename A, typename B, typename C>
struct fft_conv1_full_impl<A, B, C, std::enable_if_t<is_blas_dfft_convolve<A,B,C>::value>> {
    template<typename AA, typename BB, typename CC>
    static void apply(AA&& a, BB&& b, CC&& c){
        etl::impl::blas::dfft1_convolve(std::forward<AA>(a), std::forward<BB>(b), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct fft2_impl<A, C, std::enable_if_t<is_blas_dfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::dfft2(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct fft2_impl<A, C, std::enable_if_t<is_blas_sfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::sfft2(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct fft2_impl<A, C, std::enable_if_t<is_blas_cfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::cfft2(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct fft2_impl<A, C, std::enable_if_t<is_blas_zfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::zfft2(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct ifft2_impl<A, C, std::enable_if_t<is_blas_cfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::cifft2(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct ifft2_impl<A, C, std::enable_if_t<is_blas_zfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::zifft2(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct ifft2_real_impl<A, C, std::enable_if_t<is_blas_cfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::cifft2_real(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct ifft2_real_impl<A, C, std::enable_if_t<is_blas_zfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::zifft2_real(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename B, typename C>
struct fft_conv2_full_impl<A, B, C, std::enable_if_t<is_blas_sfft_convolve<A,B,C>::value>> {
    template<typename AA, typename BB, typename CC>
    static void apply(AA&& a, BB&& b, CC&& c){
        etl::impl::blas::sfft2_convolve(std::forward<AA>(a), std::forward<BB>(b), std::forward<CC>(c));
    }
};

template<typename A, typename B, typename C>
struct fft_conv2_full_impl<A, B, C, std::enable_if_t<is_blas_dfft_convolve<A,B,C>::value>> {
    template<typename AA, typename BB, typename CC>
    static void apply(AA&& a, BB&& b, CC&& c){
        etl::impl::blas::dfft2_convolve(std::forward<AA>(a), std::forward<BB>(b), std::forward<CC>(c));
    }
};

} //end of namespace detail

} //end of namespace etl
<commit_msg>Fix forwarding<commit_after>//=======================================================================
// Copyright (c) 2014-2015 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

#include <algorithm>

#include "../config.hpp"
#include "../traits_lite.hpp"

#include "std/fft.hpp"
#include "blas/fft.hpp"

namespace etl {

namespace detail {

template<typename A, typename C, typename Enable = void>
struct fft1_impl {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::standard::fft1(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C, typename Enable = void>
struct fft2_impl {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::standard::fft2(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C, typename Enable = void>
struct ifft1_impl {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::standard::ifft1(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C, typename Enable = void>
struct ifft1_real_impl {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::standard::ifft1_real(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C, typename Enable = void>
struct ifft2_impl {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::standard::ifft2(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C, typename Enable = void>
struct ifft2_real_impl {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::standard::ifft2_real(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename B, typename C, typename Enable = void>
struct fft_conv1_full_impl {
    template<typename AA, typename BB, typename CC>
    static void apply(AA&& a, BB&& b, CC&& c){
        etl::impl::standard::fft1_convolve(std::forward<AA>(a), std::forward<BB>(b), std::forward<CC>(c));
    }
};

template<typename A, typename B, typename C, typename Enable = void>
struct fft_conv2_full_impl {
    template<typename AA, typename BB, typename CC>
    static void apply(AA&& a, BB&& b, CC&& c){
        etl::impl::standard::fft2_convolve(std::forward<AA>(a), std::forward<BB>(b), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct is_blas_dfft : cpp::and_c<is_mkl_enabled, is_double_precision<A>, all_dma<A, C>> {};

template<typename A, typename C>
struct is_blas_sfft : cpp::and_c<is_mkl_enabled, is_single_precision<A>, all_dma<A, C>> {};

template<typename A, typename C>
struct is_blas_cfft : cpp::and_c<is_mkl_enabled, is_complex_single_precision<A>, all_dma<A, C>> {};

template<typename A, typename C>
struct is_blas_zfft : cpp::and_c<is_mkl_enabled, is_complex_double_precision<A>, all_dma<A, C>> {};

template<typename A, typename C>
struct fft1_impl<A, C, std::enable_if_t<is_blas_dfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::dfft1(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct fft1_impl<A, C, std::enable_if_t<is_blas_sfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::sfft1(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct fft1_impl<A, C, std::enable_if_t<is_blas_cfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::cfft1(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct fft1_impl<A, C, std::enable_if_t<is_blas_zfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::zfft1(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct ifft1_impl<A, C, std::enable_if_t<is_blas_cfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::cifft1(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct ifft1_impl<A, C, std::enable_if_t<is_blas_zfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::zifft1(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct ifft1_real_impl<A, C, std::enable_if_t<is_blas_cfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::cifft1_real(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct ifft1_real_impl<A, C, std::enable_if_t<is_blas_zfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::zifft1_real(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename B, typename C>
struct is_blas_sfft_convolve : cpp::and_c<is_mkl_enabled, all_single_precision<A,B,C>, all_dma<A, B, C>> {};

template<typename A, typename B, typename C>
struct is_blas_dfft_convolve : cpp::and_c<is_mkl_enabled, all_double_precision<A,B,C>, all_dma<A, B, C>> {};

template<typename A, typename B, typename C>
struct fft_conv1_full_impl<A, B, C, std::enable_if_t<is_blas_sfft_convolve<A,B,C>::value>> {
    template<typename AA, typename BB, typename CC>
    static void apply(AA&& a, BB&& b, CC&& c){
        etl::impl::blas::sfft1_convolve(std::forward<AA>(a), std::forward<BB>(b), std::forward<CC>(c));
    }
};

template<typename A, typename B, typename C>
struct fft_conv1_full_impl<A, B, C, std::enable_if_t<is_blas_dfft_convolve<A,B,C>::value>> {
    template<typename AA, typename BB, typename CC>
    static void apply(AA&& a, BB&& b, CC&& c){
        etl::impl::blas::dfft1_convolve(std::forward<AA>(a), std::forward<BB>(b), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct fft2_impl<A, C, std::enable_if_t<is_blas_dfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::dfft2(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct fft2_impl<A, C, std::enable_if_t<is_blas_sfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::sfft2(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct fft2_impl<A, C, std::enable_if_t<is_blas_cfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::cfft2(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct fft2_impl<A, C, std::enable_if_t<is_blas_zfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::zfft2(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct ifft2_impl<A, C, std::enable_if_t<is_blas_cfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::cifft2(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct ifft2_impl<A, C, std::enable_if_t<is_blas_zfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::zifft2(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct ifft2_real_impl<A, C, std::enable_if_t<is_blas_cfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::cifft2_real(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename C>
struct ifft2_real_impl<A, C, std::enable_if_t<is_blas_zfft<A,C>::value>> {
    template<typename AA, typename CC>
    static void apply(AA&& a, CC&& c){
        etl::impl::blas::zifft2_real(std::forward<AA>(a), std::forward<CC>(c));
    }
};

template<typename A, typename B, typename C>
struct fft_conv2_full_impl<A, B, C, std::enable_if_t<is_blas_sfft_convolve<A,B,C>::value>> {
    template<typename AA, typename BB, typename CC>
    static void apply(AA&& a, BB&& b, CC&& c){
        etl::impl::blas::sfft2_convolve(std::forward<AA>(a), std::forward<BB>(b), std::forward<CC>(c));
    }
};

template<typename A, typename B, typename C>
struct fft_conv2_full_impl<A, B, C, std::enable_if_t<is_blas_dfft_convolve<A,B,C>::value>> {
    template<typename AA, typename BB, typename CC>
    static void apply(AA&& a, BB&& b, CC&& c){
        etl::impl::blas::dfft2_convolve(std::forward<AA>(a), std::forward<BB>(b), std::forward<CC>(c));
    }
};

} //end of namespace detail

} //end of namespace etl
<|endoftext|>


<commit_before><commit_msg>Don't load on writeConfig, since that happens on shutdown, and it makes little sense. (Kolab Issue 1343)<commit_after><|endoftext|>


<commit_before>#if defined __linux__
#elif defined _WIN32 || defined _WIN64 || defined __CYGWIN__
	#include <Windows.h>
#else
    #error unknown platform
#endif

#include "debug.h"
#include "version.h"
#include "CRC/CRC.h"
#include "CRC/CRC32.h"
#include "CRC/CRC16IBM.h"
#include "CRC/CRC16CCITT.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <unistd.h>

#if !defined (unix)
	#include <sys/fcntl.h> // for setmode
#endif

const char *getPathToSelf()
{
	const size_t bufferSize = 256;
	static char buffer [bufferSize];
	if (false);
	#if defined __linux__
	else if (readlink("/proc/self/exe", buffer, bufferSize));
	else if (readlink("/proc/curproc/file", buffer, bufferSize));
	else if (readlink("/proc/self/path/a.out", buffer, bufferSize));
	#elif defined _WIN32 || defined _WIN64
	else if (GetModuleFileName(NULL, buffer, bufferSize));
	#endif
	else strcpy(buffer, "crcmanip");

	char *slash = NULL;
	slash = strrchr(buffer, '/');
	if (slash != NULL)
	{
		strcpy(buffer, slash + 1);
	}
	slash = strrchr(buffer, '\\');
	if (slash != NULL)
	{
		strcpy(buffer, slash + 1);
	}
	return buffer;
}

const char *getVersion()
{
	const size_t bufferSize = 256;
	static char buffer [bufferSize];
	sprintf(buffer, "%d.%d", MAJOR_VERSION, MINOR_VERSION);
	return buffer;
}

void updateProgress(
	const CRC::CRCProgressType &progressType,
	const File::OffsetType &startPos,
	const File::OffsetType &curPos,
	const File::OffsetType &endPos)
{
	static int i = 0;
	static CRC::CRCProgressType lastProgressType;
	if (lastProgressType != progressType || i == 0)
	{
		lastProgressType = progressType;
		switch (progressType)
		{
			case CRC::CRCPROG_WRITE_START:
				fprintf(stderr, "Output started\n");
				fflush(stderr);
				break;
			case CRC::CRCPROG_WRITE_END:
				fprintf(stderr, "Output ended\n");
				fflush(stderr);
				break;
			case CRC::CRCPROG_CHECKSUM_START:
				fprintf(stderr, "Partial checksum started\n");
				fflush(stderr);
				break;
			case CRC::CRCPROG_CHECKSUM_END:
				fprintf(stderr, "Partial checksum ended\n");
				fflush(stderr);
				break;
			default:
				break;
		}
	}
	switch (progressType)
	{
		case CRC::CRCPROG_WRITE_PROGRESS:
		case CRC::CRCPROG_CHECKSUM_PROGRESS:
			if (i % 1000 == 0)
			{
				fprintf(stderr, "%6.02f%%\r",
					(curPos - startPos) * 100.0f / (endPos - startPos));
				fflush(stderr);
			}
			++ i;
			break;
		default:
			break;
	}
}

void usage(FILE *where)
{
	fprintf(where, "%s - CRC checksum manipulator %s\n", getPathToSelf(), getVersion());
	fprintf(where, "Freely manipulate CRC32 checksums through smart file patching.\n");
	fprintf(where, "Usage: %s INFILE OUTFILE CHECKSUM [OPTIONS]\n", getPathToSelf());
	fputs("\n", where);
	fputs("INFILE               input file. if -, standard input will be used.\n", where);
	fputs("OUTFILE              output file. if -, standard output will be used.\n", where);
	fputs("CHECKSUM             desired checksum.\n\n", where);
	fputs("OPTIONS can be:\n", where);
	fputs("-h, --help           print this information.\n", where);
	fputs("-p, --position=NUM   position where to append the patch. Unless specified,\n", where);
	fputs("                     patch will be placed at the end of the input file.\n", where);
	fputs("                     If position is negative, patch will be placed at the\n", where);
	fputs("                     n-th byte from the end of file.\n", where);
	fputs("    --insert         specifies that patch should be inserted (default)\n", where);
	fputs("    --overwrite      specifies that patch should overwrite existing bytes\n", where);
	fputs("\n", where);
	/*
	fputs("Available checksum algorithms:\n", where);
	fputs("    --crc32          use crc32 (default)\n", where);
	fputs("    --crc16-ibm      use crc16-ibm, also known as crc16-ansi and crc16\n", where);
	fputs("    --crc16-ccitt    use crc16-ccitt\n", where);
	fputs("    --init-xor=VAL   use custom VAL as initial XOR value\n", where);
	fputs("    --final-xor=VAL  use custom VAL as final XOR value\n", where);
	fputs("\n", where);
	*/
	fputs("CHECKSUM must be a hexadecimal value.\n", where);
	fputs("INFILE must be seekable stream. In other words, it cannot be a pipe\n", where);
	fputs("(particularly standard input), fifo etc.\n", where);
	fputs("\n", where);
	fputs("Examples:\n", where);
	fputs("./crcmanip input.txt output.txt 1234abcd\n", where);
	fputs("./crcmanip input.txt output.txt 1234abcd -p -1\n", where);
	fputs("./crcmanip input.txt - 1234abcd >output.txt\n", where);
	fputs("./crcmanip - output.txt 1234abcd <input.txt\n", where);
	fputs("./crcmanip - - 1234abcd <input.txt >output.txt\n", where);
	exit(EXIT_FAILURE);
}

void validateChecksum(CRC &activeCRC, const char *str, CRCType &checksum)
{
	if (strlen(str) > activeCRC.getNumBytes() * 2)
	{
		fprintf(stderr,
			"Error: Specified checksum has more than %d digits.\n",
			activeCRC.getNumBytes() * 2);
		exit(EXIT_FAILURE);
	}
	if (strlen(str) < activeCRC.getNumBytes() * 2)
	{
		fprintf(stderr,
			"Warning: specified checksum has less than %d digits. "
			"Resulting checksum will be padded with 0.\n",
			activeCRC.getNumBytes() * 2);
	}
	const char *allowedCharacters = "0123456789abcdefABCDEF";
	for (size_t i = 0; i < strlen(str); i ++)
	{
		if (strchr(allowedCharacters, str[i]) == NULL)
		{
			fprintf(stderr,
				"Error: Specified checksum contains invalid characters. "
				"Only hexadecimal values are accepted.\n");
			exit(EXIT_FAILURE);
		}
	}
	checksum = strtoul(str, NULL, 16);
}

int main(int argc, char **argv)
{
	CRC *activeCRC = new CRC32();
	activeCRC->setProgressFunction(&updateProgress);

	for (int i = 1; i < argc; i ++)
	{
		if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0)
		{
			usage(stdout);
			exit(EXIT_SUCCESS);
		}
	}

	if (argc < 2)
	{
		fprintf(stderr, "No input file specified.\n");
		usage(stderr);
		exit(EXIT_FAILURE);
	}
	char *pathIn = argv[1];
	if (strcmp(pathIn, "-") == 0)
	{
		pathIn = NULL;
	}

	if (argc < 3)
	{
		fprintf(stderr, "No output file specified.\n");
		usage(stderr);
		exit(EXIT_FAILURE);
	}
	char *pathOut = argv[2];
	if (strcmp(pathOut, "-") == 0)
	{
		pathOut = NULL;
	}

	if (argc < 4)
	{
		fprintf(stderr, "No checksum specified.\n");
		usage(stderr);
		exit(EXIT_FAILURE);
	}
	uint32_t desiredChecksum = 0x12345678;
	validateChecksum(*activeCRC, argv[3], desiredChecksum);

	bool overwrite = false;
	bool desiredPositionSpecified = false;
	File::OffsetType desiredPosition = -1;

	for (int i = 4; i < argc; i ++)
	{
		if (strcmp(argv[i], "--insert") == 0)
		{
			overwrite = false;
			continue;
		}
		if (strcmp(argv[i], "--overwrite") == 0)
		{
			overwrite = true;
			continue;
		}
		if (strcmp(argv[i], "-p") == 0 ||
			strcmp(argv[i], "--pos") == 0 ||
			strcmp(argv[i], "--position") == 0)
		{
			if (i == argc - 1)
			{
				fprintf(stderr, "--position needs an additional parameter.");
				usage(stderr);
				exit(EXIT_FAILURE);
			}
			++ i;
			if (strcmp(argv[i], "-0") != 0)
			{
				desiredPosition = atol(argv[i]);
				desiredPositionSpecified = true;
			}
			continue;
		}
	}

	// Open the input file
	File *inputFile = NULL;
	try
	{
		if (pathIn == NULL)
		{
			#if !defined (unix)
				setmode(fileno(stdin), O_BINARY);
			#endif
			inputFile = File::fromFileHandle(stdin);
		}
		else
		{
			inputFile = File::fromFileName(
				pathIn, File::FOPEN_READ | File::FOPEN_BINARY);
		}
	}
	catch (...)
	{
		fprintf(stderr, "Failed to open %s for reading.\n", pathIn);
		exit(EXIT_FAILURE);
	}
	File::OffsetType totalSize = inputFile->getFileSize();

	if (!desiredPositionSpecified)
	{
		if (overwrite)
		{
			desiredPosition = totalSize - activeCRC->getNumBytes();
		}
		else
		{
			desiredPosition = totalSize;
		}
	}
	else
	{
		if (desiredPosition < 0)
		{
			desiredPosition += totalSize;
		}
	}
	if (!overwrite)
	{
		totalSize += activeCRC->getNumBytes();
	}
	if (desiredPosition < 0 ||
		desiredPosition + ((File::OffsetType) activeCRC->getNumBytes()) > totalSize)
	{
		fputs("Patch position is located outside available input.\n", stderr);
		exit(EXIT_FAILURE);
	}
	pmesg(ERRLEV_DEBUG,
		"Desired position: %lld (file size: %lld)\n",
		desiredPosition,
		inputFile->getFileSize());

	// Open the output file
	File *outputFile = NULL;
	try
	{
		if (pathOut == NULL)
		{
			#if !defined (unix)
				setmode(fileno(stdout), O_BINARY);
			#endif
			outputFile = File::fromFileHandle(stdout);
		}
		else
		{
			outputFile = File::fromFileName(
				pathOut, File::FOPEN_WRITE | File::FOPEN_BINARY);
		}
	}
	catch (...)
	{
		fprintf(stderr, "Failed to open %s for writing.\n", pathOut);
		exit(EXIT_FAILURE);
	}

	// Perform desired operation
	activeCRC->applyPatch(
		desiredChecksum,
		desiredPosition,
		*inputFile,
		*outputFile,
		overwrite);

	// Cleanup
	delete activeCRC;
	delete inputFile;
	delete outputFile;
	exit(EXIT_SUCCESS);
}
<commit_msg>Fixed #3<commit_after>#if defined __linux__
#elif defined _WIN32 || defined _WIN64 || defined __CYGWIN__
	#include <Windows.h>
#else
    #error unknown platform
#endif

#include "debug.h"
#include "version.h"
#include "CRC/CRC.h"
#include "CRC/CRC32.h"
#include "CRC/CRC16IBM.h"
#include "CRC/CRC16CCITT.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <unistd.h>

#if !defined (unix)
	#include <sys/fcntl.h> // for setmode
#endif

const char *getPathToSelf()
{
	const size_t bufferSize = 256;
	static char buffer [bufferSize];
	if (false);
	#if defined __linux__
	else if (readlink("/proc/self/exe", buffer, bufferSize));
	else if (readlink("/proc/curproc/file", buffer, bufferSize));
	else if (readlink("/proc/self/path/a.out", buffer, bufferSize));
	#elif defined _WIN32 || defined _WIN64
	else if (GetModuleFileName(NULL, buffer, bufferSize));
	#endif
	else strcpy(buffer, "crcmanip");

	char *slash = NULL;
	slash = strrchr(buffer, '/');
	if (slash != NULL)
	{
		strcpy(buffer, slash + 1);
	}
	slash = strrchr(buffer, '\\');
	if (slash != NULL)
	{
		strcpy(buffer, slash + 1);
	}
	return buffer;
}

const char *getVersion()
{
	const size_t bufferSize = 256;
	static char buffer [bufferSize];
	sprintf(buffer, "%d.%d", MAJOR_VERSION, MINOR_VERSION);
	return buffer;
}

void updateProgress(
	const CRC::CRCProgressType &progressType,
	const File::OffsetType &startPos,
	const File::OffsetType &curPos,
	const File::OffsetType &endPos)
{
	static int i = 0;
	static CRC::CRCProgressType lastProgressType;
	if (lastProgressType != progressType || i == 0)
	{
		lastProgressType = progressType;
		switch (progressType)
		{
			case CRC::CRCPROG_WRITE_START:
				fprintf(stderr, "Output started\n");
				fflush(stderr);
				break;
			case CRC::CRCPROG_WRITE_END:
				fprintf(stderr, "Output ended\n");
				fflush(stderr);
				break;
			case CRC::CRCPROG_CHECKSUM_START:
				fprintf(stderr, "Partial checksum started\n");
				fflush(stderr);
				break;
			case CRC::CRCPROG_CHECKSUM_END:
				fprintf(stderr, "Partial checksum ended\n");
				fflush(stderr);
				break;
			default:
				break;
		}
	}
	switch (progressType)
	{
		case CRC::CRCPROG_WRITE_PROGRESS:
		case CRC::CRCPROG_CHECKSUM_PROGRESS:
			if (i % 1000 == 0)
			{
				fprintf(stderr, "%6.02f%%\r",
					(curPos - startPos) * 100.0f / (endPos - startPos));
				fflush(stderr);
			}
			++ i;
			break;
		default:
			break;
	}
}

void usage(FILE *where)
{
	fprintf(where, "%s - CRC checksum manipulator %s\n", getPathToSelf(), getVersion());
	fprintf(where, "Freely manipulate CRC32 checksums through smart file patching.\n");
	fprintf(where, "Usage: %s INFILE OUTFILE CHECKSUM [OPTIONS]\n", getPathToSelf());
	fputs("\n", where);
	fputs("INFILE               input file. if -, standard input will be used.\n", where);
	fputs("OUTFILE              output file. if -, standard output will be used.\n", where);
	fputs("CHECKSUM             desired checksum.\n\n", where);
	fputs("OPTIONS can be:\n", where);
	fputs("-h, --help           print this information.\n", where);
	fputs("-p, --position=NUM   position where to append the patch. Unless specified,\n", where);
	fputs("                     patch will be placed at the end of the input file.\n", where);
	fputs("                     If position is negative, patch will be placed at the\n", where);
	fputs("                     n-th byte from the end of file.\n", where);
	fputs("    --insert         specifies that patch should be inserted (default)\n", where);
	fputs("    --overwrite      specifies that patch should overwrite existing bytes\n", where);
	fputs("\n", where);
	/*
	fputs("Available checksum algorithms:\n", where);
	fputs("    --crc32          use crc32 (default)\n", where);
	fputs("    --crc16-ibm      use crc16-ibm, also known as crc16-ansi and crc16\n", where);
	fputs("    --crc16-ccitt    use crc16-ccitt\n", where);
	fputs("    --init-xor=VAL   use custom VAL as initial XOR value\n", where);
	fputs("    --final-xor=VAL  use custom VAL as final XOR value\n", where);
	fputs("\n", where);
	*/
	fputs("CHECKSUM must be a hexadecimal value.\n", where);
	fputs("INFILE must be seekable stream. In other words, it cannot be a pipe\n", where);
	fputs("(particularly standard input), fifo etc.\n", where);
	fputs("\n", where);
	fputs("Examples:\n", where);
	fputs("./crcmanip input.txt output.txt 1234abcd\n", where);
	fputs("./crcmanip input.txt output.txt 1234abcd -p -1\n", where);
	fputs("./crcmanip input.txt - 1234abcd >output.txt\n", where);
	fputs("./crcmanip - output.txt 1234abcd <input.txt\n", where);
	fputs("./crcmanip - - 1234abcd <input.txt >output.txt\n", where);
	exit(EXIT_FAILURE);
}

void validateChecksum(CRC &activeCRC, const char *str, CRCType &checksum)
{
	if (strlen(str) > activeCRC.getNumBytes() * 2)
	{
		fprintf(stderr,
			"Error: Specified checksum has more than %d digits.\n",
			activeCRC.getNumBytes() * 2);
		exit(EXIT_FAILURE);
	}
	if (strlen(str) < activeCRC.getNumBytes() * 2)
	{
		fprintf(stderr,
			"Warning: specified checksum has less than %d digits. "
			"Resulting checksum will be padded with 0.\n",
			activeCRC.getNumBytes() * 2);
	}
	const char *allowedCharacters = "0123456789abcdefABCDEF";
	for (size_t i = 0; i < strlen(str); i ++)
	{
		if (strchr(allowedCharacters, str[i]) == NULL)
		{
			fprintf(stderr,
				"Error: Specified checksum contains invalid characters. "
				"Only hexadecimal values are accepted.\n");
			exit(EXIT_FAILURE);
		}
	}
	checksum = strtoul(str, NULL, 16);
}

int main(int argc, char **argv)
{
	CRC *activeCRC = new CRC32();
	activeCRC->setProgressFunction(&updateProgress);

	for (int i = 1; i < argc; i ++)
	{
		if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0)
		{
			usage(stdout);
			exit(EXIT_SUCCESS);
		}
	}

	if (argc < 2)
	{
		fprintf(stderr, "No input file specified.\n");
		usage(stderr);
		exit(EXIT_FAILURE);
	}
	char *pathIn = argv[1];
	if (strcmp(pathIn, "-") == 0)
	{
		pathIn = NULL;
	}

	if (argc < 3)
	{
		fprintf(stderr, "No output file specified.\n");
		usage(stderr);
		exit(EXIT_FAILURE);
	}
	char *pathOut = argv[2];
	if (strcmp(pathOut, "-") == 0)
	{
		pathOut = NULL;
	}

	if (argc < 4)
	{
		fprintf(stderr, "No checksum specified.\n");
		usage(stderr);
		exit(EXIT_FAILURE);
	}
	uint32_t desiredChecksum = 0x12345678;
	validateChecksum(*activeCRC, argv[3], desiredChecksum);

	bool overwrite = false;
	bool desiredPositionSpecified = false;
	File::OffsetType desiredPosition = -1;

	for (int i = 4; i < argc; i ++)
	{
		if (strcmp(argv[i], "--insert") == 0)
		{
			overwrite = false;
			continue;
		}
		if (strcmp(argv[i], "--overwrite") == 0)
		{
			overwrite = true;
			continue;
		}
		if (strcmp(argv[i], "-p") == 0 ||
			strcmp(argv[i], "--pos") == 0 ||
			strcmp(argv[i], "--position") == 0)
		{
			if (i == argc - 1)
			{
				fprintf(stderr, "--position needs an additional parameter.");
				usage(stderr);
				exit(EXIT_FAILURE);
			}
			++ i;
			if (strcmp(argv[i], "-0") != 0)
			{
				desiredPosition = sizeof(desiredPosition) == sizeof(long long)
					? atoll(argv[i])
					: atol(argv[i]);
				desiredPositionSpecified = true;
			}
			continue;
		}
	}

	// Open the input file
	File *inputFile = NULL;
	try
	{
		if (pathIn == NULL)
		{
			#if !defined (unix)
				setmode(fileno(stdin), O_BINARY);
			#endif
			inputFile = File::fromFileHandle(stdin);
		}
		else
		{
			inputFile = File::fromFileName(
				pathIn, File::FOPEN_READ | File::FOPEN_BINARY);
		}
	}
	catch (...)
	{
		fprintf(stderr, "Failed to open %s for reading.\n", pathIn);
		exit(EXIT_FAILURE);
	}
	File::OffsetType totalSize = inputFile->getFileSize();

	if (!desiredPositionSpecified)
	{
		if (overwrite)
		{
			desiredPosition = totalSize - activeCRC->getNumBytes();
		}
		else
		{
			desiredPosition = totalSize;
		}
	}
	else
	{
		if (desiredPosition < 0)
		{
			desiredPosition += totalSize;
		}
	}
	if (!overwrite)
	{
		totalSize += activeCRC->getNumBytes();
	}
	if (desiredPosition < 0 ||
		desiredPosition + ((File::OffsetType) activeCRC->getNumBytes()) > totalSize)
	{
		fputs("Patch position is located outside available input.\n", stderr);
		exit(EXIT_FAILURE);
	}
	pmesg(ERRLEV_DEBUG,
		"Desired position: %lld (file size: %lld)\n",
		desiredPosition,
		inputFile->getFileSize());

	// Open the output file
	File *outputFile = NULL;
	try
	{
		if (pathOut == NULL)
		{
			#if !defined (unix)
				setmode(fileno(stdout), O_BINARY);
			#endif
			outputFile = File::fromFileHandle(stdout);
		}
		else
		{
			outputFile = File::fromFileName(
				pathOut, File::FOPEN_WRITE | File::FOPEN_BINARY);
		}
	}
	catch (...)
	{
		fprintf(stderr, "Failed to open %s for writing.\n", pathOut);
		exit(EXIT_FAILURE);
	}

	// Perform desired operation
	activeCRC->applyPatch(
		desiredChecksum,
		desiredPosition,
		*inputFile,
		*outputFile,
		overwrite);

	// Cleanup
	delete activeCRC;
	delete inputFile;
	delete outputFile;
	exit(EXIT_SUCCESS);
}
<|endoftext|>


<commit_before>// Copyright © 2014 Lénaïc Bagnères, hnc@singularity.fr

// 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.

#ifndef HNC_COMPUTER_HPP
#define HNC_COMPUTER_HPP

#include <iostream>
#include <string>
#include <fstream>

#ifdef hnc_unix
	#include <sys/utsname.h>
	#include <sys/types.h>
	#include <sys/sysctl.h>
#endif

#ifdef hnc_windows
	#include <Windows.h>
#endif

#include "to_string.hpp"
#include "string.hpp"

namespace hnc
{
	/**
	 * @brief Get informations on computer
	 *
	 * @code
	   #include <hnc/computer.hpp>
	   @endcode
	 */
	namespace computer
	{
		/**
		 * @brief Get the name of the operating system
		 *
		   @code
		   	#include <hnc/computer.hpp>
		   @endcode
		 *
		 * @Return the name of the operating system
		 */
		inline std::string system_name()
		{
			#ifdef hnc_unix

				struct utsname infos;
				uname(&infos);

				return std::string(infos.sysname);

			#elif hnc_windows

				// http://msdn.microsoft.com/en-us/library/windows/desktop/ms724833%28v=vs.85%29.aspx

				OSVERSIONINFOEX infos;

				if (infos.dwMajorVersion == 6 && infos.dwMinorVersion == 3 && infos.wProductType == VER_NT_WORKSTATION)
				{
					return "Windows 8.1";
				}
				else if (infos.dwMajorVersion == 6 && infos.dwMinorVersion == 3 && infos.wProductType != VER_NT_WORKSTATION)
				{
					return "Windows Server 2012 R2";
				}
				else if (infos.dwMajorVersion == 6 && infos.dwMinorVersion == 2 && infos.wProductType == VER_NT_WORKSTATION)
				{
					return "Windows 8";
				}
				else if (infos.dwMajorVersion == 6 && infos.dwMinorVersion == 2 && infos.wProductType != VER_NT_WORKSTATION)
				{
					return "Windows Server 2012";
				}
				else if (infos.dwMajorVersion == 6 && infos.dwMinorVersion == 1 && infos.wProductType == VER_NT_WORKSTATION)
				{
					return "Windows 7";
				}
				else if (infos.dwMajorVersion == 6 && infos.dwMinorVersion == 1 && infos.wProductType != VER_NT_WORKSTATION)
				{
					return "Windows Server 2008 R2";
				}
				else if (infos.dwMajorVersion == 6 && infos.dwMinorVersion == 0 && infos.wProductType == VER_NT_WORKSTATION)
				{
					return "Windows Vista";
				}
				else if (infos.dwMajorVersion == 6 && infos.dwMinorVersion == 0 && infos.wProductType != VER_NT_WORKSTATION)
				{
					return "Windows Server 2008";
				}
				else if (infos.dwMajorVersion == 5 && infos.dwMinorVersion == 2 &&  GetSystemMetrics(SM_SERVERR2) != 0)
				{
					return "Windows Server 2003 R2";
				}
				else if (infos.dwMajorVersion == 5 && infos.dwMinorVersion == 2 && infos.wSuiteMask & VER_SUITE_WH_SERVER)
				{
					return "Windows Home Server";
				}
				else if (infos.dwMajorVersion == 5 && infos.dwMinorVersion == 2 &&  GetSystemMetrics(SM_SERVERR2) == 0)
				{
					return "Windows Server 2003";
				}
				else if (infos.dwMajorVersion == 5 && infos.dwMinorVersion == 2 &&  OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION && SYSTEM_INFO.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
				{
					return "Windows XP Professional x64 Edition";
				}
				else if (infos.dwMajorVersion == 5 && infos.dwMinorVersion == 1)
				{
					return "Windows XP";
				}
				else if (infos.dwMajorVersion == 5 && infos.dwMinorVersion == 0)
				{
					return "Windows 2000";
				}
				else
				{
					return "Windows";
				}

			#else

				throw hnc::except::incomplete_implementation("hnc::computer::system_name is not implemented on your platform, please write a bug report or send a mail https://gitorious.org/hnc");

			#endif
		}

		/**
		 * @brief Get the version of the operating system
		 *
		   @code
		   	#include <hnc/computer.hpp>
		   @endcode
		 *
		 * @Return the version of the operating system
		 */
		inline std::string system_version()
		{
			#ifdef hnc_unix

				struct utsname infos;
				uname(&infos);

				return std::string(infos.release);

			#elif hnc_windows

				// http://msdn.microsoft.com/en-us/library/windows/desktop/ms724833%28v=vs.85%29.aspx
				OSVERSIONINFOEX infos;
				return hnc::to_string(infos.dwMajorVersion) + "." + hnc::to_string(infos.dwMinorVersion);

			#else

				throw hnc::except::incomplete_implementation("hnc::computer::system_version is not implemented on your platform, please write a bug report or send a mail https://gitorious.org/hnc");

			#endif
		}

		/**
		 * @brief Get the model name of the processor
		 *
		   @code
		   	#include <hnc/computer.hpp>
		   @endcode
		 *
		 * @Return the model name of the processor
		 */
		inline std::string processor_name()
		{
			// http://stackoverflow.com/questions/18592580/how-to-check-cpu-name-model-speed-on-windows-linux-c

			#ifdef hnc_linux

				std::ifstream cpuinfo("/proc/cpuinfo");

				while (cpuinfo.good())
				{
					std::string line;
					std::getline(cpuinfo, line);

					// x86_64
					if (hnc::algo::find_range(line, "model name"_s) != line.end())
					{
						hnc::string::remove_multiple_whitespaces(line);
						hnc::algo::replace_all(line, "model name : "_s, ""_s);
						return line;
					}
					// ARM
					else if (hnc::algo::find_range(line, "Processor"_s) != line.end())
					{
						hnc::string::remove_multiple_whitespaces(line);
						hnc::algo::replace_all(line, "Processor : "_s, ""_s);
						return line;
					}
				}

				return "Unknown";

			#elif hnc_unix

				#ifndef hnc_linux

					std::size_t const buffer_size = 512;
					char buffer[buffer_size];
					std::fill(buffer, buffer + buffer_size, '\0');

					sysctlbyname("machdep.cpu.brand_string", &buffer, &buffer_size, NULL, 0);

					return buffer;

				#endif

			#elif hnc_windows

				// http://msdn.microsoft.com/en-us/library/windows/desktop/ms724958%28v=vs.85%29.aspx

				SYSTEM_INFO infos; GetSystemInfo(&infos);

				if (infos.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) { return "x64 (AMD or Intel)"; }
				else if (infos.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM) { return "ARM"; }
				else if (infos.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) { return "Intel Itanium-based"; }
				else if (infos.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) { return "x86"; }
				else if (infos.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_UNKNOWN) { return "Unknown"; }

				return "Unknown";

			#else

				throw hnc::except::incomplete_implementation("hnc::computer::processor_name is not implemented on your platform, please write a bug report or send a mail https://gitorious.org/hnc");

			#endif
		}
	}
}

#endif
<commit_msg>Fix hnc::computer::processor_name for UNIX<commit_after>// Copyright © 2014 Lénaïc Bagnères, hnc@singularity.fr

// 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.

#ifndef HNC_COMPUTER_HPP
#define HNC_COMPUTER_HPP

#include <iostream>
#include <string>
#include <fstream>

#ifdef hnc_unix
	#include <sys/utsname.h>
	#include <sys/types.h>
	#include <sys/sysctl.h>
#endif

#ifdef hnc_windows
	#include <Windows.h>
#endif

#include "to_string.hpp"
#include "string.hpp"

namespace hnc
{
	/**
	 * @brief Get informations on computer
	 *
	 * @code
	   #include <hnc/computer.hpp>
	   @endcode
	 */
	namespace computer
	{
		/**
		 * @brief Get the name of the operating system
		 *
		   @code
		   	#include <hnc/computer.hpp>
		   @endcode
		 *
		 * @Return the name of the operating system
		 */
		inline std::string system_name()
		{
			#ifdef hnc_unix

				struct utsname infos;
				uname(&infos);

				return std::string(infos.sysname);

			#elif hnc_windows

				// http://msdn.microsoft.com/en-us/library/windows/desktop/ms724833%28v=vs.85%29.aspx

				OSVERSIONINFOEX infos;

				if (infos.dwMajorVersion == 6 && infos.dwMinorVersion == 3 && infos.wProductType == VER_NT_WORKSTATION)
				{
					return "Windows 8.1";
				}
				else if (infos.dwMajorVersion == 6 && infos.dwMinorVersion == 3 && infos.wProductType != VER_NT_WORKSTATION)
				{
					return "Windows Server 2012 R2";
				}
				else if (infos.dwMajorVersion == 6 && infos.dwMinorVersion == 2 && infos.wProductType == VER_NT_WORKSTATION)
				{
					return "Windows 8";
				}
				else if (infos.dwMajorVersion == 6 && infos.dwMinorVersion == 2 && infos.wProductType != VER_NT_WORKSTATION)
				{
					return "Windows Server 2012";
				}
				else if (infos.dwMajorVersion == 6 && infos.dwMinorVersion == 1 && infos.wProductType == VER_NT_WORKSTATION)
				{
					return "Windows 7";
				}
				else if (infos.dwMajorVersion == 6 && infos.dwMinorVersion == 1 && infos.wProductType != VER_NT_WORKSTATION)
				{
					return "Windows Server 2008 R2";
				}
				else if (infos.dwMajorVersion == 6 && infos.dwMinorVersion == 0 && infos.wProductType == VER_NT_WORKSTATION)
				{
					return "Windows Vista";
				}
				else if (infos.dwMajorVersion == 6 && infos.dwMinorVersion == 0 && infos.wProductType != VER_NT_WORKSTATION)
				{
					return "Windows Server 2008";
				}
				else if (infos.dwMajorVersion == 5 && infos.dwMinorVersion == 2 &&  GetSystemMetrics(SM_SERVERR2) != 0)
				{
					return "Windows Server 2003 R2";
				}
				else if (infos.dwMajorVersion == 5 && infos.dwMinorVersion == 2 && infos.wSuiteMask & VER_SUITE_WH_SERVER)
				{
					return "Windows Home Server";
				}
				else if (infos.dwMajorVersion == 5 && infos.dwMinorVersion == 2 &&  GetSystemMetrics(SM_SERVERR2) == 0)
				{
					return "Windows Server 2003";
				}
				else if (infos.dwMajorVersion == 5 && infos.dwMinorVersion == 2 &&  OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION && SYSTEM_INFO.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
				{
					return "Windows XP Professional x64 Edition";
				}
				else if (infos.dwMajorVersion == 5 && infos.dwMinorVersion == 1)
				{
					return "Windows XP";
				}
				else if (infos.dwMajorVersion == 5 && infos.dwMinorVersion == 0)
				{
					return "Windows 2000";
				}
				else
				{
					return "Windows";
				}

			#else

				throw hnc::except::incomplete_implementation("hnc::computer::system_name is not implemented on your platform, please write a bug report or send a mail https://gitorious.org/hnc");

			#endif
		}

		/**
		 * @brief Get the version of the operating system
		 *
		   @code
		   	#include <hnc/computer.hpp>
		   @endcode
		 *
		 * @Return the version of the operating system
		 */
		inline std::string system_version()
		{
			#ifdef hnc_unix

				struct utsname infos;
				uname(&infos);

				return std::string(infos.release);

			#elif hnc_windows

				// http://msdn.microsoft.com/en-us/library/windows/desktop/ms724833%28v=vs.85%29.aspx
				OSVERSIONINFOEX infos;
				return hnc::to_string(infos.dwMajorVersion) + "." + hnc::to_string(infos.dwMinorVersion);

			#else

				throw hnc::except::incomplete_implementation("hnc::computer::system_version is not implemented on your platform, please write a bug report or send a mail https://gitorious.org/hnc");

			#endif
		}

		/**
		 * @brief Get the model name of the processor
		 *
		   @code
		   	#include <hnc/computer.hpp>
		   @endcode
		 *
		 * @Return the model name of the processor
		 */
		inline std::string processor_name()
		{
			// http://stackoverflow.com/questions/18592580/how-to-check-cpu-name-model-speed-on-windows-linux-c

			#ifdef hnc_linux

				std::ifstream cpuinfo("/proc/cpuinfo");

				while (cpuinfo.good())
				{
					std::string line;
					std::getline(cpuinfo, line);

					// x86_64
					if (hnc::algo::find_range(line, "model name"_s) != line.end())
					{
						hnc::string::remove_multiple_whitespaces(line);
						hnc::algo::replace_all(line, "model name : "_s, ""_s);
						return line;
					}
					// ARM
					else if (hnc::algo::find_range(line, "Processor"_s) != line.end())
					{
						hnc::string::remove_multiple_whitespaces(line);
						hnc::algo::replace_all(line, "Processor : "_s, ""_s);
						return line;
					}
				}

				return "Unknown";

			#elif hnc_unix

				#ifndef hnc_linux

					char buffer[512];
					std::size_t buffer_size = sizeof(buffer) / sizeof(char);
					std::fill(buffer, buffer + buffer_size, '\0');

					sysctlbyname("machdep.cpu.brand_string", &buffer, &buffer_size, NULL, 0);

					return buffer;

				#endif

			#elif hnc_windows

				// http://msdn.microsoft.com/en-us/library/windows/desktop/ms724958%28v=vs.85%29.aspx

				SYSTEM_INFO infos; GetSystemInfo(&infos);

				if (infos.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) { return "x64 (AMD or Intel)"; }
				else if (infos.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM) { return "ARM"; }
				else if (infos.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) { return "Intel Itanium-based"; }
				else if (infos.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) { return "x86"; }
				else if (infos.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_UNKNOWN) { return "Unknown"; }

				return "Unknown";

			#else

				throw hnc::except::incomplete_implementation("hnc::computer::processor_name is not implemented on your platform, please write a bug report or send a mail https://gitorious.org/hnc");

			#endif
		}
	}
}

#endif
<|endoftext|>


<commit_before>//
// Copyright (c) 2014 CNRS
// Authors: Florent Lamiraux
//
// This file is part of hpp-core
// hpp-core is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either version
// 3 of the License, or (at your option) any later version.
//
// hpp-core is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-core  If not, see
// <http://www.gnu.org/licenses/>.

#ifndef HPP_CORE_PATH_HH
# define HPP_CORE_PATH_HH

# include <boost/concept_check.hpp>
# include <hpp/core/fwd.hh>
# include <hpp/core/config.hh>
# include <hpp/core/constraint-set.hh>
# include <hpp/core/deprecated.hh>

namespace hpp {
  namespace core {
    /// Abstraction of paths: mapping from time to configuration space
    ///
    class HPP_CORE_DLLAPI Path
    {
    public:
      /// \name Construction, destruction, copy
      /// \{

      /// Destructor
      virtual ~Path () throw () {}

      /// Return a shared pointer to a copy of this
      virtual PathPtr_t copy () const = 0;

      /// Return a shared pointer to a copy of this and set constraints
      ///
      /// \param constraints constraints to apply to the copy
      /// \precond *this should not have constraints.
      virtual PathPtr_t copy (const ConstraintSetPtr_t& constraints) const = 0;

      /// Static cast into a derived type
      template <class T> boost::shared_ptr<T> as (void)
      {
	assert (HPP_DYNAMIC_PTR_CAST (T, weak_.lock ()));
	return HPP_STATIC_PTR_CAST (T, weak_.lock ());
      }

      /// Static cast into a derived type
      template <class T> boost::shared_ptr<const T> as (void) const
      {
	assert (HPP_DYNAMIC_PTR_CAST (const T, weak_.lock ()));
	return HPP_STATIC_PTR_CAST (const T, weak_.lock ());
      }

      /// Extraction/Reversion of a sub-path
      /// \param subInterval interval of definition of the extract path
      /// If upper bound of subInterval is smaller than lower bound,
      /// result is reversed.
      virtual PathPtr_t extract (const interval_t& subInterval) const;

      /// Reversion of a path
      /// \return a new path that is this one reversed.
      virtual PathPtr_t reverse () const;

      /// \}

      Configuration_t operator () (const value_type& t) const
        HPP_CORE_DEPRECATED
      {
	Configuration_t result (outputSize ());
	impl_compute (result, t);
	if (constraints_) {
	  constraints_->apply (result);
	}
	return result;
      }

      Configuration_t operator () (const value_type& t, bool& success) const
      {
	Configuration_t result (outputSize ());
	success = impl_compute (result, t);
	if (!success) return result;
	if (constraints_) {
	  success = constraints_->apply (result);
	}
	return result;
      }

      bool operator () (ConfigurationOut_t result, const value_type& t)
       const throw ()
      {
	bool success = impl_compute (result, t);
	if (!success) return false;
	return (!constraints_ || constraints_->apply (result));
      }

      /// \brief Function evaluation without applying constraints
      ///
      /// \return true if everything went good.
      virtual bool impl_compute (ConfigurationOut_t configuration,
				 value_type t) const = 0;
      /// \name Constraints
      /// \{

      /// Get constraints the path is subject to
      const ConstraintSetPtr_t& constraints () const
      {
	return constraints_;
      }
      /// \}

      /// Get size of configuration space
      size_type outputSize () const
      {
	return outputSize_;
      }

      /// Get size of velocity
      size_type outputDerivativeSize () const
      {
	return outputDerivativeSize_;
      }

      /// Get interval of definition
      const interval_t& timeRange () const
      {
	return timeRange_;
      }

      /// Get length of definition interval
      value_type length () const
      {
	return timeRange_.second - timeRange_.first;
      }

      /// Get the initial configuration
      virtual Configuration_t initial () const = 0;

      /// Get the final configuration
      virtual Configuration_t end () const = 0;

    protected:
      /// Print path in a stream
      virtual std::ostream& print (std::ostream &os) const = 0;

      /// Constructor
      /// \param interval interval of definition of the path,
      /// \param outputSize size of the output configuration,
      /// \param outputDerivativeSize number of degrees of freedom of  the
      ///        underlying robot
      /// \param constraints constraints the set is subject to,
      ///        constraints are solved at each evaluation of the output
      ///        configuration.
      /// \note Constraints are copied.
      Path (const interval_t& interval, size_type outputSize,
	    size_type outputDerivativeSize,
	    const ConstraintSetPtr_t& constraints);

      /// Constructor
      /// \param interval interval of definition of the path,
      /// \param outputSize size of the output configuration,
      /// \param outputDerivativeSize number of degrees of freedom of  the
      ///        underlying robot
      Path (const interval_t& interval, size_type outputSize,
	    size_type outputDerivativeSize);

      /// Copy constructor
      Path (const Path& path);

      /// Copy constructor with constraints
      Path (const Path& path, const ConstraintSetPtr_t& constraints);

      /// Store weak pointer to itself
      ///
      /// should be called at construction of derived class instances
      void init (const PathPtr_t& self);
      /// should be called at copy construction of derived class instances
      void initCopy (const PathPtr_t& self);

      /// Interval of definition
      interval_t timeRange_;
    private:
      /// Size of the configuration space
      size_type outputSize_;
      /// Number of degrees of freedom of the robot
      size_type outputDerivativeSize_;
      /// Constraints that apply to the robot
      ConstraintSetPtr_t constraints_;
      /// Weak pointer to itself
      PathWkPtr_t weak_;
      friend std::ostream& operator<< (std::ostream& os, const Path& path);
    }; // class Path
    inline std::ostream& operator<< (std::ostream& os, const Path& path)
    {
      return path.print (os);
    }

  } //   namespace core
} // namespace hpp
#endif // HPP_CORE_PATH_HH
<commit_msg>Add protected setter for path constraints<commit_after>//
// Copyright (c) 2014 CNRS
// Authors: Florent Lamiraux
//
// This file is part of hpp-core
// hpp-core is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either version
// 3 of the License, or (at your option) any later version.
//
// hpp-core is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-core  If not, see
// <http://www.gnu.org/licenses/>.

#ifndef HPP_CORE_PATH_HH
# define HPP_CORE_PATH_HH

# include <boost/concept_check.hpp>
# include <hpp/core/fwd.hh>
# include <hpp/core/config.hh>
# include <hpp/core/constraint-set.hh>
# include <hpp/core/deprecated.hh>

namespace hpp {
  namespace core {
    /// Abstraction of paths: mapping from time to configuration space
    ///
    class HPP_CORE_DLLAPI Path
    {
    public:
      /// \name Construction, destruction, copy
      /// \{

      /// Destructor
      virtual ~Path () throw () {}

      /// Return a shared pointer to a copy of this
      virtual PathPtr_t copy () const = 0;

      /// Return a shared pointer to a copy of this and set constraints
      ///
      /// \param constraints constraints to apply to the copy
      /// \precond *this should not have constraints.
      virtual PathPtr_t copy (const ConstraintSetPtr_t& constraints) const = 0;

      /// Static cast into a derived type
      template <class T> boost::shared_ptr<T> as (void)
      {
	assert (HPP_DYNAMIC_PTR_CAST (T, weak_.lock ()));
	return HPP_STATIC_PTR_CAST (T, weak_.lock ());
      }

      /// Static cast into a derived type
      template <class T> boost::shared_ptr<const T> as (void) const
      {
	assert (HPP_DYNAMIC_PTR_CAST (const T, weak_.lock ()));
	return HPP_STATIC_PTR_CAST (const T, weak_.lock ());
      }

      /// Extraction/Reversion of a sub-path
      /// \param subInterval interval of definition of the extract path
      /// If upper bound of subInterval is smaller than lower bound,
      /// result is reversed.
      virtual PathPtr_t extract (const interval_t& subInterval) const;

      /// Reversion of a path
      /// \return a new path that is this one reversed.
      virtual PathPtr_t reverse () const;

      /// \}

      Configuration_t operator () (const value_type& t) const
        HPP_CORE_DEPRECATED
      {
	Configuration_t result (outputSize ());
	impl_compute (result, t);
	if (constraints_) {
	  constraints_->apply (result);
	}
	return result;
      }

      Configuration_t operator () (const value_type& t, bool& success) const
      {
	Configuration_t result (outputSize ());
	success = impl_compute (result, t);
	if (!success) return result;
	if (constraints_) {
	  success = constraints_->apply (result);
	}
	return result;
      }

      bool operator () (ConfigurationOut_t result, const value_type& t)
       const throw ()
      {
	bool success = impl_compute (result, t);
	if (!success) return false;
	return (!constraints_ || constraints_->apply (result));
      }

      /// \brief Function evaluation without applying constraints
      ///
      /// \return true if everything went good.
      virtual bool impl_compute (ConfigurationOut_t configuration,
				 value_type t) const = 0;
      /// \name Constraints
      /// \{

      /// Get constraints the path is subject to
      const ConstraintSetPtr_t& constraints () const
      {
	return constraints_;
      }
      /// \}

      /// Get size of configuration space
      size_type outputSize () const
      {
	return outputSize_;
      }

      /// Get size of velocity
      size_type outputDerivativeSize () const
      {
	return outputDerivativeSize_;
      }

      /// Get interval of definition
      const interval_t& timeRange () const
      {
	return timeRange_;
      }

      /// Get length of definition interval
      value_type length () const
      {
	return timeRange_.second - timeRange_.first;
      }

      /// Get the initial configuration
      virtual Configuration_t initial () const = 0;

      /// Get the final configuration
      virtual Configuration_t end () const = 0;

    protected:
      /// Print path in a stream
      virtual std::ostream& print (std::ostream &os) const = 0;

      /// Constructor
      /// \param interval interval of definition of the path,
      /// \param outputSize size of the output configuration,
      /// \param outputDerivativeSize number of degrees of freedom of  the
      ///        underlying robot
      /// \param constraints constraints the set is subject to,
      ///        constraints are solved at each evaluation of the output
      ///        configuration.
      /// \note Constraints are copied.
      Path (const interval_t& interval, size_type outputSize,
	    size_type outputDerivativeSize,
	    const ConstraintSetPtr_t& constraints);

      /// Constructor
      /// \param interval interval of definition of the path,
      /// \param outputSize size of the output configuration,
      /// \param outputDerivativeSize number of degrees of freedom of  the
      ///        underlying robot
      Path (const interval_t& interval, size_type outputSize,
	    size_type outputDerivativeSize);

      /// Copy constructor
      Path (const Path& path);

      /// Copy constructor with constraints
      Path (const Path& path, const ConstraintSetPtr_t& constraints);

      /// Store weak pointer to itself
      ///
      /// should be called at construction of derived class instances
      void init (const PathPtr_t& self);
      /// should be called at copy construction of derived class instances
      void initCopy (const PathPtr_t& self);

      /// Interval of definition
      interval_t timeRange_;

      /// Set the constraints
      /// \warning this method is protected for child classes that need to
      ///          initialize themselves before being sure that the initial and
      ///          end configuration satisfy the constraints
      void constraints (const ConstraintSetPtr_t& constraint) {
        constraints_ = constraint;
      }
    private:
      /// Size of the configuration space
      size_type outputSize_;
      /// Number of degrees of freedom of the robot
      size_type outputDerivativeSize_;
      /// Constraints that apply to the robot
      ConstraintSetPtr_t constraints_;
      /// Weak pointer to itself
      PathWkPtr_t weak_;
      friend std::ostream& operator<< (std::ostream& os, const Path& path);
    }; // class Path
    inline std::ostream& operator<< (std::ostream& os, const Path& path)
    {
      return path.print (os);
    }

  } //   namespace core
} // namespace hpp
#endif // HPP_CORE_PATH_HH
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2014 Cloudius Systems, Ltd.
 */

#ifndef DATABASE_HH_
#define DATABASE_HH_

#include "core/sstring.hh"
#include "core/shared_ptr.hh"
#include <functional>
#include <boost/any.hpp>
#include <cstdint>
#include <boost/variant.hpp>
#include <unordered_map>
#include <map>
#include <set>
#include <vector>
#include <iostream>
#include <boost/functional/hash.hpp>

// FIXME: should be int8_t
using bytes = basic_sstring<char, uint32_t, 31>;

class data_type {
public:
    // Hide the virtual stuff behind an impl class.  This allows us to treat
    // data_type as a normal value - we can copy, assign, and destroy it
    // without worrying about the destructor.
    struct impl {
        sstring name;
        impl(sstring name) : name(name) {}
        virtual ~impl() {}
        virtual void serialize(const boost::any& value, std::ostream& out) = 0;
        virtual boost::any deserialize(std::istream& in) = 0;
        virtual bool less(const bytes& v1, const bytes& v2) = 0;
        boost::any deserialize(const bytes& v) {
            // FIXME: optimize
            std::istringstream iss(v);
            return deserialize(iss);
        }
    };
private:
    shared_ptr<impl> _impl;
public:
    explicit data_type(shared_ptr<impl> impl) : _impl(std::move(impl)) {}
    static data_type find(const sstring& name);
    const sstring& name() const { return _impl->name; }
    void serialize(const boost::any& value, std::ostream& out) {
        return _impl->serialize(value, out);
    }
    bytes decompose(const boost::any& value) {
        // FIXME: optimize
        std::ostringstream oss;
        _impl->serialize(value, oss);
        auto s = oss.str();
        return bytes(s.data(), s.size());
    }
    boost::any deserialize(std::istream& in) {
        return _impl->deserialize(in);
    }
    boost::any deserialize(const bytes& v) {
        return _impl->deserialize(v);
    }
    bool operator==(const data_type& x) const {
        return _impl == x._impl;
    }
    bool operator!=(const data_type& x) const {
        return _impl != x._impl;
    }
    bool less(const bytes& v1, const bytes& v2) const {
        return _impl->less(v1, v2);
    }
    friend size_t hash_value(const data_type& x) {
        return std::hash<impl*>()(x._impl.get());
    }
};

template <typename Type>
data_type data_type_for();

class key_compare {
    data_type _type;
public:
    key_compare(data_type type) : _type(type) {}
    bool operator()(const bytes& v1, const bytes& v2) const {
        return _type.less(v1, v2);
    }
};

struct row;
struct paritition;
struct column_family;

struct row {
    std::vector<bytes> cells;
};

struct partition {
    explicit partition(column_family& cf);
    row static_columns;
    // row key within partition -> row
    std::map<bytes, row, key_compare> rows;
};

// FIXME: add missing types
extern thread_local data_type int_type;
extern thread_local data_type bigint_type;
extern thread_local data_type ascii_type;
extern thread_local data_type blob_type;
extern thread_local data_type varchar_type;
extern thread_local data_type text_type;

template <>
inline
data_type data_type_for<int32_t>() {
    return int_type;
}

template <>
inline
data_type data_type_for<int64_t>() {
    return bigint_type;
}

template <>
inline
data_type data_type_for<sstring>() {
    return varchar_type;
}

struct column_definition {
    sstring name;
    data_type type;
    struct name_compare {
        bool operator()(const column_definition& cd1, const column_definition& cd2) const {
            return std::lexicographical_compare(
                    cd1.name.begin(), cd1.name.end(),
                    cd2.name.begin(), cd2.name.end(),
                    [] (char c1, char c2) { return uint8_t(c1) < uint8_t(c1); });
        }
    };
};

struct column_family {
    column_family(data_type partition_key_type, data_type clustering_key_type);
    // primary key = paritition key + clustering_key
    data_type partition_key_type;
    data_type clustering_key_type;
    std::vector<column_definition> partition_key;
    std::vector<column_definition> clustering_key;
    std::vector<column_definition> column_defs; // sorted by name
    partition& find_or_create_partition(const bytes& key);
    row& find_or_create_row(const bytes& partition_key, const bytes& clustering_key);
    partition* find_partition(const bytes& key);
    row* find_row(const bytes& partition_key, const bytes& clustering_key);
    // partition key -> partition
    std::map<bytes, partition, key_compare> partitions;
};

struct keyspace {
    std::unordered_map<sstring, column_family> column_families;
};

struct database {
    std::unordered_map<sstring, keyspace> keyspaces;
};

namespace std {

template <>
struct hash<data_type> : boost::hash<data_type> {
};

}

inline
bytes
to_bytes(const char* x) {
    return bytes(reinterpret_cast<const char*>(x), std::strlen(x));
}

inline
bytes
to_bytes(const std::string& x) {
    return bytes(reinterpret_cast<const char*>(x.data()), x.size());
}

inline
bytes
to_bytes(const sstring& x) {
    return bytes(reinterpret_cast<const char*>(x.c_str()), x.size());
}

// This follows java.util.Comparator
// FIXME: Choose a better place than database.hh
template <typename T>
struct comparator {
    virtual ~comparator() {}
    virtual bool operator()(const T& v1, const T& v2) const = 0;
};

#endif /* DATABASE_HH_ */
<commit_msg>db: add abstract_type alias<commit_after>/*
 * Copyright (C) 2014 Cloudius Systems, Ltd.
 */

#ifndef DATABASE_HH_
#define DATABASE_HH_

#include "core/sstring.hh"
#include "core/shared_ptr.hh"
#include <functional>
#include <boost/any.hpp>
#include <cstdint>
#include <boost/variant.hpp>
#include <unordered_map>
#include <map>
#include <set>
#include <vector>
#include <iostream>
#include <boost/functional/hash.hpp>

// FIXME: should be int8_t
using bytes = basic_sstring<char, uint32_t, 31>;

class data_type {
public:
    // Hide the virtual stuff behind an impl class.  This allows us to treat
    // data_type as a normal value - we can copy, assign, and destroy it
    // without worrying about the destructor.
    struct impl {
        sstring name;
        impl(sstring name) : name(name) {}
        virtual ~impl() {}
        virtual void serialize(const boost::any& value, std::ostream& out) = 0;
        virtual boost::any deserialize(std::istream& in) = 0;
        virtual bool less(const bytes& v1, const bytes& v2) = 0;
        boost::any deserialize(const bytes& v) {
            // FIXME: optimize
            std::istringstream iss(v);
            return deserialize(iss);
        }
    };
private:
    shared_ptr<impl> _impl;
public:
    explicit data_type(shared_ptr<impl> impl) : _impl(std::move(impl)) {}
    static data_type find(const sstring& name);
    const sstring& name() const { return _impl->name; }
    void serialize(const boost::any& value, std::ostream& out) {
        return _impl->serialize(value, out);
    }
    bytes decompose(const boost::any& value) {
        // FIXME: optimize
        std::ostringstream oss;
        _impl->serialize(value, oss);
        auto s = oss.str();
        return bytes(s.data(), s.size());
    }
    boost::any deserialize(std::istream& in) {
        return _impl->deserialize(in);
    }
    boost::any deserialize(const bytes& v) {
        return _impl->deserialize(v);
    }
    bool operator==(const data_type& x) const {
        return _impl == x._impl;
    }
    bool operator!=(const data_type& x) const {
        return _impl != x._impl;
    }
    bool less(const bytes& v1, const bytes& v2) const {
        return _impl->less(v1, v2);
    }
    friend size_t hash_value(const data_type& x) {
        return std::hash<impl*>()(x._impl.get());
    }
};

using abstract_type = data_type;

template <typename Type>
data_type data_type_for();

class key_compare {
    data_type _type;
public:
    key_compare(data_type type) : _type(type) {}
    bool operator()(const bytes& v1, const bytes& v2) const {
        return _type.less(v1, v2);
    }
};

struct row;
struct paritition;
struct column_family;

struct row {
    std::vector<bytes> cells;
};

struct partition {
    explicit partition(column_family& cf);
    row static_columns;
    // row key within partition -> row
    std::map<bytes, row, key_compare> rows;
};

// FIXME: add missing types
extern thread_local data_type int_type;
extern thread_local data_type bigint_type;
extern thread_local data_type ascii_type;
extern thread_local data_type blob_type;
extern thread_local data_type varchar_type;
extern thread_local data_type text_type;

template <>
inline
data_type data_type_for<int32_t>() {
    return int_type;
}

template <>
inline
data_type data_type_for<int64_t>() {
    return bigint_type;
}

template <>
inline
data_type data_type_for<sstring>() {
    return varchar_type;
}

struct column_definition {
    sstring name;
    data_type type;
    struct name_compare {
        bool operator()(const column_definition& cd1, const column_definition& cd2) const {
            return std::lexicographical_compare(
                    cd1.name.begin(), cd1.name.end(),
                    cd2.name.begin(), cd2.name.end(),
                    [] (char c1, char c2) { return uint8_t(c1) < uint8_t(c1); });
        }
    };
};

struct column_family {
    column_family(data_type partition_key_type, data_type clustering_key_type);
    // primary key = paritition key + clustering_key
    data_type partition_key_type;
    data_type clustering_key_type;
    std::vector<column_definition> partition_key;
    std::vector<column_definition> clustering_key;
    std::vector<column_definition> column_defs; // sorted by name
    partition& find_or_create_partition(const bytes& key);
    row& find_or_create_row(const bytes& partition_key, const bytes& clustering_key);
    partition* find_partition(const bytes& key);
    row* find_row(const bytes& partition_key, const bytes& clustering_key);
    // partition key -> partition
    std::map<bytes, partition, key_compare> partitions;
};

struct keyspace {
    std::unordered_map<sstring, column_family> column_families;
};

struct database {
    std::unordered_map<sstring, keyspace> keyspaces;
};

namespace std {

template <>
struct hash<data_type> : boost::hash<data_type> {
};

}

inline
bytes
to_bytes(const char* x) {
    return bytes(reinterpret_cast<const char*>(x), std::strlen(x));
}

inline
bytes
to_bytes(const std::string& x) {
    return bytes(reinterpret_cast<const char*>(x.data()), x.size());
}

inline
bytes
to_bytes(const sstring& x) {
    return bytes(reinterpret_cast<const char*>(x.c_str()), x.size());
}

// This follows java.util.Comparator
// FIXME: Choose a better place than database.hh
template <typename T>
struct comparator {
    virtual ~comparator() {}
    virtual bool operator()(const T& v1, const T& v2) const = 0;
};

#endif /* DATABASE_HH_ */
<|endoftext|>


<commit_before>/*
 * MpiProvider.cpp
 *
 * Copyright (C) 2014 Visualisierungsinstitut der Universität Stuttgart.
 * Alle Rechte vorbehalten.
 */

#include "stdafx.h"
#include "MpiProvider.h"

#ifndef WIN32
#include <cstdio>
#include <cstdlib>
#endif /* !_WIN32 */

#include "MpiCall.h"

#include "vislib/assert.h"
#include "vislib/CmdLineProvider.h"
#include "vislib/Log.h"

/*
 * megamol::core::cluster::mpi::MpiProvider::IsAvailable
 */
bool megamol::core::cluster::mpi::MpiProvider::IsAvailable(void) {
#ifdef WITH_MPI
    return true;
#else /* WITH_MPI */
    return false;
#endif /* WITH_MPI */
}

/*
 * megamol::core::cluster::mpi::MpiProvider::MpiProvider
 */
megamol::core::cluster::mpi::MpiProvider::MpiProvider(void) : Base(),
        callProvideMpi("provideMpi", "Provides the MPI communicator etc.") {
#ifdef WITH_MPI
    this->comm = MPI_COMM_NULL;
#endif /* WITH_MPI */

    this->callProvideMpi.SetCallback(MpiCall::ClassName(),
        MpiCall::FunctionName(MpiCall::IDX_PROVIDE_MPI),
        &MpiProvider::OnCallProvideMpi);
    this->MakeSlotAvailable(&this->callProvideMpi);
}

/*
 * megamol::core::cluster::mpi::MpiProvider::~MpiProvider
 */
megamol::core::cluster::mpi::MpiProvider::~MpiProvider(void) {
    this->Release();
}

/*
 * megamol::core::cluster::mpi::MpiProvider::create
 */
bool megamol::core::cluster::mpi::MpiProvider::create(void) {
    return true;
}

/*
 * megamol::core::cluster::mpi::MpiProvider::OnCallProvideMpi
 */
bool megamol::core::cluster::mpi::MpiProvider::OnCallProvideMpi(Call& call) {
#ifdef WITH_MPI
    try {
        auto c = dynamic_cast<MpiCall&>(call);
        ASSERT(!c.GetIsInitialising());

        if (this->comm == MPI_COMM_NULL) {
            if (!this->initialiseMpi(c.GetColour())) {
                return false;
            }
            c.SetIsInitialising(true);
        }
        ASSERT(this->comm != MPI_COMM_NULL);

        c.SetComm(this->comm);

        return true;
    } catch (...) {
        return false;
    }

#else /* WITH_MPI */
    return false;
#endif /* WITH_MPI */
}

/*
 * megamol::core::cluster::mpi::MpiProvider::release
 */
void megamol::core::cluster::mpi::MpiProvider::release(void) {
#ifdef WITH_MPI
    if (this->comm != MPI_COMM_NULL) {
        ::MPI_Comm_free(&this->comm);
        this->comm = MPI_COMM_NULL;
        ::MPI_Finalize();
    }
#endif /* WITH_MPI */
}

/*
 * megamol::core::cluster::mpi::MpiProvider::getCommandLine
 */
vislib::StringA megamol::core::cluster::mpi::MpiProvider::getCommandLine(void) {
    vislib::StringA retval;

#ifdef WIN32
    retval = ::GetCommandLineA();
#else /* _WIN32 */
    char *arg = nullptr;
    size_t size = 0;

    auto fp = ::fopen("/proc/self/cmdline", "rb");
    if (fp != nullptr) {
        while (::getdelim(&arg, &size, 0, fp) != -1) {
            retval.Append(arg, size);
            retval.Append(" ");
        }
        ::free(arg);
        ::fclose(fp);
    }
#endif /* _WIN32 */

    vislib::sys::Log::DefaultLog.WriteInfo("Command line used for MPI "
        "initialisation is \"%s\".", retval.PeekBuffer());
    return retval;
}

/*
 * megamol::core::cluster::mpi::MpiProvider::initialiseMpi
 */
bool megamol::core::cluster::mpi::MpiProvider::initialiseMpi(const int colour) {
    using vislib::sys::Log;

#ifdef WITH_MPI
    int isInitialised = false;
    int rank = 0;

    ::MPI_Initialized(&isInitialised);

    if (isInitialised != 0) {
        Log::DefaultLog.WriteWarn("MPI has already been initialised before "
            "MpiProvider::initialiseMpi was called. This might indicate an "
            "application error as some one else is also using MPI, which we "
            "did not expect.");

    } else {
        vislib::sys::CmdLineProviderA cmdLine(MpiProvider::getCommandLine());
        auto argc = cmdLine.ArgC();
        auto argv = cmdLine.ArgV();

        Log::DefaultLog.WriteInfo("Initialising MPI ...");
        auto status =::MPI_Init(&argc, &argv);
        if (status != MPI_SUCCESS) {
            Log::DefaultLog.WriteError("MPI_Init failed with error code %d",
                status);
            return false;
        }
    }

    Log::DefaultLog.WriteInfo("Performing node colouring with colour %d ...",
        colour);
    ::MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    ::MPI_Comm_split(MPI_COMM_WORLD, colour, rank, &this->comm);
    // TODO: Check status?

    return true;

#else /* WITH_MPI */
    return false;
#endif /* WITH_MPI */
}
<commit_msg>Fixed casting bug.<commit_after>/*
 * MpiProvider.cpp
 *
 * Copyright (C) 2014 Visualisierungsinstitut der Universität Stuttgart.
 * Alle Rechte vorbehalten.
 */

#include "stdafx.h"
#include "MpiProvider.h"

#ifndef WIN32
#include <cstdio>
#include <cstdlib>
#endif /* !_WIN32 */

#include "MpiCall.h"

#include "vislib/assert.h"
#include "vislib/CmdLineProvider.h"
#include "vislib/Log.h"

/*
 * megamol::core::cluster::mpi::MpiProvider::IsAvailable
 */
bool megamol::core::cluster::mpi::MpiProvider::IsAvailable(void) {
#ifdef WITH_MPI
    return true;
#else /* WITH_MPI */
    return false;
#endif /* WITH_MPI */
}

/*
 * megamol::core::cluster::mpi::MpiProvider::MpiProvider
 */
megamol::core::cluster::mpi::MpiProvider::MpiProvider(void) : Base(),
        callProvideMpi("provideMpi", "Provides the MPI communicator etc.") {
#ifdef WITH_MPI
    this->comm = MPI_COMM_NULL;
#endif /* WITH_MPI */

    this->callProvideMpi.SetCallback(MpiCall::ClassName(),
        MpiCall::FunctionName(MpiCall::IDX_PROVIDE_MPI),
        &MpiProvider::OnCallProvideMpi);
    this->MakeSlotAvailable(&this->callProvideMpi);
}

/*
 * megamol::core::cluster::mpi::MpiProvider::~MpiProvider
 */
megamol::core::cluster::mpi::MpiProvider::~MpiProvider(void) {
    this->Release();
}

/*
 * megamol::core::cluster::mpi::MpiProvider::create
 */
bool megamol::core::cluster::mpi::MpiProvider::create(void) {
    return true;
}

/*
 * megamol::core::cluster::mpi::MpiProvider::OnCallProvideMpi
 */
bool megamol::core::cluster::mpi::MpiProvider::OnCallProvideMpi(Call& call) {
#ifdef WITH_MPI
    try {
        auto& c = dynamic_cast<MpiCall&>(call);
        ASSERT(!c.GetIsInitialising());

        if (this->comm == MPI_COMM_NULL) {
            if (!this->initialiseMpi(c.GetColour())) {
                return false;
            }
            c.SetIsInitialising(true);
        }
        ASSERT(this->comm != MPI_COMM_NULL);

        c.SetComm(this->comm);

        return true;
    } catch (...) {
        return false;
    }

#else /* WITH_MPI */
    return false;
#endif /* WITH_MPI */
}

/*
 * megamol::core::cluster::mpi::MpiProvider::release
 */
void megamol::core::cluster::mpi::MpiProvider::release(void) {
#ifdef WITH_MPI
    if (this->comm != MPI_COMM_NULL) {
        ::MPI_Comm_free(&this->comm);
        this->comm = MPI_COMM_NULL;
        ::MPI_Finalize();
    }
#endif /* WITH_MPI */
}

/*
 * megamol::core::cluster::mpi::MpiProvider::getCommandLine
 */
vislib::StringA megamol::core::cluster::mpi::MpiProvider::getCommandLine(void) {
    vislib::StringA retval;

#ifdef WIN32
    retval = ::GetCommandLineA();
#else /* _WIN32 */
    char *arg = nullptr;
    size_t size = 0;

    auto fp = ::fopen("/proc/self/cmdline", "rb");
    if (fp != nullptr) {
        while (::getdelim(&arg, &size, 0, fp) != -1) {
            retval.Append(arg, size);
            retval.Append(" ");
        }
        ::free(arg);
        ::fclose(fp);
    }
#endif /* _WIN32 */

    vislib::sys::Log::DefaultLog.WriteInfo("Command line used for MPI "
        "initialisation is \"%s\".", retval.PeekBuffer());
    return retval;
}

/*
 * megamol::core::cluster::mpi::MpiProvider::initialiseMpi
 */
bool megamol::core::cluster::mpi::MpiProvider::initialiseMpi(const int colour) {
    using vislib::sys::Log;

#ifdef WITH_MPI
    int isInitialised = 0;
    int rank = 0;

    ::MPI_Initialized(&isInitialised);

    if (isInitialised != 0) {
        Log::DefaultLog.WriteWarn("MPI has already been initialised before "
            "MpiProvider::initialiseMpi was called. This might indicate an "
            "application error as some one else is also using MPI, which we "
            "did not expect.");

    } else {
        vislib::sys::CmdLineProviderA cmdLine(MpiProvider::getCommandLine());
        auto argc = cmdLine.ArgC();
        auto argv = cmdLine.ArgV();

        Log::DefaultLog.WriteInfo("Initialising MPI ...");
        auto status =::MPI_Init(&argc, &argv);
        if (status != MPI_SUCCESS) {
            Log::DefaultLog.WriteError("MPI_Init failed with error code %d",
                status);
            return false;
        }
    }

    Log::DefaultLog.WriteInfo("Performing node colouring with colour %d ...",
        colour);
    ::MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    ::MPI_Comm_split(MPI_COMM_WORLD, colour, rank, &this->comm);
    // TODO: Check status?

    return true;

#else /* WITH_MPI */
    return false;
#endif /* WITH_MPI */
}
<|endoftext|>