<commit_before>/* RTcmix  - Copyright (C) 2000  The RTcmix Development Team
   See ``AUTHORS'' for a list of contributors. See ``LICENSE'' for
   the license to this software and for a DISCLAIMER OF ALL WARRANTIES.
*/
// audio_devices.cpp
// C++ functions for creating and configuring AudioDevice instances for input
// and output.
//

#include <string.h>
#include <RTcmix.h>
#include <sndlibsupport.h>
#include <ugens.h>
#include <prototypes.h>
#include <assert.h>
#include <Option.h>

#include "AudioDevice.h"
#include "AudioFileDevice.h"
#include "AudioIODevice.h"
#include "AudioOutputGroupDevice.h"
#include "DualOutputAudioDevice.h"
#include "audio_devices.h"

#ifdef NETAUDIO
char globalNetworkPath[128];			// Set by Minc/setnetplay.c
#endif

AudioDevice *globalAudioDevice;			// Used by Minc/intraverse.C

// Return pointers to the most recently specified audio device strings.
// "indevice" always overrides "device", and same with "outdevice".

const char *get_audio_device_name()
{
	if (strlen(Option::inDevice()) || strlen(Option::outDevice()))
		return NULL;
	if (strlen(Option::device()))
		return Option::device();
	return NULL;
}

const char *get_audio_indevice_name()
{
	if (strlen(Option::inDevice()))
		return Option::inDevice();
	else if (strlen(Option::device()))
		return Option::device();
	return NULL;
}

const char *get_audio_outdevice_name()
{
	if (strlen(Option::outDevice()))
		return Option::outDevice();
	else if (strlen(Option::device()))
		return Option::device();
	return NULL;
}

int
create_audio_devices(int record, int play, int chans, float srate, int *buffersize, int numBuffers)
{
	int status;
	const char *inDeviceName = get_audio_indevice_name();
	const char *outDeviceName = get_audio_outdevice_name();
	AudioDevice *device = NULL;

#ifdef NETAUDIO
	// For backwards compatibility, we check to see if a network path was set
	// via the command line and stored in the global.
	if (strlen(globalNetworkPath) > 0)
		outDeviceName = globalNetworkPath;
#endif	// NETAUDIO

	// See audio_dev_creator.cpp for this function.
	device = createAudioDevice(inDeviceName, outDeviceName, record, play);
	if (device == NULL) {
		die("rtsetparams", "Failed to create audio device.");
		return -1;
	}

	// We hand the device noninterleaved, full-range floating point buffers.
	int audioFormat = NATIVE_FLOAT_FMT | MUS_NON_INTERLEAVED;
	device->setFrameFormat(audioFormat, chans);

	int openMode = (record && play) ? AudioDevice::RecordPlayback
				   : (record) ? AudioDevice::Record
				   : AudioDevice::Playback;
	if (Option::checkPeaks())
		openMode |= AudioDevice::CheckPeaks;
	if (Option::reportClipping())
		openMode |= AudioDevice::ReportClipping;

	printf("DEBUG: audio device: peak check: %d report clip: %d\n",
		   openMode & AudioDevice::CheckPeaks, openMode & AudioDevice::ReportClipping);

	if ((status = device->open(openMode, audioFormat, chans, srate)) == 0)
	{
		int reqsize = *buffersize;
		int reqcount = numBuffers;
		if ((status = device->setQueueSize(&reqsize, &reqcount)) < 0) {
			die("rtsetparams", "%s", device->getLastError());
			return -1;
		}
		int newSize = reqsize * numBuffers / reqcount;
		if (newSize != *buffersize) {
			advise("rtsetparams",
				   "RTBUFSAMPS reset by audio device from %d to %d.",
					*buffersize, newSize);
			*buffersize = newSize;
		}
	}
	else
	{
		die("rtsetparams", "%s", device->getLastError());
		return -1;
	}

	globalAudioDevice = device;

	return status;
}

int create_audio_file_device(const char *outfilename,
							 int header_type,
							 int sample_format,
							 int chans,
							 float srate,
							 int normalize_output_floats,
							 int check_peaks)
{
	assert(rtsetparams_was_called());

	AudioFileDevice *fileDevice = new AudioFileDevice(outfilename,
													  header_type);

	if (fileDevice == NULL) {
		rterror("rtoutput", "Failed to create audio file device");
		return -1;
	}

	// Here is the logic for opening the file device.  We do this all in
	// advance now, rather than over and over during rtwritesamps().

	const bool recording = Option::record();
	const bool playing = Option::play();
	const bool fileIsRawFloats = IS_FLOAT_FORMAT(sample_format) && !normalize_output_floats;

	int openMode = AudioFileDevice::Playback;
	if (playing | recording)
		openMode |= AudioDevice::Passive;		// Don't run thread for file device.
	if (!fileIsRawFloats || (check_peaks && !playing))
		openMode |= AudioDevice::CheckPeaks;	// Dont check peaks if HW already doing so.
	if (Option::reportClipping() && !playing)
		openMode |= AudioDevice::ReportClipping;	// Ditto for reporting of clipping

	printf("DEBUG: file device: peak check: %d report clip: %d\n",
		   openMode & AudioDevice::CheckPeaks, openMode & AudioDevice::ReportClipping);

	// We send the device noninterleaved, floating point buffers.  If we are playing
	// to HW at the same time, the data received by the file device will already be
	// clipped.

	int audioFormat = NATIVE_FLOAT_FMT | MUS_NON_INTERLEAVED;
	if (playing) audioFormat |= MUS_CLIPPED;

	fileDevice->setFrameFormat(audioFormat, chans);

	// File format is interleaved and may be normalized.
	sample_format |= MUS_INTERLEAVED;
	if (normalize_output_floats)
		sample_format |= MUS_NORMALIZED;
	int ret = fileDevice->open(openMode, sample_format, chans, srate);

	if (ret == -1) {
		rterror("rtoutput", "Can't create output for \"%s\": %s",
				 outfilename, fileDevice->getLastError());
		return -1;
	}
	// Cheating -- should hand in queue size as argument!
	int queueSize = RTcmix::bufsamps();
	int count = 1;
	ret = fileDevice->setQueueSize(&queueSize, &count);
	if (ret == -1) {
		rterror("rtoutput", "Failed to set queue size on file device:  %s",
				 fileDevice->getLastError());
		return -1;
	}

	if (!playing && !recording) {	// To file only.
		// If we are only writing to disk, we only have a single output device.
		globalAudioDevice = fileDevice;
	}
	else {							// To file, plus record and/or playback.
		if (playing && !recording) {		// Dual outputs to both HW and file.
			printf("DEBUG: Group output device for file and HW playback\n");
			bool fileDoesLimiting = !fileIsRawFloats;
			globalAudioDevice = new DualOutputAudioDevice(globalAudioDevice,
														  fileDevice,
														  fileDoesLimiting);
		}
		else if (recording && !playing) {	// Record from HW, write to file.
			assert(globalAudioDevice != NULL);
			printf("DEBUG: Dual device for HW record, file playback\n");
			globalAudioDevice = new AudioIODevice(globalAudioDevice, fileDevice, true);
		}
		else {	// HW Record and playback, plus write to file.
			printf("DEBUG: Dual device for HW record/playback, file playback\n");
			bool fileDoesLimiting = !fileIsRawFloats;
			globalAudioDevice = new DualOutputAudioDevice(globalAudioDevice,
														  fileDevice,
														  fileDoesLimiting);
		}
	}

	if (Option::print()) {
		 printf("Output file set for writing:\n");
		 printf("      name:  %s\n", outfilename);
		 printf("      type:  %s\n", mus_header_type_name(header_type));
		 printf("    format:  %s\n", mus_data_format_name(MUS_GET_FORMAT(sample_format)));
		 printf("     srate:  %g\n", srate);
		 printf("     chans:  %d\n", chans);
	}

	return 0;
}

int audio_input_is_initialized()
{
	return globalAudioDevice != NULL;
}

void
stop_audio_devices()
{
	// Turns out we need to close, not just stop (close calls stop)
	globalAudioDevice->close();
}

static bool destroying = false;	// avoid reentrancy

void
destroy_audio_devices()
{
	if (!destroying) {
		destroying = true;
		delete globalAudioDevice;
		globalAudioDevice = NULL;
	}
}

int
destroy_audio_file_device()
{
	int result = 0;

// 	if (globalOutputFileDevice != globalAudioDevice) {
//     	delete globalOutputFileDevice;
// 	}
// 	globalOutputFileDevice = NULL;

	return result;
}
<commit_msg>Fixed debug to print 0 or 1 for boolean<commit_after>/* RTcmix  - Copyright (C) 2000  The RTcmix Development Team
   See ``AUTHORS'' for a list of contributors. See ``LICENSE'' for
   the license to this software and for a DISCLAIMER OF ALL WARRANTIES.
*/
// audio_devices.cpp
// C++ functions for creating and configuring AudioDevice instances for input
// and output.
//

#include <string.h>
#include <RTcmix.h>
#include <sndlibsupport.h>
#include <ugens.h>
#include <prototypes.h>
#include <assert.h>
#include <Option.h>

#include "AudioDevice.h"
#include "AudioFileDevice.h"
#include "AudioIODevice.h"
#include "AudioOutputGroupDevice.h"
#include "DualOutputAudioDevice.h"
#include "audio_devices.h"

#ifdef NETAUDIO
char globalNetworkPath[128];			// Set by Minc/setnetplay.c
#endif

AudioDevice *globalAudioDevice;			// Used by Minc/intraverse.C

// Return pointers to the most recently specified audio device strings.
// "indevice" always overrides "device", and same with "outdevice".

const char *get_audio_device_name()
{
	if (strlen(Option::inDevice()) || strlen(Option::outDevice()))
		return NULL;
	if (strlen(Option::device()))
		return Option::device();
	return NULL;
}

const char *get_audio_indevice_name()
{
	if (strlen(Option::inDevice()))
		return Option::inDevice();
	else if (strlen(Option::device()))
		return Option::device();
	return NULL;
}

const char *get_audio_outdevice_name()
{
	if (strlen(Option::outDevice()))
		return Option::outDevice();
	else if (strlen(Option::device()))
		return Option::device();
	return NULL;
}

int
create_audio_devices(int record, int play, int chans, float srate, int *buffersize, int numBuffers)
{
	int status;
	const char *inDeviceName = get_audio_indevice_name();
	const char *outDeviceName = get_audio_outdevice_name();
	AudioDevice *device = NULL;

#ifdef NETAUDIO
	// For backwards compatibility, we check to see if a network path was set
	// via the command line and stored in the global.
	if (strlen(globalNetworkPath) > 0)
		outDeviceName = globalNetworkPath;
#endif	// NETAUDIO

	// See audio_dev_creator.cpp for this function.
	device = createAudioDevice(inDeviceName, outDeviceName, record, play);
	if (device == NULL) {
		die("rtsetparams", "Failed to create audio device.");
		return -1;
	}

	// We hand the device noninterleaved, full-range floating point buffers.
	int audioFormat = NATIVE_FLOAT_FMT | MUS_NON_INTERLEAVED;
	device->setFrameFormat(audioFormat, chans);

	int openMode = (record && play) ? AudioDevice::RecordPlayback
				   : (record) ? AudioDevice::Record
				   : AudioDevice::Playback;
	if (Option::checkPeaks())
		openMode |= AudioDevice::CheckPeaks;
	if (Option::reportClipping())
		openMode |= AudioDevice::ReportClipping;

	printf("DEBUG: audio device: peak check: %d report clip: %d\n",
		   !!(openMode & AudioDevice::CheckPeaks),
		   !!(openMode & AudioDevice::ReportClipping));

	if ((status = device->open(openMode, audioFormat, chans, srate)) == 0)
	{
		int reqsize = *buffersize;
		int reqcount = numBuffers;
		if ((status = device->setQueueSize(&reqsize, &reqcount)) < 0) {
			die("rtsetparams", "%s", device->getLastError());
			return -1;
		}
		int newSize = reqsize * numBuffers / reqcount;
		if (newSize != *buffersize) {
			advise("rtsetparams",
				   "RTBUFSAMPS reset by audio device from %d to %d.",
					*buffersize, newSize);
			*buffersize = newSize;
		}
	}
	else
	{
		die("rtsetparams", "%s", device->getLastError());
		return -1;
	}

	globalAudioDevice = device;

	return status;
}

int create_audio_file_device(const char *outfilename,
							 int header_type,
							 int sample_format,
							 int chans,
							 float srate,
							 int normalize_output_floats,
							 int check_peaks)
{
	assert(rtsetparams_was_called());

	AudioFileDevice *fileDevice = new AudioFileDevice(outfilename,
													  header_type);

	if (fileDevice == NULL) {
		rterror("rtoutput", "Failed to create audio file device");
		return -1;
	}

	// Here is the logic for opening the file device.  We do this all in
	// advance now, rather than over and over during rtwritesamps().

	const bool recording = Option::record();
	const bool playing = Option::play();
	const bool fileIsRawFloats = IS_FLOAT_FORMAT(sample_format) && !normalize_output_floats;

	int openMode = AudioFileDevice::Playback;
	if (playing | recording)
		openMode |= AudioDevice::Passive;		// Don't run thread for file device.
	if (!fileIsRawFloats || (check_peaks && !playing))
		openMode |= AudioDevice::CheckPeaks;	// Dont check peaks if HW already doing so.
	if (Option::reportClipping() && !playing)
		openMode |= AudioDevice::ReportClipping;	// Ditto for reporting of clipping

	printf("DEBUG: file device: peak check: %d report clip: %d\n",
		   openMode & AudioDevice::CheckPeaks, openMode & AudioDevice::ReportClipping);

	// We send the device noninterleaved, floating point buffers.  If we are playing
	// to HW at the same time, the data received by the file device will already be
	// clipped.

	int audioFormat = NATIVE_FLOAT_FMT | MUS_NON_INTERLEAVED;
	if (playing) audioFormat |= MUS_CLIPPED;

	fileDevice->setFrameFormat(audioFormat, chans);

	// File format is interleaved and may be normalized.
	sample_format |= MUS_INTERLEAVED;
	if (normalize_output_floats)
		sample_format |= MUS_NORMALIZED;
	int ret = fileDevice->open(openMode, sample_format, chans, srate);

	if (ret == -1) {
		rterror("rtoutput", "Can't create output for \"%s\": %s",
				 outfilename, fileDevice->getLastError());
		return -1;
	}
	// Cheating -- should hand in queue size as argument!
	int queueSize = RTcmix::bufsamps();
	int count = 1;
	ret = fileDevice->setQueueSize(&queueSize, &count);
	if (ret == -1) {
		rterror("rtoutput", "Failed to set queue size on file device:  %s",
				 fileDevice->getLastError());
		return -1;
	}

	if (!playing && !recording) {	// To file only.
		// If we are only writing to disk, we only have a single output device.
		globalAudioDevice = fileDevice;
	}
	else {							// To file, plus record and/or playback.
		if (playing && !recording) {		// Dual outputs to both HW and file.
			printf("DEBUG: Group output device for file and HW playback\n");
			bool fileDoesLimiting = !fileIsRawFloats;
			globalAudioDevice = new DualOutputAudioDevice(globalAudioDevice,
														  fileDevice,
														  fileDoesLimiting);
		}
		else if (recording && !playing) {	// Record from HW, write to file.
			assert(globalAudioDevice != NULL);
			printf("DEBUG: Dual device for HW record, file playback\n");
			globalAudioDevice = new AudioIODevice(globalAudioDevice, fileDevice, true);
		}
		else {	// HW Record and playback, plus write to file.
			printf("DEBUG: Dual device for HW record/playback, file playback\n");
			bool fileDoesLimiting = !fileIsRawFloats;
			globalAudioDevice = new DualOutputAudioDevice(globalAudioDevice,
														  fileDevice,
														  fileDoesLimiting);
		}
	}

	if (Option::print()) {
		 printf("Output file set for writing:\n");
		 printf("      name:  %s\n", outfilename);
		 printf("      type:  %s\n", mus_header_type_name(header_type));
		 printf("    format:  %s\n", mus_data_format_name(MUS_GET_FORMAT(sample_format)));
		 printf("     srate:  %g\n", srate);
		 printf("     chans:  %d\n", chans);
	}

	return 0;
}

int audio_input_is_initialized()
{
	return globalAudioDevice != NULL;
}

void
stop_audio_devices()
{
	// Turns out we need to close, not just stop (close calls stop)
	globalAudioDevice->close();
}

static bool destroying = false;	// avoid reentrancy

void
destroy_audio_devices()
{
	if (!destroying) {
		destroying = true;
		delete globalAudioDevice;
		globalAudioDevice = NULL;
	}
}

int
destroy_audio_file_device()
{
	int result = 0;

// 	if (globalOutputFileDevice != globalAudioDevice) {
//     	delete globalOutputFileDevice;
// 	}
// 	globalOutputFileDevice = NULL;

	return result;
}
<|endoftext|>


<commit_before>/* This file is part of Strigi Desktop Search
 *
 * Copyright (C) 2006 Jos van den Oever <jos@vandenoever.info>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
#include "streamindexer.h"
#include "fileinputstream.h"
#include "streamendanalyzer.h"
#include "streamthroughanalyzer.h"
#include "bz2endanalyzer.h"
#include "textendanalyzer.h"
#include "saxendanalyzer.h"
#include "tarendanalyzer.h"
#include "zipendanalyzer.h"
#include "pngendanalyzer.h"
#include "gzipendanalyzer.h"
#include "mailendanalyzer.h"
#include "digestthroughanalyzer.h"
#include "pluginthroughanalyzer.h"
#include "indexwriter.h"
#include <sstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
using namespace std;
using namespace jstreams;

StreamIndexer::StreamIndexer(IndexWriter* w) :writer(w) {
}
StreamIndexer::~StreamIndexer() {
    // delete the through analyzers and end analyzers
    std::vector<std::vector<StreamThroughAnalyzer*> >::iterator tIter;
    for (tIter = through.begin(); tIter != through.end(); ++tIter) {
        std::vector<StreamThroughAnalyzer*>::iterator t;
        for (t = tIter->begin(); t != tIter->end(); ++t) {
            delete *t;
        }
    }
    std::vector<std::vector<StreamEndAnalyzer*> >::iterator eIter;
    for (eIter = end.begin(); eIter != end.end(); ++eIter) {
        std::vector<StreamEndAnalyzer*>::iterator e;
        for (e = eIter->begin(); e != eIter->end(); ++e) {
            delete *e;
        }
    }
}
char
StreamIndexer::indexFile(const char *filepath) {
    std::string path(filepath);
    return indexFile(path);
}
char
StreamIndexer::indexFile(const std::string& filepath) {
    struct stat s;
    stat(filepath.c_str(), &s);
    FileInputStream file(filepath.c_str());
    // ensure a decent buffer size
    file.mark(65530);
    return analyze(filepath, s.st_mtime, &file, 0);
}
void
StreamIndexer::addThroughAnalyzers() {
    through.resize(through.size()+1);
    std::vector<std::vector<StreamThroughAnalyzer*> >::reverse_iterator tIter;
    tIter = through.rbegin();
    StreamThroughAnalyzer* ana = new DigestThroughAnalyzer();
    tIter->push_back(ana);
    PluginThroughAnalyzer::loadPlugins("/usr/local/lib");
    PluginThroughAnalyzer::loadPlugins("/usr/lib");
    PluginThroughAnalyzer::loadPlugins("/lib");
// two dirs that make development easier, harmless for releases
    PluginThroughAnalyzer::loadPlugins("/home/oever/testinstall/lib");
    PluginThroughAnalyzer::loadPlugins("/home/jos/testinstall/lib");
    PluginThroughAnalyzer *pta = new PluginThroughAnalyzer();
    ana = pta;
    tIter->push_back(ana);

}
void
StreamIndexer::addEndAnalyzers() {
    end.resize(end.size()+1);
    std::vector<std::vector<StreamEndAnalyzer*> >::reverse_iterator eIter;
    eIter = end.rbegin();
    StreamEndAnalyzer* ana = new BZ2EndAnalyzer();
    eIter->push_back(ana);
    ana = new GZipEndAnalyzer();
    eIter->push_back(ana);
    ana = new TarEndAnalyzer();
    eIter->push_back(ana);
    ana = new MailEndAnalyzer();
    eIter->push_back(ana);
    ana = new ZipEndAnalyzer();
    eIter->push_back(ana);
    ana = new PngEndAnalyzer();
    eIter->push_back(ana);
/*    ana = new PdfEndAnalyzer();
    eIter->push_back(ana);*/
    // add a sax analyzer before the text analyzer
    ana = new SaxEndAnalyzer();
    eIter->push_back(ana);
    // add a text analyzer to the end of the queue
    ana = new TextEndAnalyzer();
    eIter->push_back(ana);
}
char
StreamIndexer::analyze(const std::string &path, int64_t mtime,
        InputStream *input, uint depth) {
    static int count = 1;
    if (++count % 1000 == 0) {
        printf("file #%i: %s\n", count, path.c_str());
    }
    //printf("depth #%i: %s\n", depth, path.c_str());
    Indexable idx(path, mtime, writer, depth);

    // retrieve or construct the through analyzers and end analyzers
    std::vector<std::vector<StreamThroughAnalyzer*> >::iterator tIter;
    std::vector<std::vector<StreamEndAnalyzer*> >::iterator eIter;
    while (through.size() < depth+1) {
        addThroughAnalyzers();
        addEndAnalyzers();
    }
    tIter = through.begin() + depth;
    eIter = end.begin() + depth;

    // insert the through analyzers
    std::vector<StreamThroughAnalyzer*>::iterator ts;
    for (ts = tIter->begin(); ts != tIter->end(); ++ts) {
        (*ts)->setIndexable(&idx);
        input = (*ts)->connectInputStream(input);
    }
    bool finished = false;
    int32_t headersize = 1024;
    const char* header;
    headersize = input->read(header, headersize, 0);
    if (input->reset(0) != 0) {
        printf("resetting is impossible!! pos: %lli status: %i\n",
            input->getPosition(), input->getStatus());
    }
    if (headersize < 0) finished = true;
    int es = 0, size = eIter->size();
    while (!finished && es != size) {
        StreamEndAnalyzer* sea = (*eIter)[es];
        if (sea->checkHeader(header, headersize)) {
            char ar = sea->analyze(path, input, depth+1, this, &idx);
            if (ar) {
                int64_t pos = input->reset(0);
                if (pos != 0) { // could not reset
                    printf("could not reset stream of %s from pos %lli to 0 "
                        "after reading with %s: %s\n", path.c_str(),
                        input->getPosition(), sea->getName(),
                        sea->getError().c_str());
                    removeIndexable(depth);
                    return -2;
                }
            } else {
                finished = true;
            }
            eIter = end.begin() + depth;
        }
        es++;
    }
    // make sure the entire stream as read
    int64_t nskipped;
    do {
        nskipped = input->skip(1000000);
    } while (input->getStatus() == Ok);
    if (input->getStatus() == Error) {
        printf("Error: %s\n", input->getError());
        removeIndexable(depth);
        return -2;
    }

    // store the size of the stream
    ostringstream sizestr;
    sizestr << input->getSize();
    idx.setField("size", sizestr.str());

    // remove references to the indexable before it goes out of scope
    removeIndexable(depth);
    return 0;
}
void
StreamIndexer::removeIndexable(uint depth) {
    std::vector<std::vector<StreamThroughAnalyzer*> >::iterator tIter;
    std::vector<StreamThroughAnalyzer*>::iterator ts;
    tIter = through.begin() + depth;
    for (ts = tIter->begin(); ts != tIter->end(); ++ts) {
        // remove references to the indexable before it goes out of scope
        (*ts)->setIndexable(0);
    }
}
<commit_msg>msvc compatibility. removed unnecessary includes<commit_after>/* This file is part of Strigi Desktop Search
 *
 * Copyright (C) 2006 Jos van den Oever <jos@vandenoever.info>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
#include "jstreamsconfig.h"
#include "streamindexer.h"
#include "fileinputstream.h"
#include "streamendanalyzer.h"
#include "streamthroughanalyzer.h"
#include "bz2endanalyzer.h"
#include "textendanalyzer.h"
#include "saxendanalyzer.h"
#include "tarendanalyzer.h"
#include "zipendanalyzer.h"
#include "pngendanalyzer.h"
#include "gzipendanalyzer.h"
#include "mailendanalyzer.h"
#include "digestthroughanalyzer.h"
#include "pluginthroughanalyzer.h"
#include "indexwriter.h"
#include <sys/stat.h>

using namespace std;
using namespace jstreams;

StreamIndexer::StreamIndexer(IndexWriter* w) :writer(w) {
}
StreamIndexer::~StreamIndexer() {
    // delete the through analyzers and end analyzers
    std::vector<std::vector<StreamThroughAnalyzer*> >::iterator tIter;
    for (tIter = through.begin(); tIter != through.end(); ++tIter) {
        std::vector<StreamThroughAnalyzer*>::iterator t;
        for (t = tIter->begin(); t != tIter->end(); ++t) {
            delete *t;
        }
    }
    std::vector<std::vector<StreamEndAnalyzer*> >::iterator eIter;
    for (eIter = end.begin(); eIter != end.end(); ++eIter) {
        std::vector<StreamEndAnalyzer*>::iterator e;
        for (e = eIter->begin(); e != eIter->end(); ++e) {
            delete *e;
        }
    }
}
char
StreamIndexer::indexFile(const char *filepath) {
    std::string path(filepath);
    return indexFile(path);
}
char
StreamIndexer::indexFile(const std::string& filepath) {
    struct stat s;
    stat(filepath.c_str(), &s);
    FileInputStream file(filepath.c_str());
    // ensure a decent buffer size
    file.mark(65530);
    return analyze(filepath, s.st_mtime, &file, 0);
}
void
StreamIndexer::addThroughAnalyzers() {
    through.resize(through.size()+1);
    std::vector<std::vector<StreamThroughAnalyzer*> >::reverse_iterator tIter;
    tIter = through.rbegin();
    StreamThroughAnalyzer* ana = new DigestThroughAnalyzer();
    tIter->push_back(ana);
    PluginThroughAnalyzer::loadPlugins("/usr/local/lib");
    PluginThroughAnalyzer::loadPlugins("/usr/lib");
    PluginThroughAnalyzer::loadPlugins("/lib");
// two dirs that make development easier, harmless for releases
    PluginThroughAnalyzer::loadPlugins("/home/oever/testinstall/lib");
    PluginThroughAnalyzer::loadPlugins("/home/jos/testinstall/lib");
    PluginThroughAnalyzer *pta = new PluginThroughAnalyzer();
    ana = pta;
    tIter->push_back(ana);

}
void
StreamIndexer::addEndAnalyzers() {
    end.resize(end.size()+1);
    std::vector<std::vector<StreamEndAnalyzer*> >::reverse_iterator eIter;
    eIter = end.rbegin();
    StreamEndAnalyzer* ana = new BZ2EndAnalyzer();
    eIter->push_back(ana);
    ana = new GZipEndAnalyzer();
    eIter->push_back(ana);
    ana = new TarEndAnalyzer();
    eIter->push_back(ana);
    ana = new MailEndAnalyzer();
    eIter->push_back(ana);
    ana = new ZipEndAnalyzer();
    eIter->push_back(ana);
    ana = new PngEndAnalyzer();
    eIter->push_back(ana);
/*    ana = new PdfEndAnalyzer();
    eIter->push_back(ana);*/
    // add a sax analyzer before the text analyzer
    ana = new SaxEndAnalyzer();
    eIter->push_back(ana);
    // add a text analyzer to the end of the queue
    ana = new TextEndAnalyzer();
    eIter->push_back(ana);
}
char
StreamIndexer::analyze(const std::string &path, int64_t mtime,
        InputStream *input, uint depth) {
    static int count = 1;
    if (++count % 1000 == 0) {
        printf("file #%i: %s\n", count, path.c_str());
    }
    //printf("depth #%i: %s\n", depth, path.c_str());
    Indexable idx(path, mtime, writer, depth);

    // retrieve or construct the through analyzers and end analyzers
    std::vector<std::vector<StreamThroughAnalyzer*> >::iterator tIter;
    std::vector<std::vector<StreamEndAnalyzer*> >::iterator eIter;
    while (through.size() < depth+1) {
        addThroughAnalyzers();
        addEndAnalyzers();
    }
    tIter = through.begin() + depth;
    eIter = end.begin() + depth;

    // insert the through analyzers
    std::vector<StreamThroughAnalyzer*>::iterator ts;
    for (ts = tIter->begin(); ts != tIter->end(); ++ts) {
        (*ts)->setIndexable(&idx);
        input = (*ts)->connectInputStream(input);
    }
    bool finished = false;
    int32_t headersize = 1024;
    const char* header;
    headersize = input->read(header, headersize, 0);
    if (input->reset(0) != 0) {
        printf("resetting is impossible!! pos: %lli status: %i\n",
            input->getPosition(), input->getStatus());
    }
    if (headersize < 0) finished = true;
    int es = 0, size = eIter->size();
    while (!finished && es != size) {
        StreamEndAnalyzer* sea = (*eIter)[es];
        if (sea->checkHeader(header, headersize)) {
            char ar = sea->analyze(path, input, depth+1, this, &idx);
            if (ar) {
                int64_t pos = input->reset(0);
                if (pos != 0) { // could not reset
                    printf("could not reset stream of %s from pos %lli to 0 "
                        "after reading with %s: %s\n", path.c_str(),
                        input->getPosition(), sea->getName(),
                        sea->getError().c_str());
                    removeIndexable(depth);
                    return -2;
                }
            } else {
                finished = true;
            }
            eIter = end.begin() + depth;
        }
        es++;
    }
    // make sure the entire stream as read
    int64_t nskipped;
    do {
        nskipped = input->skip(1000000);
    } while (input->getStatus() == Ok);
    if (input->getStatus() == Error) {
        printf("Error: %s\n", input->getError());
        removeIndexable(depth);
        return -2;
    }

    // store the size of the stream
    {
		//tmp scope out tmp mem
		char tmp[100];
		sprintf(tmp, "%d", input->getSize());
		idx.setField("size", tmp);
	}

    // remove references to the indexable before it goes out of scope
    removeIndexable(depth);
    return 0;
}
void
StreamIndexer::removeIndexable(uint depth) {
    std::vector<std::vector<StreamThroughAnalyzer*> >::iterator tIter;
    std::vector<StreamThroughAnalyzer*>::iterator ts;
    tIter = through.begin() + depth;
    for (ts = tIter->begin(); ts != tIter->end(); ++ts) {
        // remove references to the indexable before it goes out of scope
        (*ts)->setIndexable(0);
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2015-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <bench/bench.h>

#include <crypto/sha256.h>
#include <util/strencodings.h>
#include <util/system.h>

#include <memory>

static const char* DEFAULT_BENCH_FILTER = ".*";

static void SetupBenchArgs(ArgsManager& argsman)
{
    SetupHelpOptions(argsman);

    argsman.AddArg("-list", "List benchmarks without executing them", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
    argsman.AddArg("-filter=<regex>", strprintf("Regular expression filter to select benchmark by name (default: %s)", DEFAULT_BENCH_FILTER), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
    argsman.AddArg("-asymptote=n1,n2,n3,...", strprintf("Test asymptotic growth of the runtime of an algorithm, if supported by the benchmark"), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
    argsman.AddArg("-output_csv=<output.csv>", "Generate CSV file with the most important benchmark results.", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
    argsman.AddArg("-output_json=<output.json>", "Generate JSON file with all benchmark results.", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
}

// parses a comma separated list like "10,20,30,50"
static std::vector<double> parseAsymptote(const std::string& str) {
    std::stringstream ss(str);
    std::vector<double> numbers;
    double d;
    char c;
    while (ss >> d) {
        numbers.push_back(d);
        ss >> c;
    }
    return numbers;
}

int main(int argc, char** argv)
{
    ArgsManager argsman;
    SetupBenchArgs(argsman);
    SHA256AutoDetect();
    std::string error;
    if (!argsman.ParseParameters(argc, argv, error)) {
        tfm::format(std::cerr, "Error parsing command line arguments: %s\n", error);
        return EXIT_FAILURE;
    }

    if (HelpRequested(argsman)) {
        std::cout << argsman.GetHelpMessage();

        return EXIT_SUCCESS;
    }

    benchmark::Args args;
    args.regex_filter = argsman.GetArg("-filter", DEFAULT_BENCH_FILTER);
    args.is_list_only = argsman.GetBoolArg("-list", false);
    args.asymptote = parseAsymptote(argsman.GetArg("-asymptote", ""));
    args.output_csv = argsman.GetArg("-output_csv", "");
    args.output_json = argsman.GetArg("-output_json", "");

    benchmark::BenchRunner::RunAll(args);

    return EXIT_SUCCESS;
}
<commit_msg>bench: bench_bitcoin.cpp help fixups<commit_after>// Copyright (c) 2015-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <bench/bench.h>

#include <crypto/sha256.h>
#include <util/strencodings.h>
#include <util/system.h>

#include <memory>

static const char* DEFAULT_BENCH_FILTER = ".*";

static void SetupBenchArgs(ArgsManager& argsman)
{
    SetupHelpOptions(argsman);

    argsman.AddArg("-asymptote=n1,n2,n3,...", "Test asymptotic growth of the runtime of an algorithm, if supported by the benchmark", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
    argsman.AddArg("-filter=<regex>", strprintf("Regular expression filter to select benchmark by name (default: %s)", DEFAULT_BENCH_FILTER), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
    argsman.AddArg("-list", "List benchmarks without executing them", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
    argsman.AddArg("-output_csv=<output.csv>", "Generate CSV file with the most important benchmark results", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
    argsman.AddArg("-output_json=<output.json>", "Generate JSON file with all benchmark results", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
}

// parses a comma separated list like "10,20,30,50"
static std::vector<double> parseAsymptote(const std::string& str) {
    std::stringstream ss(str);
    std::vector<double> numbers;
    double d;
    char c;
    while (ss >> d) {
        numbers.push_back(d);
        ss >> c;
    }
    return numbers;
}

int main(int argc, char** argv)
{
    ArgsManager argsman;
    SetupBenchArgs(argsman);
    SHA256AutoDetect();
    std::string error;
    if (!argsman.ParseParameters(argc, argv, error)) {
        tfm::format(std::cerr, "Error parsing command line arguments: %s\n", error);
        return EXIT_FAILURE;
    }

    if (HelpRequested(argsman)) {
        std::cout << argsman.GetHelpMessage();

        return EXIT_SUCCESS;
    }

    benchmark::Args args;
    args.regex_filter = argsman.GetArg("-filter", DEFAULT_BENCH_FILTER);
    args.is_list_only = argsman.GetBoolArg("-list", false);
    args.asymptote = parseAsymptote(argsman.GetArg("-asymptote", ""));
    args.output_csv = argsman.GetArg("-output_csv", "");
    args.output_json = argsman.GetArg("-output_json", "");

    benchmark::BenchRunner::RunAll(args);

    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>#include "buffer_cache/alt/alt.hpp"

#include "arch/runtime/coroutines.hpp"
#include "concurrency/auto_drainer.hpp"

// RSI: get rid of this.
#define ALT_DEBUG 0

namespace alt {

alt_cache_t::alt_cache_t(serializer_t *serializer)
    : tracker_(),
      page_cache_(serializer, &tracker_),
      drainer_(make_scoped<auto_drainer_t>()) { }

alt_cache_t::~alt_cache_t() {
    drainer_.reset();
}

block_size_t alt_cache_t::max_block_size() const {
    return page_cache_.max_block_size();
}

alt_inner_txn_t::alt_inner_txn_t(alt_cache_t *cache, alt_inner_txn_t *preceding_txn)
    : cache_(cache),
      page_txn_(&cache->page_cache_,
                preceding_txn == NULL ? NULL : &preceding_txn->page_txn_),
      this_txn_timestamp_(repli_timestamp_t::invalid) {
    // RSI: Use this_txn_timestamp_ for something.
    (void)this_txn_timestamp_;
}

alt_inner_txn_t::~alt_inner_txn_t() {
    // RSI: Do anything?
}

alt_txn_t::alt_txn_t(alt_cache_t *cache,
                     alt_txn_t *preceding_txn)
    : durability_(write_durability_t::HARD) {
    inner_.init(new alt_inner_txn_t(cache,
                                    preceding_txn == NULL ? NULL
                                    : preceding_txn->inner_.get()));
}

alt_txn_t::alt_txn_t(alt_cache_t *cache,
                     write_durability_t durability,
                     alt_txn_t *preceding_txn)
    : durability_(durability) {
    inner_.init(new alt_inner_txn_t(cache,
                                    preceding_txn == NULL ? NULL
                                    : preceding_txn->inner_.get()));
}

void destroy_inner_txn(alt_inner_txn_t *inner, auto_drainer_t::lock_t) {
    delete inner;
}

alt_txn_t::~alt_txn_t() {
    if (durability_ == write_durability_t::SOFT) {
        alt_inner_txn_t *inner = inner_.release();
        coro_t::spawn_sometime(std::bind(&destroy_inner_txn,
                                         inner,
                                         inner->cache()->drainer_->lock()));
    }
}

alt_buf_lock_t::alt_buf_lock_t()
    : txn_(NULL),
      current_page_acq_(),
      snapshot_node_(NULL),
      access_ref_count_(0) {
}

#if ALT_DEBUG
const char *show(alt_access_t access) {
    return access == alt_access_t::read ? "read" : "write";
}
#endif

alt_buf_lock_t::alt_buf_lock_t(alt_buf_parent_t parent,
                               block_id_t block_id,
                               alt_access_t access)
    : txn_(parent.txn()),
      current_page_acq_(),
      snapshot_node_(NULL),
      access_ref_count_(0) {
    alt_buf_lock_t::wait_for_parent(parent, access);
    current_page_acq_.init(new current_page_acq_t(txn_->page_txn(), block_id, access));
#if ALT_DEBUG
    debugf("%p: alt_buf_lock_t %p %s %lu\n", cache(), this, show(access), block_id);
#endif
}

alt_buf_lock_t::alt_buf_lock_t(alt_txn_t *txn,
                               block_id_t block_id,
                               alt_create_t create)
    : txn_(txn),
      current_page_acq_(new current_page_acq_t(txn->page_txn(), block_id,
                                               alt_access_t::write, true)),
      snapshot_node_(NULL),
      access_ref_count_(0) {
    guarantee(create == alt_create_t::create);
#if ALT_DEBUG
    debugf("%p: alt_buf_lock_t %p create %lu\n", cache(), this, block_id);
#endif
}

bool is_subordinate(alt_access_t parent, alt_access_t child) {
    return parent == alt_access_t::write || child == alt_access_t::read;
}

void alt_buf_lock_t::wait_for_parent(alt_buf_parent_t parent, alt_access_t access) {
    if (parent.lock_or_null_ != NULL) {
        alt_buf_lock_t *lock = parent.lock_or_null_;
        guarantee(is_subordinate(lock->access(), access));
        if (access == alt_access_t::write) {
            lock->write_acq_signal()->wait();
        } else {
            lock->read_acq_signal()->wait();
        }
    }
}

alt_buf_lock_t::alt_buf_lock_t(alt_buf_lock_t *parent,
                               block_id_t block_id,
                               alt_access_t access)
    : txn_(parent->txn_),
      current_page_acq_(),
      snapshot_node_(NULL),
      access_ref_count_(0) {

    alt_buf_lock_t::wait_for_parent(alt_buf_parent_t(parent), access);

    current_page_acq_.init(new current_page_acq_t(txn_->page_txn(), block_id, access));
#if ALT_DEBUG
    debugf("%p: alt_buf_lock_t %p %s %lu\n", cache(), this, show(access), block_id);
#endif
}

alt_buf_lock_t::alt_buf_lock_t(alt_buf_parent_t parent,
                               alt_create_t create)
    : txn_(parent.txn()),
      current_page_acq_(),
      snapshot_node_(NULL),
      access_ref_count_(0) {
    guarantee(create == alt_create_t::create);
    wait_for_parent(parent, alt_access_t::write);
    current_page_acq_.init(new current_page_acq_t(txn_->page_txn(),
                                                  alt_access_t::write));
#if ALT_DEBUG
    debugf("%p: alt_buf_lock_t %p create %lu\n", cache(), this, block_id());
#endif
}

alt_buf_lock_t::alt_buf_lock_t(alt_buf_lock_t *parent,
                               alt_create_t create)
    : txn_(parent->txn_),
      current_page_acq_(),
      snapshot_node_(NULL),
      access_ref_count_(0) {
    guarantee(create == alt_create_t::create);
    wait_for_parent(alt_buf_parent_t(parent), alt_access_t::write);

    current_page_acq_.init(new current_page_acq_t(txn_->page_txn(),
                                                  alt_access_t::write));
#if ALT_DEBUG
    debugf("%p: alt_buf_lock_t %p create %lu\n", cache(), this, block_id());
#endif
}

alt_buf_lock_t::~alt_buf_lock_t() {
#if ALT_DEBUG
    if (txn_ != NULL) {
        debugf("%p: alt_buf_lock_t %p destroy %lu\n", cache(), this, block_id());
    }
#endif
    // RSI: We'll have to do something with snapshot_node_ here.
    (void)snapshot_node_;
    guarantee(access_ref_count_ == 0);
}

alt_buf_lock_t::alt_buf_lock_t(alt_buf_lock_t &&movee)
    : txn_(movee.txn_),
      current_page_acq_(std::move(movee.current_page_acq_)),
      snapshot_node_(movee.snapshot_node_),
      access_ref_count_(0)
{
    guarantee(movee.access_ref_count_ == 0);
    movee.txn_ = NULL;
    movee.current_page_acq_.reset();
    movee.snapshot_node_ = NULL;
}

alt_buf_lock_t &alt_buf_lock_t::operator=(alt_buf_lock_t &&movee) {
    guarantee(access_ref_count_ == 0);
    alt_buf_lock_t tmp(std::move(movee));
    swap(tmp);
    return *this;
}

void alt_buf_lock_t::swap(alt_buf_lock_t &other) {
    guarantee(access_ref_count_ == 0);
    guarantee(other.access_ref_count_ == 0);
    std::swap(txn_, other.txn_);
    current_page_acq_.swap(other.current_page_acq_);
    std::swap(snapshot_node_, other.snapshot_node_);
}

void alt_buf_lock_t::reset_buf_lock() {
    alt_buf_lock_t tmp;
    swap(tmp);
}

void alt_buf_lock_t::snapshot_subtree() {
    guarantee(!empty());
    // RSI: Actually implement this.
}

void alt_buf_lock_t::detach_child(block_id_t child_id) {
    (void)child_id;
    guarantee(!empty());
    // RSI: Actually implement this.
}

void alt_buf_lock_t::reduce_to_readonly() {
    guarantee(!empty());
    // RSI: Actually implement this.
}

void alt_buf_lock_t::reduce_to_nothing() {
    guarantee(!empty());
    // RSI: Actually implement this.
}

repli_timestamp_t alt_buf_lock_t::get_recency() const {
    guarantee(!empty());
    return current_page_acq_->recency();
}

alt_buf_read_t::alt_buf_read_t(alt_buf_lock_t *lock)
    : lock_(lock) {
    guarantee(!lock_->empty());
    lock_->access_ref_count_++;
}

alt_buf_read_t::~alt_buf_read_t() {
    guarantee(!lock_->empty());
    lock_->access_ref_count_--;
}

const void *alt_buf_read_t::get_data_read(uint32_t *block_size_out) {
    guarantee(!lock_->empty());
    lock_->current_page_acq_->read_acq_signal()->wait();
    page_t *page = lock_->current_page_acq_->current_page_for_read();
    guarantee(!lock_->empty());
    if (!page_acq_.has()) {
        page_acq_.init(page, &lock_->cache()->page_cache_);
    }
    page_acq_.buf_ready_signal()->wait();
    *block_size_out = page_acq_.get_buf_size();
    return page_acq_.get_buf_read();
}

alt_buf_write_t::alt_buf_write_t(alt_buf_lock_t *lock)
    : lock_(lock) {
    guarantee(!lock_->empty());
    lock_->access_ref_count_++;
    lock_->access_ref_count_--;
}

alt_buf_write_t::~alt_buf_write_t() {
    guarantee(!lock_->empty());
}

void *alt_buf_write_t::get_data_write(uint32_t block_size) {
    guarantee(!lock_->empty());
    // RSI: Use block_size somehow.
    (void)block_size;
    lock_->current_page_acq_->write_acq_signal()->wait();
    guarantee(!lock_->empty());
    page_t *page = lock_->current_page_acq_->current_page_for_write();
    if (!page_acq_.has()) {
        page_acq_.init(page, &lock_->cache()->page_cache_);
    }
    page_acq_.buf_ready_signal()->wait();
    return page_acq_.get_buf_write();
}

void *alt_buf_write_t::get_data_write() {
    return get_data_write(lock_->cache()->max_block_size().value());
}

}  // namespace alt
<commit_msg>Moved access_ref_count_ decrement to alt_buf_write_t destructor.<commit_after>#include "buffer_cache/alt/alt.hpp"

#include "arch/runtime/coroutines.hpp"
#include "concurrency/auto_drainer.hpp"

// RSI: get rid of this.
#define ALT_DEBUG 0

namespace alt {

alt_cache_t::alt_cache_t(serializer_t *serializer)
    : tracker_(),
      page_cache_(serializer, &tracker_),
      drainer_(make_scoped<auto_drainer_t>()) { }

alt_cache_t::~alt_cache_t() {
    drainer_.reset();
}

block_size_t alt_cache_t::max_block_size() const {
    return page_cache_.max_block_size();
}

alt_inner_txn_t::alt_inner_txn_t(alt_cache_t *cache, alt_inner_txn_t *preceding_txn)
    : cache_(cache),
      page_txn_(&cache->page_cache_,
                preceding_txn == NULL ? NULL : &preceding_txn->page_txn_),
      this_txn_timestamp_(repli_timestamp_t::invalid) {
    // RSI: Use this_txn_timestamp_ for something.
    (void)this_txn_timestamp_;
}

alt_inner_txn_t::~alt_inner_txn_t() {
    // RSI: Do anything?
}

alt_txn_t::alt_txn_t(alt_cache_t *cache,
                     alt_txn_t *preceding_txn)
    : durability_(write_durability_t::HARD) {
    inner_.init(new alt_inner_txn_t(cache,
                                    preceding_txn == NULL ? NULL
                                    : preceding_txn->inner_.get()));
}

alt_txn_t::alt_txn_t(alt_cache_t *cache,
                     write_durability_t durability,
                     alt_txn_t *preceding_txn)
    : durability_(durability) {
    inner_.init(new alt_inner_txn_t(cache,
                                    preceding_txn == NULL ? NULL
                                    : preceding_txn->inner_.get()));
}

void destroy_inner_txn(alt_inner_txn_t *inner, auto_drainer_t::lock_t) {
    delete inner;
}

alt_txn_t::~alt_txn_t() {
    if (durability_ == write_durability_t::SOFT) {
        alt_inner_txn_t *inner = inner_.release();
        coro_t::spawn_sometime(std::bind(&destroy_inner_txn,
                                         inner,
                                         inner->cache()->drainer_->lock()));
    }
}

alt_buf_lock_t::alt_buf_lock_t()
    : txn_(NULL),
      current_page_acq_(),
      snapshot_node_(NULL),
      access_ref_count_(0) {
}

#if ALT_DEBUG
const char *show(alt_access_t access) {
    return access == alt_access_t::read ? "read" : "write";
}
#endif

alt_buf_lock_t::alt_buf_lock_t(alt_buf_parent_t parent,
                               block_id_t block_id,
                               alt_access_t access)
    : txn_(parent.txn()),
      current_page_acq_(),
      snapshot_node_(NULL),
      access_ref_count_(0) {
    alt_buf_lock_t::wait_for_parent(parent, access);
    current_page_acq_.init(new current_page_acq_t(txn_->page_txn(), block_id, access));
#if ALT_DEBUG
    debugf("%p: alt_buf_lock_t %p %s %lu\n", cache(), this, show(access), block_id);
#endif
}

alt_buf_lock_t::alt_buf_lock_t(alt_txn_t *txn,
                               block_id_t block_id,
                               alt_create_t create)
    : txn_(txn),
      current_page_acq_(new current_page_acq_t(txn->page_txn(), block_id,
                                               alt_access_t::write, true)),
      snapshot_node_(NULL),
      access_ref_count_(0) {
    guarantee(create == alt_create_t::create);
#if ALT_DEBUG
    debugf("%p: alt_buf_lock_t %p create %lu\n", cache(), this, block_id);
#endif
}

bool is_subordinate(alt_access_t parent, alt_access_t child) {
    return parent == alt_access_t::write || child == alt_access_t::read;
}

void alt_buf_lock_t::wait_for_parent(alt_buf_parent_t parent, alt_access_t access) {
    if (parent.lock_or_null_ != NULL) {
        alt_buf_lock_t *lock = parent.lock_or_null_;
        guarantee(is_subordinate(lock->access(), access));
        if (access == alt_access_t::write) {
            lock->write_acq_signal()->wait();
        } else {
            lock->read_acq_signal()->wait();
        }
    }
}

alt_buf_lock_t::alt_buf_lock_t(alt_buf_lock_t *parent,
                               block_id_t block_id,
                               alt_access_t access)
    : txn_(parent->txn_),
      current_page_acq_(),
      snapshot_node_(NULL),
      access_ref_count_(0) {

    alt_buf_lock_t::wait_for_parent(alt_buf_parent_t(parent), access);

    current_page_acq_.init(new current_page_acq_t(txn_->page_txn(), block_id, access));
#if ALT_DEBUG
    debugf("%p: alt_buf_lock_t %p %s %lu\n", cache(), this, show(access), block_id);
#endif
}

alt_buf_lock_t::alt_buf_lock_t(alt_buf_parent_t parent,
                               alt_create_t create)
    : txn_(parent.txn()),
      current_page_acq_(),
      snapshot_node_(NULL),
      access_ref_count_(0) {
    guarantee(create == alt_create_t::create);
    wait_for_parent(parent, alt_access_t::write);
    current_page_acq_.init(new current_page_acq_t(txn_->page_txn(),
                                                  alt_access_t::write));
#if ALT_DEBUG
    debugf("%p: alt_buf_lock_t %p create %lu\n", cache(), this, block_id());
#endif
}

alt_buf_lock_t::alt_buf_lock_t(alt_buf_lock_t *parent,
                               alt_create_t create)
    : txn_(parent->txn_),
      current_page_acq_(),
      snapshot_node_(NULL),
      access_ref_count_(0) {
    guarantee(create == alt_create_t::create);
    wait_for_parent(alt_buf_parent_t(parent), alt_access_t::write);

    current_page_acq_.init(new current_page_acq_t(txn_->page_txn(),
                                                  alt_access_t::write));
#if ALT_DEBUG
    debugf("%p: alt_buf_lock_t %p create %lu\n", cache(), this, block_id());
#endif
}

alt_buf_lock_t::~alt_buf_lock_t() {
#if ALT_DEBUG
    if (txn_ != NULL) {
        debugf("%p: alt_buf_lock_t %p destroy %lu\n", cache(), this, block_id());
    }
#endif
    // RSI: We'll have to do something with snapshot_node_ here.
    (void)snapshot_node_;
    guarantee(access_ref_count_ == 0);
}

alt_buf_lock_t::alt_buf_lock_t(alt_buf_lock_t &&movee)
    : txn_(movee.txn_),
      current_page_acq_(std::move(movee.current_page_acq_)),
      snapshot_node_(movee.snapshot_node_),
      access_ref_count_(0)
{
    guarantee(movee.access_ref_count_ == 0);
    movee.txn_ = NULL;
    movee.current_page_acq_.reset();
    movee.snapshot_node_ = NULL;
}

alt_buf_lock_t &alt_buf_lock_t::operator=(alt_buf_lock_t &&movee) {
    guarantee(access_ref_count_ == 0);
    alt_buf_lock_t tmp(std::move(movee));
    swap(tmp);
    return *this;
}

void alt_buf_lock_t::swap(alt_buf_lock_t &other) {
    guarantee(access_ref_count_ == 0);
    guarantee(other.access_ref_count_ == 0);
    std::swap(txn_, other.txn_);
    current_page_acq_.swap(other.current_page_acq_);
    std::swap(snapshot_node_, other.snapshot_node_);
}

void alt_buf_lock_t::reset_buf_lock() {
    alt_buf_lock_t tmp;
    swap(tmp);
}

void alt_buf_lock_t::snapshot_subtree() {
    guarantee(!empty());
    // RSI: Actually implement this.
}

void alt_buf_lock_t::detach_child(block_id_t child_id) {
    (void)child_id;
    guarantee(!empty());
    // RSI: Actually implement this.
}

void alt_buf_lock_t::reduce_to_readonly() {
    guarantee(!empty());
    // RSI: Actually implement this.
}

void alt_buf_lock_t::reduce_to_nothing() {
    guarantee(!empty());
    // RSI: Actually implement this.
}

repli_timestamp_t alt_buf_lock_t::get_recency() const {
    guarantee(!empty());
    return current_page_acq_->recency();
}

alt_buf_read_t::alt_buf_read_t(alt_buf_lock_t *lock)
    : lock_(lock) {
    guarantee(!lock_->empty());
    lock_->access_ref_count_++;
}

alt_buf_read_t::~alt_buf_read_t() {
    guarantee(!lock_->empty());
    lock_->access_ref_count_--;
}

const void *alt_buf_read_t::get_data_read(uint32_t *block_size_out) {
    guarantee(!lock_->empty());
    lock_->current_page_acq_->read_acq_signal()->wait();
    page_t *page = lock_->current_page_acq_->current_page_for_read();
    guarantee(!lock_->empty());
    if (!page_acq_.has()) {
        page_acq_.init(page, &lock_->cache()->page_cache_);
    }
    page_acq_.buf_ready_signal()->wait();
    *block_size_out = page_acq_.get_buf_size();
    return page_acq_.get_buf_read();
}

alt_buf_write_t::alt_buf_write_t(alt_buf_lock_t *lock)
    : lock_(lock) {
    guarantee(!lock_->empty());
    lock_->access_ref_count_++;
}

alt_buf_write_t::~alt_buf_write_t() {
    guarantee(!lock_->empty());
    lock_->access_ref_count_--;
}

void *alt_buf_write_t::get_data_write(uint32_t block_size) {
    guarantee(!lock_->empty());
    // RSI: Use block_size somehow.
    (void)block_size;
    lock_->current_page_acq_->write_acq_signal()->wait();
    guarantee(!lock_->empty());
    page_t *page = lock_->current_page_acq_->current_page_for_write();
    if (!page_acq_.has()) {
        page_acq_.init(page, &lock_->cache()->page_cache_);
    }
    page_acq_.buf_ready_signal()->wait();
    return page_acq_.get_buf_write();
}

void *alt_buf_write_t::get_data_write() {
    return get_data_write(lock_->cache()->max_block_size().value());
}

}  // namespace alt
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named LICENSE that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "Authentication.h"

// because kebos dosn't asume anyone else but them has defines.
#ifdef MAXHOSTNAMELEN
#undef MAXHOSTNAMELEN
#endif

/* system implementation headers */
#ifdef HAVE_KRB5
#include <com_err.h>
#endif
#include <sys/types.h>
#ifndef _WIN32
#include <unistd.h>
#endif
#include <string>
#include <assert.h>

#ifdef HAVE_KRB5
krb5_context   Authentication::context        = NULL;
krb5_ccache    Authentication::cc             = NULL;
krb5_principal Authentication::client;
krb5_creds     Authentication::my_creds;
#endif
bool           Authentication::authentication = false;

Authentication::Authentication() : trusted(false)
{
}

#ifdef HAVE_KRB5
void Authentication::init(const char *address, int port, const char *password)
{
  assert(context == NULL);
  assert(cc == NULL);

  krb5_error_code retval;
  char            ccfile[MAXPATHLEN+6]; // FILE:path+\0

  if (!address)
    return;

  int i;
  char serverName[128];
  strncpy(serverName, address, 128);
  for (i = 0; i < 127 && serverName[i] != 0 && serverName[i] != ':'; i++);

  // With no public address we cannot do auth
  if (!i)
    return;
  serverName[i] = 0;

  // Initializing kerberos library
  if ((retval = krb5_init_context(&context)))
    com_err("bzfs:", retval, "while initializing krb5");

  // Gettin a default cache different for any bzfs process
  sprintf(ccfile, "FILE:/tmp/krb5cc_p%ld", (long)getpid());
  if (context && (retval = krb5_cc_set_default_name(context, ccfile)))
    com_err("bzfs:", retval, "setting default cache");
  unlink(ccfile+strlen("FILE:"));

  // Getting credential cache
  if (!retval && (retval = krb5_cc_default(context, &cc)))
    com_err("bzfs:", retval, "getting credentials cache");

  // Getting principal identifier
  char serverPort[8];
  snprintf(serverPort, sizeof(serverPort), "%d", port);
  if (cc && (retval = krb5_sname_to_principal(context, serverName, serverPort,
					      KRB5_NT_SRV_HST, &client)))
    com_err("bzfs:", retval, "getting principal name");

  // Initing credential cache
  if (!retval && (retval = krb5_cc_initialize(context, cc, client)))
    com_err("bzfs:", retval, "initializing credential cache");

  char intPassword[128];
  strncpy(intPassword, password, 128);
  intPassword[127] = 0;
  // Get credentials for server
  if (!retval && (retval = krb5_get_init_creds_password(context, &my_creds,
 							client, intPassword,
 							krb5_prompter_posix,
 							NULL, 0, NULL, NULL)))
    com_err("bzfs:", retval, "getting credential");

  // Store credentials in cache
  if (!retval && (retval = krb5_cc_store_cred(context, cc, &my_creds)))
    com_err("bzfs:", retval, "storing credential in cache");

  if (!retval)
    authentication = true;
}
#else
void Authentication::init(const char *, int , const char *)
{
}
#endif

#ifdef HAVE_KRB5
void Authentication::setPrincipalName(char *buf, int len)
{
  if (!authentication)
    return;

  krb5_error_code retval;
  char            remotePrincipal[1024];

  memcpy(remotePrincipal, buf, len);
  remotePrincipal[len] = 0;

  if ((retval = krb5_parse_name(context, remotePrincipal, &server)))
    com_err("bzfs", retval, "parsing remote name");
}
#else
void Authentication::setPrincipalName(char *, int)
{
}
#endif

#ifdef HAVE_KRB5
void Authentication::verifyCredential(char *buf, int len)
{
  if (!authentication)
    return;

  krb5_creds        creds;
  krb5_error_code   retval;
  krb5_creds       *new_creds;

  memset((char*)&creds, 0, sizeof(creds));
  memcpy(&creds.client, &client, sizeof(client));
  memcpy(&creds.server, &server, sizeof(server));

  creds.second_ticket.length = len;
  creds.second_ticket.data   = buf;

  // Check authentication info
  if ((retval = krb5_get_credentials(context, KRB5_GC_USER_USER, cc, &creds,
				     &new_creds)))
    com_err("bzfs", retval, "getting user-user ticket");
  else
    trusted = true;
}
#else
void Authentication::verifyCredential(char *, int)
{
}
#endif // HAVE_KRB5

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>using BZFLAG.ORG realm, not default one<commit_after>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named LICENSE that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "Authentication.h"

// because kebos dosn't asume anyone else but them has defines.
#ifdef MAXHOSTNAMELEN
#undef MAXHOSTNAMELEN
#endif

/* system implementation headers */
#ifdef HAVE_KRB5
#include <com_err.h>
#endif
#include <sys/types.h>
#ifndef _WIN32
#include <unistd.h>
#endif
#include <string>
#include <assert.h>

#ifdef HAVE_KRB5
krb5_context   Authentication::context        = NULL;
krb5_ccache    Authentication::cc             = NULL;
krb5_principal Authentication::client;
krb5_creds     Authentication::my_creds;
#endif
bool           Authentication::authentication = false;

Authentication::Authentication() : trusted(false)
{
}

#ifdef HAVE_KRB5
void Authentication::init(const char *address, int port, const char *password)
{
  assert(context == NULL);
  assert(cc == NULL);

  krb5_error_code retval;
  char            ccfile[MAXPATHLEN+6]; // FILE:path+\0

  if (!address)
    return;

  int i;
  char serverName[128];
  strncpy(serverName, address, 128);
  for (i = 0; i < 127 && serverName[i] != 0 && serverName[i] != ':'; i++);

  // With no public address we cannot do auth
  if (!i)
    return;
  serverName[i] = 0;

  // Initializing kerberos library
  if ((retval = krb5_init_context(&context)))
    com_err("bzfs:", retval, "while initializing krb5");

  // Gettin a default cache different for any bzfs process
  sprintf(ccfile, "FILE:/tmp/krb5cc_p%ld", (long)getpid());
  if (context && (retval = krb5_cc_set_default_name(context, ccfile)))
    com_err("bzfs:", retval, "setting default cache");
  unlink(ccfile+strlen("FILE:"));

  // Getting credential cache
  if (!retval && (retval = krb5_cc_default(context, &cc)))
    com_err("bzfs:", retval, "getting credentials cache");

  // Getting principal identifier
  char name[1024];
  snprintf(name, sizeof(name), "%d/%s@BZFLAG.ORG", port, serverName);
  if (cc && (retval = krb5_parse_name(context, name, &client)))
    com_err("bzfs:", retval, "getting principal name");

  // Initing credential cache
  if (!retval && (retval = krb5_cc_initialize(context, cc, client)))
    com_err("bzfs:", retval, "initializing credential cache");

  char intPassword[128];
  strncpy(intPassword, password, 128);
  intPassword[127] = 0;
  // Get credentials for server
  if (!retval && (retval = krb5_get_init_creds_password(context, &my_creds,
 							client, intPassword,
 							krb5_prompter_posix,
 							NULL, 0, NULL, NULL)))
    com_err("bzfs:", retval, "getting credential");

  // Store credentials in cache
  if (!retval && (retval = krb5_cc_store_cred(context, cc, &my_creds)))
    com_err("bzfs:", retval, "storing credential in cache");

  if (!retval)
    authentication = true;
}
#else
void Authentication::init(const char *, int , const char *)
{
}
#endif

#ifdef HAVE_KRB5
void Authentication::setPrincipalName(char *buf, int len)
{
  if (!authentication)
    return;

  krb5_error_code retval;
  char            remotePrincipal[1024];

  memcpy(remotePrincipal, buf, len);
  remotePrincipal[len] = 0;

  if ((retval = krb5_parse_name(context, remotePrincipal, &server)))
    com_err("bzfs", retval, "parsing remote name");
}
#else
void Authentication::setPrincipalName(char *, int)
{
}
#endif

#ifdef HAVE_KRB5
void Authentication::verifyCredential(char *buf, int len)
{
  if (!authentication)
    return;

  krb5_creds        creds;
  krb5_error_code   retval;
  krb5_creds       *new_creds;

  memset((char*)&creds, 0, sizeof(creds));
  memcpy(&creds.client, &client, sizeof(client));
  memcpy(&creds.server, &server, sizeof(server));

  creds.second_ticket.length = len;
  creds.second_ticket.data   = buf;

  // Check authentication info
  if ((retval = krb5_get_credentials(context, KRB5_GC_USER_USER, cc, &creds,
				     &new_creds)))
    com_err("bzfs", retval, "getting user-user ticket");
  else
    trusted = true;
}
#else
void Authentication::verifyCredential(char *, int)
{
}
#endif // HAVE_KRB5

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>#include "test/test_syscoin_services.h"
#include "data/utxo.json.h"
#include "utiltime.h"
#include "rpcserver.h"
#include <boost/test/unit_test.hpp>
#include <univalue.h>
int currentTx = 0;
extern UniValue read_json(const std::string& jsondata);
BOOST_FIXTURE_TEST_SUITE (syscoin_snapshot_tests, SyscoinMainNetSetup)
struct PaymentAmount
{
	std::string address;
	std::string amount;
};
void VerifySnapShot()
{
}
void SendSnapShotPayment(const std::string &strSend)
{
	currentTx++;
	std::string strSendMany = "sendmany \"\" {" + strSend + "}";
	UniValue r;
	printf("strSendMany #%d\n", currentTx);
	BOOST_CHECK_NO_THROW(r = CallRPC("mainnet1", strSendMany, false));
}
void GenerateSnapShot(const std::vector<PaymentAmount> &paymentAmounts)
{
	int numberOfTxPerBlock = 1000;
	std::string sendManyString = "";
	for(int i =0;i<paymentAmounts.size();i++)
	{
		if(sendManyString != "")
			sendManyString += ",";
		sendManyString += "\"" + paymentAmounts[i].address "\"" + "," + paymentAmounts[i].amount;
		if(i != 0 && (i%numberOfTxPerBlock) == 0)
		{
			SendSnapShotPayment(sendManyString);
			GenerateMainNetBlocks(1, "mainnet1");
			sendManyString = "";
		}
	}
	if(sendManyString != "")
	{
		SendSnapShotPayment(sendManyString);
		GenerateMainNetBlocks(1, "mainnet1");
	}

}
void GetUTXOs(std::vector<PaymentAmount> &paymentAmounts)
{
    UniValue tests = read_json(std::string(json_tests::utxo, json_tests::utxo + sizeof(json_tests::utxo)));
    for (unsigned int idx = 0; idx < tests.size(); idx++) {
        UniValue test = tests[idx];
        std::string strTest = test.write();
        if (test.size() < 2) // Allow for extra stuff (useful for comments)
        {
            BOOST_ERROR("Bad test: " << strTest);
            continue;
        }
		PaymentAmount payment;
        payment.address  = test[0].get_str();
        payment.amount = ValueFromAmount(test[1].get_int64()).write();
		paymentAmounts.push_back(payment);
    }
}
bool IsMainNetAlreadyCreated()
{
	int height;
	UniValue r;
	BOOST_CHECK_NO_THROW(r = CallRPC("mainnet1", "getinfo", false));
	height = find_value(r.get_obj(), "blocks").get_int();
	return height > 0;
}
BOOST_AUTO_TEST_CASE (generate_and_verify_snapshot)
{
	std::vector<PaymentAmount> paymentAmounts;
	GetUTXOs(paymentAmounts);
	if(IsMainNetAlreadyCreated())
	{
		VerifySnapShot();
	}
	else
	{
		GenerateSnapShot(paymentAmounts);
		VerifySnapShot();
	}
}
BOOST_AUTO_TEST_SUITE_END ()<commit_msg>typo<commit_after>#include "test/test_syscoin_services.h"
#include "data/utxo.json.h"
#include "utiltime.h"
#include "rpcserver.h"
#include <boost/test/unit_test.hpp>
#include <univalue.h>
int currentTx = 0;
extern UniValue read_json(const std::string& jsondata);
BOOST_FIXTURE_TEST_SUITE (syscoin_snapshot_tests, SyscoinMainNetSetup)
struct PaymentAmount
{
	std::string address;
	std::string amount;
};
void VerifySnapShot()
{
}
void SendSnapShotPayment(const std::string &strSend)
{
	currentTx++;
	std::string strSendMany = "sendmany \"\" {" + strSend + "}";
	UniValue r;
	printf("strSendMany #%d\n", currentTx);
	BOOST_CHECK_NO_THROW(r = CallRPC("mainnet1", strSendMany, false));
}
void GenerateSnapShot(const std::vector<PaymentAmount> &paymentAmounts)
{
	int numberOfTxPerBlock = 1000;
	std::string sendManyString = "";
	for(int i =0;i<paymentAmounts.size();i++)
	{
		if(sendManyString != "")
			sendManyString += ",";
		sendManyString += "\"" + paymentAmounts[i].address + "\"," + paymentAmounts[i].amount;
		if(i != 0 && (i%numberOfTxPerBlock) == 0)
		{
			SendSnapShotPayment(sendManyString);
			GenerateMainNetBlocks(1, "mainnet1");
			sendManyString = "";
		}
	}
	if(sendManyString != "")
	{
		SendSnapShotPayment(sendManyString);
		GenerateMainNetBlocks(1, "mainnet1");
	}

}
void GetUTXOs(std::vector<PaymentAmount> &paymentAmounts)
{
    UniValue tests = read_json(std::string(json_tests::utxo, json_tests::utxo + sizeof(json_tests::utxo)));
    for (unsigned int idx = 0; idx < tests.size(); idx++) {
        UniValue test = tests[idx];
        std::string strTest = test.write();
        if (test.size() < 2) // Allow for extra stuff (useful for comments)
        {
            BOOST_ERROR("Bad test: " << strTest);
            continue;
        }
		PaymentAmount payment;
        payment.address  = test[0].get_str();
        payment.amount = ValueFromAmount(test[1].get_int64()).write();
		paymentAmounts.push_back(payment);
    }
}
bool IsMainNetAlreadyCreated()
{
	int height;
	UniValue r;
	BOOST_CHECK_NO_THROW(r = CallRPC("mainnet1", "getinfo", false));
	height = find_value(r.get_obj(), "blocks").get_int();
	return height > 0;
}
BOOST_AUTO_TEST_CASE (generate_and_verify_snapshot)
{
	std::vector<PaymentAmount> paymentAmounts;
	GetUTXOs(paymentAmounts);
	if(IsMainNetAlreadyCreated())
	{
		VerifySnapShot();
	}
	else
	{
		GenerateSnapShot(paymentAmounts);
		VerifySnapShot();
	}
}
BOOST_AUTO_TEST_SUITE_END ()<|endoftext|>


<commit_before>/*
 * Copyright 2009-2020 The VOTCA Development Team (http://www.votca.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 *
 *     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.
 *
 */
#define BOOST_TEST_MAIN

#define BOOST_TEST_MODULE threecenter_gwbse_test

// Third party includes
#include <boost/test/unit_test.hpp>

// VOTCA inlcudes
#include <votca/tools/tokenizer.h>
#include <votca/tools/eigenio_matrixmarket.h>

// Local VOTCA includes
#include "votca/xtp/aobasis.h"
#include "votca/xtp/qmmolecule.h"
#include "votca/xtp/threecenter.h"

using namespace votca::xtp;
using namespace std;

BOOST_AUTO_TEST_SUITE(threecenter_gwbse_test)
BOOST_AUTO_TEST_CASE(threecenter_gwbse) {

    QMMolecule mol(" ", 0);
  mol.LoadFromFile(std::string(XTP_TEST_DATA_FOLDER) + "/threecenter_gwbse/molecule.xyz");
  BasisSet basis;
  basis.Load(std::string(XTP_TEST_DATA_FOLDER) + "/threecenter_gwbse/3-21G.xml");
  AOBasis aobasis;
  aobasis.Fill(basis, mol);

  Eigen::MatrixXd MOs = votca::tools::EigenIO_MatrixMarket::ReadMatrix(
  std::string(XTP_TEST_DATA_FOLDER) + "/threecenter_gwbse/MOs.mm");

  Logger log;
  TCMatrix_gwbse tc{log};
  tc.Initialize(aobasis.AOBasisSize(), 0, 5, 0, 7);
  tc.Fill(aobasis, aobasis, MOs);

  Eigen::MatrixXd ref0b = votca::tools::EigenIO_MatrixMarket::ReadMatrix(
  std::string(XTP_TEST_DATA_FOLDER) + "/threecenter_gwbse/ref0b.mm");

  bool check0_before = ref0b.isApprox(tc[0], 1e-5);
  if (!check0_before) {
    cout << "tc0" << endl;
    cout << tc[0] << endl;
    cout << "tc0_ref" << endl;
    cout << ref0b << endl;
  }
  BOOST_CHECK_EQUAL(check0_before, true);

  Eigen::MatrixXd ref2b = votca::tools::EigenIO_MatrixMarket::ReadMatrix(
  std::string(XTP_TEST_DATA_FOLDER) + "/threecenter_gwbse/ref2b.mm");

  bool check2_before = ref2b.isApprox(tc[2], 1e-5);
  if (!check2_before) {
    cout << "tc2" << endl;
    cout << tc[2] << endl;
    cout << "tc2_ref" << endl;
    cout << ref2b << endl;
  }

  BOOST_CHECK_EQUAL(check2_before, true);

  Eigen::MatrixXd ref4b = votca::tools::EigenIO_MatrixMarket::ReadMatrix(
  std::string(XTP_TEST_DATA_FOLDER) + "/threecenter_gwbse/ref4b.mm");

  bool check4_before = ref4b.isApprox(tc[4], 1e-5);
  if (!check4_before) {
    cout << "tc4" << endl;
    cout << tc[4] << endl;
    cout << "tc4_ref" << endl;
    cout << ref4b << endl;
  }

  BOOST_CHECK_EQUAL(check4_before, true);

  Eigen::MatrixXd auxmatrix =
      Eigen::MatrixXd::Identity(aobasis.AOBasisSize(), aobasis.AOBasisSize());
  tc.MultiplyRightWithAuxMatrix(auxmatrix);

  bool check0_after = ref0b.isApprox(tc[0], 1e-5);
  if (!check0_after) {
    cout << "tc0" << endl;
    cout << tc[0] << endl;
    cout << "tc0_ref" << endl;
    cout << ref0b << endl;
  }
  BOOST_CHECK_EQUAL(check0_after, true);

  bool check2_after = ref2b.isApprox(tc[2], 1e-5);
  if (!check2_after) {
    cout << "tc2" << endl;
    cout << tc[2] << endl;
    cout << "tc2_ref" << endl;
    cout << ref2b << endl;
  }

  BOOST_CHECK_EQUAL(check2_after, true);

  bool check4_after = ref4b.isApprox(tc[4], 1e-5);
  if (!check4_after) {
    cout << "tc4" << endl;
    cout << tc[4] << endl;
    cout << "tc4_ref" << endl;
    cout << ref4b << endl;
  }

  BOOST_CHECK_EQUAL(check4_after, true);
}
BOOST_AUTO_TEST_SUITE_END()
<commit_msg>Format code using clang-format version 10.0.0 (Fedora 10.0.0-2.fc32)<commit_after>/*
 * Copyright 2009-2020 The VOTCA Development Team (http://www.votca.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 *
 *     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.
 *
 */
#define BOOST_TEST_MAIN

#define BOOST_TEST_MODULE threecenter_gwbse_test

// Third party includes
#include <boost/test/unit_test.hpp>

// VOTCA inlcudes
#include <votca/tools/eigenio_matrixmarket.h>
#include <votca/tools/tokenizer.h>

// Local VOTCA includes
#include "votca/xtp/aobasis.h"
#include "votca/xtp/qmmolecule.h"
#include "votca/xtp/threecenter.h"

using namespace votca::xtp;
using namespace std;

BOOST_AUTO_TEST_SUITE(threecenter_gwbse_test)
BOOST_AUTO_TEST_CASE(threecenter_gwbse) {

  QMMolecule mol(" ", 0);
  mol.LoadFromFile(std::string(XTP_TEST_DATA_FOLDER) +
                   "/threecenter_gwbse/molecule.xyz");
  BasisSet basis;
  basis.Load(std::string(XTP_TEST_DATA_FOLDER) +
             "/threecenter_gwbse/3-21G.xml");
  AOBasis aobasis;
  aobasis.Fill(basis, mol);

  Eigen::MatrixXd MOs = votca::tools::EigenIO_MatrixMarket::ReadMatrix(
      std::string(XTP_TEST_DATA_FOLDER) + "/threecenter_gwbse/MOs.mm");

  Logger log;
  TCMatrix_gwbse tc{log};
  tc.Initialize(aobasis.AOBasisSize(), 0, 5, 0, 7);
  tc.Fill(aobasis, aobasis, MOs);

  Eigen::MatrixXd ref0b = votca::tools::EigenIO_MatrixMarket::ReadMatrix(
      std::string(XTP_TEST_DATA_FOLDER) + "/threecenter_gwbse/ref0b.mm");

  bool check0_before = ref0b.isApprox(tc[0], 1e-5);
  if (!check0_before) {
    cout << "tc0" << endl;
    cout << tc[0] << endl;
    cout << "tc0_ref" << endl;
    cout << ref0b << endl;
  }
  BOOST_CHECK_EQUAL(check0_before, true);

  Eigen::MatrixXd ref2b = votca::tools::EigenIO_MatrixMarket::ReadMatrix(
      std::string(XTP_TEST_DATA_FOLDER) + "/threecenter_gwbse/ref2b.mm");

  bool check2_before = ref2b.isApprox(tc[2], 1e-5);
  if (!check2_before) {
    cout << "tc2" << endl;
    cout << tc[2] << endl;
    cout << "tc2_ref" << endl;
    cout << ref2b << endl;
  }

  BOOST_CHECK_EQUAL(check2_before, true);

  Eigen::MatrixXd ref4b = votca::tools::EigenIO_MatrixMarket::ReadMatrix(
      std::string(XTP_TEST_DATA_FOLDER) + "/threecenter_gwbse/ref4b.mm");

  bool check4_before = ref4b.isApprox(tc[4], 1e-5);
  if (!check4_before) {
    cout << "tc4" << endl;
    cout << tc[4] << endl;
    cout << "tc4_ref" << endl;
    cout << ref4b << endl;
  }

  BOOST_CHECK_EQUAL(check4_before, true);

  Eigen::MatrixXd auxmatrix =
      Eigen::MatrixXd::Identity(aobasis.AOBasisSize(), aobasis.AOBasisSize());
  tc.MultiplyRightWithAuxMatrix(auxmatrix);

  bool check0_after = ref0b.isApprox(tc[0], 1e-5);
  if (!check0_after) {
    cout << "tc0" << endl;
    cout << tc[0] << endl;
    cout << "tc0_ref" << endl;
    cout << ref0b << endl;
  }
  BOOST_CHECK_EQUAL(check0_after, true);

  bool check2_after = ref2b.isApprox(tc[2], 1e-5);
  if (!check2_after) {
    cout << "tc2" << endl;
    cout << tc[2] << endl;
    cout << "tc2_ref" << endl;
    cout << ref2b << endl;
  }

  BOOST_CHECK_EQUAL(check2_after, true);

  bool check4_after = ref4b.isApprox(tc[4], 1e-5);
  if (!check4_after) {
    cout << "tc4" << endl;
    cout << tc[4] << endl;
    cout << "tc4_ref" << endl;
    cout << ref4b << endl;
  }

  BOOST_CHECK_EQUAL(check4_after, true);
}
BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>#include "chatcontroller.h"

#include <QtCore/QFile>
#include <QtCore/QThread>

ChatController::ChatController(QObject *parent) : QTcpServer(parent)
{
    init();
}

void ChatController::connectingUsers(const QByteArray &sender, const QByteArray &receiver, const QByteArray &publicKey)
{
    // Check if both user are already registered
    if ( deviceList.contains(sender) && deviceList.contains(receiver) ) {
        Connector * connector = deviceList.value(receiver)->getConnector();

        connector->send(
                        QByteArrayLiteral("STARTUP:") +
                        sender +
                        QByteArrayLiteral("\r\n") +
                        publicKey +
                        QByteArrayLiteral("\r\n\r\n")
                    );
    }
}

void ChatController::sendMessageToUserFromUser(const QByteArray &sender,
                                               const QByteArray &receiver,
                                               const QByteArray &message)
{
    // Check if both user are already registered
    if ( deviceList.contains(sender) && deviceList.contains(receiver) ) {

        qDebug() << "send message to user";

        Connector * connector = deviceList.value(receiver)->getConnector();
        connector->send(
                        QByteArrayLiteral("MESSAGE:") +
                        sender +
                        QByteArrayLiteral("\r\n") +
                        message +
                        QByteArrayLiteral("\r\n\r\n")
                    );
    }
}

void ChatController::sendEncryptionKey(const QByteArray &sender,
                                       const QByteArray &receiver,
                                       const QByteArray &encryptedKey)
{
    // Check if both user are already registered
    if ( deviceList.contains(sender) && deviceList.contains(receiver) ) {

        qDebug() << "send encryption key to user";

        Connector * connector = deviceList.value(receiver)->getConnector();
        connector->send(
                        QByteArrayLiteral("ENCRYPT:") +
                        sender +
                        QByteArrayLiteral("\r\n") +
                        encryptedKey +
                        QByteArrayLiteral("\r\n\r\n")
                    );
    }
}

void ChatController::closeUser(const QByteArray &username)
{
    deviceList.value(username)->deleteLater();
    deviceList.remove(username);
}

void ChatController::ready()
{
    const QByteArray userLiteral("USER:");
    const QByteArray endLiteral("\r\n\r\n");

    qDebug() << "On connection ready";
    QTcpSocket * socket = pendingSockets.dequeue();

    QSslSocket * sslSocket = qobject_cast<QSslSocket *>(socket);
    qDebug() << sslSocket->sessionCipher();

    QByteArray data = socket->readAll();

    disconnect(socket, SIGNAL(readyRead()), this, SLOT(ready()));

    if ( data.indexOf(userLiteral) != 0 ) {
        socket->write(QByteArrayLiteral("ERROR:NO USER\r\n\r\n"));
        socket->close();
        return;
    }

    data = data.remove(0, userLiteral.length());

    int endIndex = data.indexOf(endLiteral);
    if ( endIndex == -1 ) {
        socket->write(QByteArrayLiteral("ERROR:NO END\r\n\r\n"));
        socket->close();
        return;
    }

    // Get user name
    data = data.remove(endIndex, endLiteral.length());

    if ( data.length() == 0 ) {
        socket->write(QByteArrayLiteral("ERROR:NO USER\r\n\r\n"));
        socket->close();
        return;
    }

    if ( !deviceList.contains(data) ) {
        ChatDeviceController * deviceController = new ChatDeviceController(socket, this, data);
        deviceController->listen();
        deviceList.insert(data, deviceController);
    }
    else {
        socket->write(QByteArrayLiteral("ERROR:WRONG USER\r\n\r\n"));
        socket->close();
        return;
    }
}

void ChatController::onError(QAbstractSocket::SocketError error)
{
    qDebug() << "SOCKET ERROR: " << error;
}

void ChatController::onSslErrors(QList<QSslError> errors)
{
    qDebug() << "SSL ERRORS: " << errors;
}

void ChatController::init()
{
    // Save certificate
    QFile certificateFile("certificates/cert.pem");
    if ( !certificateFile.open(QIODevice::ReadOnly) ) {
        qWarning() << "CERTIFICATE FILE ERROR: Could not open (" << certificateFile.errorString() << ")";
    }

    QByteArray data = certificateFile.readAll();
    certificateFile.close();

    certificate = QSslCertificate(data);

    // Allowed ciphers
    ciphers << QSslCipher(QStringLiteral("ECDHE-RSA-AES256-GCM-SHA384"), QSsl::TlsV1_2);

    // Private key

    QFile privateKeyFile("certificates/key.pem");
    if ( !privateKeyFile.open(QIODevice::ReadOnly) ) {
        qWarning() << "PRIVATE KEY FILE ERROR: Could not open (" << privateKeyFile.errorString() << ")";
    }

    data = privateKeyFile.readAll();

    certificateFile.close();

    privateKey = QSslKey(data,
                         QSsl::Rsa,
                         QSsl::Pem,
                         QSsl::PrivateKey,
                         QByteArrayLiteral("1234"));
}

void ChatController::incomingConnection(qintptr socketDescriptor)
{
    QSslSocket *serverSocket = new QSslSocket;

    qDebug() << "New connection";

    if (serverSocket->setSocketDescriptor(socketDescriptor)) {
        connect(serverSocket, SIGNAL(readyRead()), this, SLOT(ready()));

        connect(serverSocket, SIGNAL(error(QAbstractSocket::SocketError)),
                this, SLOT(onError(QAbstractSocket::SocketError)));

        connect(serverSocket, SIGNAL(sslErrors(QList<QSslError>)),
                this, SLOT(onSslErrors(QList<QSslError>)));

        qDebug() << "Connected to encrypted signal";

        serverSocket->setPrivateKey(privateKey);
        serverSocket->setLocalCertificate(certificate);

        // Update config
        QSslConfiguration config = serverSocket->sslConfiguration();
        config.setProtocol(QSsl::TlsV1_2);
        //config.setCiphers(ciphers);

        serverSocket->setSslConfiguration(config);

        serverSocket->startServerEncryption();

        pendingSockets.enqueue(serverSocket);
    } else {
        delete serverSocket;
    }
}
<commit_msg>You have to compile this server with at least Qt 5.5 (perfect forward secrecy ciphers support)<commit_after>#include "chatcontroller.h"

#include <QtCore/QFile>
#include <QtCore/QThread>

ChatController::ChatController(QObject *parent) : QTcpServer(parent)
{
    init();
}

void ChatController::connectingUsers(const QByteArray &sender, const QByteArray &receiver, const QByteArray &publicKey)
{
    // Check if both user are already registered
    if ( deviceList.contains(sender) && deviceList.contains(receiver) ) {
        Connector * connector = deviceList.value(receiver)->getConnector();

        connector->send(
                        QByteArrayLiteral("STARTUP:") +
                        sender +
                        QByteArrayLiteral("\r\n") +
                        publicKey +
                        QByteArrayLiteral("\r\n\r\n")
                    );
    }
}

void ChatController::sendMessageToUserFromUser(const QByteArray &sender,
                                               const QByteArray &receiver,
                                               const QByteArray &message)
{
    // Check if both user are already registered
    if ( deviceList.contains(sender) && deviceList.contains(receiver) ) {

        qDebug() << "send message to user";

        Connector * connector = deviceList.value(receiver)->getConnector();
        connector->send(
                        QByteArrayLiteral("MESSAGE:") +
                        sender +
                        QByteArrayLiteral("\r\n") +
                        message +
                        QByteArrayLiteral("\r\n\r\n")
                    );
    }
}

void ChatController::sendEncryptionKey(const QByteArray &sender,
                                       const QByteArray &receiver,
                                       const QByteArray &encryptedKey)
{
    // Check if both user are already registered
    if ( deviceList.contains(sender) && deviceList.contains(receiver) ) {

        qDebug() << "send encryption key to user";

        Connector * connector = deviceList.value(receiver)->getConnector();
        connector->send(
                        QByteArrayLiteral("ENCRYPT:") +
                        sender +
                        QByteArrayLiteral("\r\n") +
                        encryptedKey +
                        QByteArrayLiteral("\r\n\r\n")
                    );
    }
}

void ChatController::closeUser(const QByteArray &username)
{
    deviceList.value(username)->deleteLater();
    deviceList.remove(username);
}

void ChatController::ready()
{
    const QByteArray userLiteral("USER:");
    const QByteArray endLiteral("\r\n\r\n");

    qDebug() << "On connection ready";
    QTcpSocket * socket = pendingSockets.dequeue();

    QSslSocket * sslSocket = qobject_cast<QSslSocket *>(socket);
    qDebug() << sslSocket->sessionCipher();

    QByteArray data = socket->readAll();

    disconnect(socket, SIGNAL(readyRead()), this, SLOT(ready()));

    if ( data.indexOf(userLiteral) != 0 ) {
        socket->write(QByteArrayLiteral("ERROR:NO USER\r\n\r\n"));
        socket->close();
        return;
    }

    data = data.remove(0, userLiteral.length());

    int endIndex = data.indexOf(endLiteral);
    if ( endIndex == -1 ) {
        socket->write(QByteArrayLiteral("ERROR:NO END\r\n\r\n"));
        socket->close();
        return;
    }

    // Get user name
    data = data.remove(endIndex, endLiteral.length());

    if ( data.length() == 0 ) {
        socket->write(QByteArrayLiteral("ERROR:NO USER\r\n\r\n"));
        socket->close();
        return;
    }

    if ( !deviceList.contains(data) ) {
        ChatDeviceController * deviceController = new ChatDeviceController(socket, this, data);
        deviceController->listen();
        deviceList.insert(data, deviceController);
    }
    else {
        socket->write(QByteArrayLiteral("ERROR:WRONG USER\r\n\r\n"));
        socket->close();
        return;
    }
}

void ChatController::onError(QAbstractSocket::SocketError error)
{
    qDebug() << "SOCKET ERROR: " << error;
}

void ChatController::onSslErrors(QList<QSslError> errors)
{
    qDebug() << "SSL ERRORS: " << errors;
}

void ChatController::init()
{
    // Save certificate
    QFile certificateFile("certificates/cert.pem");
    if ( !certificateFile.open(QIODevice::ReadOnly) ) {
        qWarning() << "CERTIFICATE FILE ERROR: Could not open (" << certificateFile.errorString() << ")";
    }

    QByteArray data = certificateFile.readAll();
    certificateFile.close();

    certificate = QSslCertificate(data);

    // Allowed ciphers
    ciphers << QSslCipher(QStringLiteral("ECDHE-RSA-AES256-GCM-SHA384"), QSsl::TlsV1_2);

    // Private key

    QFile privateKeyFile("certificates/key.pem");
    if ( !privateKeyFile.open(QIODevice::ReadOnly) ) {
        qWarning() << "PRIVATE KEY FILE ERROR: Could not open (" << privateKeyFile.errorString() << ")";
    }

    data = privateKeyFile.readAll();

    certificateFile.close();

    privateKey = QSslKey(data,
                         QSsl::Rsa,
                         QSsl::Pem,
                         QSsl::PrivateKey,
                         QByteArrayLiteral("1234"));
}

void ChatController::incomingConnection(qintptr socketDescriptor)
{
    QSslSocket *serverSocket = new QSslSocket;

    qDebug() << "New connection";

    if (serverSocket->setSocketDescriptor(socketDescriptor)) {
        connect(serverSocket, SIGNAL(readyRead()), this, SLOT(ready()));

        connect(serverSocket, SIGNAL(error(QAbstractSocket::SocketError)),
                this, SLOT(onError(QAbstractSocket::SocketError)));

        connect(serverSocket, SIGNAL(sslErrors(QList<QSslError>)),
                this, SLOT(onSslErrors(QList<QSslError>)));

        qDebug() << "Connected to encrypted signal";

        serverSocket->setPrivateKey(privateKey);
        serverSocket->setLocalCertificate(certificate);

        // Update config
        QSslConfiguration config = serverSocket->sslConfiguration();
        config.setProtocol(QSsl::TlsV1_2);
        config.setCiphers(ciphers);

        serverSocket->setSslConfiguration(config);

        serverSocket->startServerEncryption();

        pendingSockets.enqueue(serverSocket);
    } else {
        delete serverSocket;
    }
}
<|endoftext|>