<commit_before>/*
 * Copyright (C) 2004, Mart Kelder (mart.kde@hccnet.nl)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "keditlistboxman.h"

#include <kconfig.h>
#include <kdebug.h>

#include <qmap.h>
#include <qlistview.h>
#include <qstring.h>

KEditListBoxManager::KEditListBoxManager(	QWidget *parent, const char *name,
						bool checkAtEntering, KEditListBox::Buttons buttons )
	: KEditListBox( parent, name, checkAtEntering, buttons ),
	_config( 0 ),
	_groupName( 0 ),
	_subGroupName( 0 ),
	_prevCount( 0 )
{
	init();
}

KEditListBoxManager::KEditListBoxManager(	const QString& title, QWidget *parent,
						const char *name, bool checkAtEntering,
						KEditListBox::Buttons buttons)
	: KEditListBox( title, parent, name, checkAtEntering, buttons ),
	_config( 0 ),
	_groupName( 0 ),
	_subGroupName( 0 ),
	_prevCount( 0 )
{
	init();
}

KEditListBoxManager::KEditListBoxManager(	const QString& title,
						const KEditListBox::CustomEditor &customEditor,
						QWidget *parent, const char *name,
						bool checkAtEntering, KEditListBox::Buttons buttons )
	: KEditListBox( title, customEditor, parent, name, checkAtEntering, buttons ),
	_config( 0 ),
	_groupName( 0 ),
	_subGroupName( 0 ),
	_prevCount( 0 )
{
	init();
}

KEditListBoxManager::~KEditListBoxManager()
{
	delete _groupName;
}

void KEditListBoxManager::setConfig( KConfig* config )
{
	_config = config;
	if( _groupName )
		readNames();
}

void KEditListBoxManager::setGroupName( const QString& name )
{
	if( _groupName )
		*_groupName = name;
	else
		_groupName = new QString( name );

	if( _config )
		readNames();
}

void KEditListBoxManager::setSubGroupName( const QString& name )
{
	if( _subGroupName )
		*_subGroupName = name;
	else
		_subGroupName = new QString( name );

	if( _config && _groupName )
		readNames();
}

void KEditListBoxManager::init()
{
	connect( this, SIGNAL( changed() ), this, SLOT( slotChanged() ) );
	connect( this, SIGNAL( added( const QString& ) ), this, SLOT( slotAdded( const QString& ) ) );
	connect( this, SIGNAL( removed( const QString& ) ), this, SLOT( slotRemoved( const QString& ) ) );

	connect( this->listView(), SIGNAL( doubleClicked( const QModelIndex&) ), this, SLOT( slotActivated( const QModelIndex& ) ) );
	connect( this->listView(), SIGNAL( returnPressed( const QModelIndex& ) ), this, SLOT( slotActivated( const QModelIndex& ) ) );
}

void KEditListBoxManager::readNames()
{
	int number = 0;

	this->clear();
	while( _config->hasGroup( _groupName->arg( number ) ) )
	{
		_config->setGroup( _groupName->arg( number ) );
		this->insertItem( _config->readEntry( "name", QString() ) );
		++number;
	}

	_prevCount = this->count();
}

void KEditListBoxManager::slotChanged()
{
	/* Three thing could be hapened:
	 * 1. the text is changed;
	 * 2. the item has moved up;
	 * 3. the item has moved down.
	 */

	//_prevCount is invariant under all of these operation
	//if _prevCount is changed, is wasn't one of those operations.

	if( _prevCount != this->count() )
		return;

	 if( !_config || !_groupName )
	 	return;

	//First check if the item was moved up

        int ci = currentItem();
        if (ci >= 0)
 		_config->setGroup( _groupName->arg( ci ) );

	if( ci > 0 && this->text( ci - 1 ) == _config->readEntry( "name", QString() ) )
		changeItem( ci - 1, ci ); //moved down
	else if( ci >= 0 && ci < this->count() - 1 &&
		 this->text( ci + 1 ) == _config->readEntry( "name", QString() ) )
		changeItem( ci, ci + 1 );  //moved up
	else if( this->currentText() != _config->readEntry( "name", QString() ) )
		changedText(); //changed
}

void KEditListBoxManager::slotAdded( const QString& name )
{
	//Update _prevCount
	_prevCount = this->count();

	if( !_config || !_groupName )
	 	return;

	int number = 0;
	while( _config->hasGroup( _groupName->arg( number ) ) )
		++number;

	_config->setGroup( _groupName->arg( number ) );
	_config->writeEntry( "name", name );

	emit setDefaults( name, number, _config );
}

void KEditListBoxManager::slotRemoved( const QString& name )
{
	//Update prevCount
	_prevCount = this->count();

	if( !_config || !_groupName )
	 	return;

	//First: search the item number.
	int number = 0;
	int subnumber = 0;
	while( true )
	{
		if( !_config->hasGroup( _groupName->arg( number ) ) )
		{
			number = -1; //not found
			break;
		}
		_config->setGroup( _groupName->arg( number ) );
		if( name == _config->readEntry( "name", QString() ) )
			break; //found

		++number; //Try next group
	}

	if( number < 0 ) //failure
		return; //do nothing

	_config->deleteGroup( _groupName->arg( number ), KConfig::NLS );
	emit elementDeleted( number );
	while( _subGroupName && _config->hasGroup( _subGroupName->arg( number ).arg( subnumber ) ) )
	{
		_config->deleteGroup( _subGroupName->arg( number ).arg( subnumber ) );
		++subnumber;
	}

	//rotate groups
	while( _config->hasGroup( _groupName->arg( number + 1 ) ) )
	{
		moveItem( number + 1, number );

		++number;
	}
}

void KEditListBoxManager::slotActivated( const QModelIndex& item )
{
	emit activated( item );
}

void KEditListBoxManager::moveItem( int src, int dest )
{
	QMap<QString, QString> *srcList = new QMap<QString, QString >;
	QMap<QString, QString>::iterator it;
	int subnumber = 0;

	*srcList = _config->entryMap( _groupName->arg( src ) );
	_config->deleteGroup( _groupName->arg( src ) );

	_config->setGroup( _groupName->arg( dest ) );
	for( it = srcList->begin(); it != srcList->end(); ++it )
		_config->writeEntry( it.key(), it.value() );

	while( _subGroupName && _config->hasGroup( _subGroupName->arg( src ).arg( subnumber ) ) )
	{
		_config->deleteGroup( _subGroupName->arg( dest ).arg( subnumber ) );
		_config->setGroup( _subGroupName->arg( dest ).arg( subnumber ) );
		for( it = srcList->begin(); it != srcList->end(); ++it )
			_config->writeEntry( it.key(), it.value() );

		++subnumber;
	}

	emit elementsSwapped( src, dest );

	delete srcList;
}

void KEditListBoxManager::changeItem( int first, int last )
{
	QMap<QString, QString> *firstList = new QMap<QString, QString >;
	QMap<QString, QString> *lastList = new QMap<QString, QString >;
	QMap<QString, QString>::iterator it;
	int subnumber = 0;

	*firstList = _config->entryMap( _groupName->arg( first ) );
	*lastList = _config->entryMap( _groupName->arg( last ) );
	_config->deleteGroup( _groupName->arg( first ) );
	_config->deleteGroup( _groupName->arg( last ) );

	_config->setGroup( _groupName->arg( last ) );
	for( it = firstList->begin(); it != firstList->end(); ++it )
		_config->writeEntry( it.key(), it.value() );

	_config->setGroup( _groupName->arg( first ) );
	for( it = lastList->begin(); it != lastList->end(); ++it )
		_config->writeEntry( it.key(), it.value() );

	while( _subGroupName && (
		_config->hasGroup( _subGroupName->arg( first ).arg( subnumber ) ) ||
		_config->hasGroup( _subGroupName->arg( last ).arg( subnumber ) ) ) )
	{
		*firstList = _config->entryMap( _subGroupName->arg( first ).arg( subnumber ) );
		*lastList = _config->entryMap( _subGroupName->arg( last ).arg( subnumber ) );
		_config->deleteGroup( _subGroupName->arg( first ).arg( subnumber ) );
		_config->deleteGroup( _subGroupName->arg( last ).arg( subnumber ) );

		_config->setGroup( _subGroupName->arg( last ).arg( subnumber ) );
		for( it = firstList->begin(); it != firstList->end(); ++it )
			_config->writeEntry( it.key(), it.value() );

		_config->setGroup( _subGroupName->arg( first ).arg( subnumber ) );
		for( it = lastList->begin(); it != lastList->end(); ++it )
			_config->writeEntry( it.key(), it.value() );

		++subnumber;
	}

	emit elementsSwapped( first, last );

	delete firstList;
	delete lastList;
}

void KEditListBoxManager::changedText()
{
	_config->setGroup( _groupName->arg( this->currentItem() ) );
	_config->writeEntry( "name", this->currentText() );
}

#include "keditlistboxman.moc"
<commit_msg>fix crash (CID 1355)<commit_after>/*
 * Copyright (C) 2004, Mart Kelder (mart.kde@hccnet.nl)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "keditlistboxman.h"

#include <kconfig.h>
#include <kdebug.h>

#include <qmap.h>
#include <qlistview.h>
#include <qstring.h>

KEditListBoxManager::KEditListBoxManager(	QWidget *parent, const char *name,
						bool checkAtEntering, KEditListBox::Buttons buttons )
	: KEditListBox( parent, name, checkAtEntering, buttons ),
	_config( 0 ),
	_groupName( 0 ),
	_subGroupName( 0 ),
	_prevCount( 0 )
{
	init();
}

KEditListBoxManager::KEditListBoxManager(	const QString& title, QWidget *parent,
						const char *name, bool checkAtEntering,
						KEditListBox::Buttons buttons)
	: KEditListBox( title, parent, name, checkAtEntering, buttons ),
	_config( 0 ),
	_groupName( 0 ),
	_subGroupName( 0 ),
	_prevCount( 0 )
{
	init();
}

KEditListBoxManager::KEditListBoxManager(	const QString& title,
						const KEditListBox::CustomEditor &customEditor,
						QWidget *parent, const char *name,
						bool checkAtEntering, KEditListBox::Buttons buttons )
	: KEditListBox( title, customEditor, parent, name, checkAtEntering, buttons ),
	_config( 0 ),
	_groupName( 0 ),
	_subGroupName( 0 ),
	_prevCount( 0 )
{
	init();
}

KEditListBoxManager::~KEditListBoxManager()
{
	delete _groupName;
}

void KEditListBoxManager::setConfig( KConfig* config )
{
	_config = config;
	if( _groupName )
		readNames();
}

void KEditListBoxManager::setGroupName( const QString& name )
{
	if( _groupName )
		*_groupName = name;
	else
		_groupName = new QString( name );

	if( _config )
		readNames();
}

void KEditListBoxManager::setSubGroupName( const QString& name )
{
	if( _subGroupName )
		*_subGroupName = name;
	else
		_subGroupName = new QString( name );

	if( _config && _groupName )
		readNames();
}

void KEditListBoxManager::init()
{
	connect( this, SIGNAL( changed() ), this, SLOT( slotChanged() ) );
	connect( this, SIGNAL( added( const QString& ) ), this, SLOT( slotAdded( const QString& ) ) );
	connect( this, SIGNAL( removed( const QString& ) ), this, SLOT( slotRemoved( const QString& ) ) );

	connect( this->listView(), SIGNAL( doubleClicked( const QModelIndex&) ), this, SLOT( slotActivated( const QModelIndex& ) ) );
	connect( this->listView(), SIGNAL( returnPressed( const QModelIndex& ) ), this, SLOT( slotActivated( const QModelIndex& ) ) );
}

void KEditListBoxManager::readNames()
{
	int number = 0;

	this->clear();
	while( _config->hasGroup( _groupName->arg( number ) ) )
	{
		_config->setGroup( _groupName->arg( number ) );
		this->insertItem( _config->readEntry( "name", QString() ) );
		++number;
	}

	_prevCount = this->count();
}

void KEditListBoxManager::slotChanged()
{
	/* Three thing could be hapened:
	 * 1. the text is changed;
	 * 2. the item has moved up;
	 * 3. the item has moved down.
	 */

	//_prevCount is invariant under all of these operation
	//if _prevCount is changed, is wasn't one of those operations.

	if( _prevCount != this->count() )
		return;

	 if( !_config || !_groupName )
	 	return;

	//First check if the item was moved up

        int ci = currentItem();
        if (ci >= 0)
 		_config->setGroup( _groupName->arg( ci ) );

	if( ci > 0 && this->text( ci - 1 ) == _config->readEntry( "name", QString() ) )
		changeItem( ci - 1, ci ); //moved down
	else if( ci >= 0 && ci < this->count() - 1 &&
		 this->text( ci + 1 ) == _config->readEntry( "name", QString() ) )
		changeItem( ci, ci + 1 );  //moved up
	else if( this->currentText() != _config->readEntry( "name", QString() ) )
		changedText(); //changed
}

void KEditListBoxManager::slotAdded( const QString& name )
{
	//Update _prevCount
	_prevCount = this->count();

	if( !_config || !_groupName )
	 	return;

	int number = 0;
	while( _config->hasGroup( _groupName->arg( number ) ) )
		++number;

	_config->setGroup( _groupName->arg( number ) );
	_config->writeEntry( "name", name );

	emit setDefaults( name, number, _config );
}

void KEditListBoxManager::slotRemoved( const QString& name )
{
	//Update prevCount
	_prevCount = this->count();

	if( !_config || !_groupName )
	 	return;

	//First: search the item number.
	int number = 0;
	int subnumber = 0;
	while( true )
	{
		if( !_config->hasGroup( _groupName->arg( number ) ) )
		{
			number = -1; //not found
			break;
		}
		_config->setGroup( _groupName->arg( number ) );
		if( name == _config->readEntry( "name", QString() ) )
			break; //found

		++number; //Try next group
	}

	if( number < 0 ) //failure
		return; //do nothing

	_config->deleteGroup( _groupName->arg( number ), KConfig::NLS );
	emit elementDeleted( number );
	while( _subGroupName && _config->hasGroup( _subGroupName->arg( number ).arg( subnumber ) ) )
	{
		_config->deleteGroup( _subGroupName->arg( number ).arg( subnumber ) );
		++subnumber;
	}

	//rotate groups
	while( _config->hasGroup( _groupName->arg( number + 1 ) ) )
	{
		moveItem( number + 1, number );

		++number;
	}
}

void KEditListBoxManager::slotActivated( const QModelIndex& item )
{
	emit activated( item );
}

void KEditListBoxManager::moveItem( int src, int dest )
{
	QMap<QString, QString> *srcList = new QMap<QString, QString >;
	QMap<QString, QString>::iterator it;
	int subnumber = 0;

	*srcList = _config->entryMap( _groupName->arg( src ) );
	_config->deleteGroup( _groupName->arg( src ) );

	_config->setGroup( _groupName->arg( dest ) );
	for( it = srcList->begin(); it != srcList->end(); ++it )
		_config->writeEntry( it.key(), it.value() );

	while( _subGroupName && _config->hasGroup( _subGroupName->arg( src ).arg( subnumber ) ) )
	{
		_config->deleteGroup( _subGroupName->arg( dest ).arg( subnumber ) );
		_config->setGroup( _subGroupName->arg( dest ).arg( subnumber ) );
		for( it = srcList->begin(); it != srcList->end(); ++it )
			_config->writeEntry( it.key(), it.value() );

		++subnumber;
	}

	emit elementsSwapped( src, dest );

	delete srcList;
}

void KEditListBoxManager::changeItem( int first, int last )
{
	QMap<QString, QString> *firstList = new QMap<QString, QString >;
	QMap<QString, QString> *lastList = new QMap<QString, QString >;
	QMap<QString, QString>::iterator it;
	int subnumber = 0;

	*firstList = _config->entryMap( _groupName->arg( first ) );
	*lastList = _config->entryMap( _groupName->arg( last ) );
	_config->deleteGroup( _groupName->arg( first ) );
	_config->deleteGroup( _groupName->arg( last ) );

	_config->setGroup( _groupName->arg( last ) );
	for( it = firstList->begin(); it != firstList->end(); ++it )
		_config->writeEntry( it.key(), it.value() );

	_config->setGroup( _groupName->arg( first ) );
	for( it = lastList->begin(); it != lastList->end(); ++it )
		_config->writeEntry( it.key(), it.value() );

	while( _subGroupName && (
		_config->hasGroup( _subGroupName->arg( first ).arg( subnumber ) ) ||
		_config->hasGroup( _subGroupName->arg( last ).arg( subnumber ) ) ) )
	{
		*firstList = _config->entryMap( _subGroupName->arg( first ).arg( subnumber ) );
		*lastList = _config->entryMap( _subGroupName->arg( last ).arg( subnumber ) );
		_config->deleteGroup( _subGroupName->arg( first ).arg( subnumber ) );
		_config->deleteGroup( _subGroupName->arg( last ).arg( subnumber ) );

		_config->setGroup( _subGroupName->arg( last ).arg( subnumber ) );
		for( it = firstList->begin(); it != firstList->end(); ++it )
			_config->writeEntry( it.key(), it.value() );

		_config->setGroup( _subGroupName->arg( first ).arg( subnumber ) );
		for( it = lastList->begin(); it != lastList->end(); ++it )
			_config->writeEntry( it.key(), it.value() );

		++subnumber;
	}

	emit elementsSwapped( first, last );

	delete firstList;
	delete lastList;
}

void KEditListBoxManager::changedText()
{
	int ci = this->currentItem();
        if (ci < 0) return;

	_config->setGroup( _groupName->arg( ci ) );
	_config->writeEntry( "name", this->currentText() );
}

#include "keditlistboxman.moc"
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <opencv2/opencv.hpp>
#include <stdio.h>
#include <stdlib.h>
#include <vector>

using namespace cv;
using std::vector;

int main(int argc, char** argv) {
    // Display usage
    if (argc < 5) {
        printf("Usage: %s <rows> <cols> <size> [cameras...]\n", argv[0]);
        return -1;
    }

    // Parse arguments
    int rows = atoi(argv[1]);
    int cols = atoi(argv[2]);
    float size = atof(argv[3]);

    // Open video capture devices
    vector<VideoCapture> devices;
    vector<vector<vector<Point2f>>> img_points;
    vector<vector<vector<Point3f>>> obj_points;
    for (int i = 4; i < argc; i++) {
        int id = atoi(argv[i]);
        VideoCapture device(id);
        if (device.isOpened()) {
            device.set(CV_CAP_PROP_FRAME_WIDTH, 1280);
            device.set(CV_CAP_PROP_FRAME_HEIGHT, 720);
            device.set(CV_CAP_PROP_FPS, 30);
            img_points.push_back(vector<vector<Point2f>>());
            obj_points.push_back(vector<vector<Point3f>>());
        }
        else {
            std::cerr << "Failed to open video capture device " << id << std::endl;
        }
        devices.push_back(device);
    }

    // Calibration variables
    Size checkerboard_size(rows, cols);
    vector<Point3f> checkerboard_points;
    for (int j = 0; j < cols; j++) {
        for (int i = 0; i < rows; i++) {
            checkerboard_points.push_back(Point3f(i * size, j * size, 0.f));
        }
    }

    int key = 0;
    Mat frame, gray;
    vector<Point2f> corners;
    while (key != 27) { // Quit on escape keypress
        for (size_t i = 0; i < devices.size(); i++) {
            if (!devices[i].isOpened()) {
                continue;
            }

            devices[i] >> frame;

            // Detect checkerboards on spacebar
            if (waitKey(1) == 32) {
                cvtColor(frame, gray, COLOR_BGR2GRAY);
                bool found = findChessboardCorners(gray, checkerboard_size, corners);
                if (found) {
                    std::cout << "Found checkerboard on " << i << std::endl;
                    img_points[i].push_back(corners);
                    obj_points[i].push_back(checkerboard_points);
                    cornerSubPix(gray, corners, Size(11, 11), Size(-1, -1),
                            TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
                }
                drawChessboardCorners(frame, checkerboard_size, Mat(corners), found);
            }

            imshow(std::to_string(i), frame);
        }

        key = waitKey(16);
        if (key == 'w') { // Write calibration to text files
            Mat camera_matrix;
            Mat dist_coeffs;
            vector<Mat> rvecs;
            vector<Mat> tvecs;
            for (size_t i = 0; i < devices.size(); i++) {
                if (!devices[i].isOpened()) {
                    continue;
                }
                if (obj_points[i].size() == 0) {
                    std::cout << "No checkerboards detected on camera " << i << std::endl;
                    continue;
                }

                std::cout << "Calibrate camera " << i << std::endl;
                calibrateCamera(obj_points[i], img_points[i], frame.size(), camera_matrix,
                        dist_coeffs, rvecs, tvecs);

                std::cout << "Write calibration" << std::endl;
                std::ofstream fout;
                fout.open(std::to_string(i) + ".calib");
                fout << "camera_matrix =";
                for (int r = 0; r < camera_matrix.rows; r++) {
                    for (int c = 0; c < camera_matrix.cols; c++) {
                        //fout << " " << camera_matrix.at<float>(r, c);
                    }
                }
                fout.close();

                std::cout << "Write calibration output to " << i << ".calib" << std:: endl;
            }
        }
    }
}
<commit_msg>Fix write to camera calibration<commit_after>#include <iostream>
#include <fstream>
#include <opencv2/opencv.hpp>
#include <stdio.h>
#include <stdlib.h>
#include <vector>

using namespace cv;
using std::vector;

int main(int argc, char** argv) {
    // Display usage
    if (argc < 5) {
        printf("Usage: %s <rows> <cols> <size> [cameras...]\n", argv[0]);
        return -1;
    }

    // Parse arguments
    int rows = atoi(argv[1]);
    int cols = atoi(argv[2]);
    float size = atof(argv[3]);

    // Open video capture devices
    vector<VideoCapture> devices;
    vector<int> device_ids;
    vector<vector<vector<Point2f>>> img_points;
    vector<vector<vector<Point3f>>> obj_points;
    for (int i = 4; i < argc; i++) {
        int id = atoi(argv[i]);
        VideoCapture device(id);
        if (device.isOpened()) {
            device.set(CV_CAP_PROP_FRAME_WIDTH, 1280);
            device.set(CV_CAP_PROP_FRAME_HEIGHT, 720);
            device.set(CV_CAP_PROP_FPS, 30);
            img_points.push_back(vector<vector<Point2f>>());
            obj_points.push_back(vector<vector<Point3f>>());
            devices.push_back(device);
            device_ids.push_back(id);
        }
        else {
            std::cerr << "Failed to open video capture device " << id << std::endl;
        }
    }

    // Calibration variables
    Size checkerboard_size(rows, cols);
    vector<Point3f> checkerboard_points;
    for (int j = 0; j < cols; j++) {
        for (int i = 0; i < rows; i++) {
            checkerboard_points.push_back(Point3f(i * size, j * size, 0.f));
        }
    }

    int key = 0;
    Mat frame, gray;
    vector<Point2f> corners;
    while (key != 27) { // Quit on escape keypress
        for (size_t i = 0; i < devices.size(); i++) {
            if (!devices[i].isOpened()) {
                continue;
            }

            devices[i] >> frame;

            // Detect checkerboards on spacebar
            if (waitKey(1) == 32) {
                cvtColor(frame, gray, COLOR_BGR2GRAY);
                bool found = findChessboardCorners(gray, checkerboard_size, corners,
                        CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE + CALIB_CB_FAST_CHECK);
                if (found) {
                    std::cout << "Found checkerboard on " << i << std::endl;
                    img_points[i].push_back(corners);
                    obj_points[i].push_back(checkerboard_points);
                    cornerSubPix(gray, corners, Size(11, 11), Size(-1, -1),
                            TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
                }
                drawChessboardCorners(frame, checkerboard_size, Mat(corners), found);
            }

            imshow(std::to_string(i), frame);
        }

        key = waitKey(16);
        if (key == 'w') { // Write calibration to text files
            Mat camera_matrix;
            Mat dist_coeffs;
            vector<Mat> rvecs;
            vector<Mat> tvecs;
            for (size_t i = 0; i < devices.size(); i++) {
                if (!devices[i].isOpened()) {
                    continue;
                }
                if (obj_points[i].size() == 0) {
                    std::cout << "No checkerboards detected on camera " << device_ids[i] << std::endl;
                    continue;
                }

                // TODO Check if calibration already exists first

                std::cout << "Calibrate camera " << device_ids[i] << std::endl;
                calibrateCamera(obj_points[i], img_points[i], frame.size(), camera_matrix,
                        dist_coeffs, rvecs, tvecs);

                std::cout << "Write calibration" << std::endl;
                std::ofstream fout;
                fout.open(std::to_string(device_ids[i]) + ".calib");
                fout << "camera_matrix =";
                for (int r = 0; r < camera_matrix.rows; r++) {
                    for (int c = 0; c < camera_matrix.cols; c++) {
                        fout << " " << camera_matrix.at<double>(r, c);
                    }
                }
                fout << std::endl;
                fout << "dist_coeffs =";
                for (int r = 0; r < dist_coeffs.rows; r++) {
                    for (int c = 0; c < dist_coeffs.cols; c++) {
                        fout << " " << dist_coeffs.at<double>(r, c);
                    }
                }
                fout << std::endl;
                fout.close();

                std::cout << "Write calibration output to " << device_ids[i] << ".calib" << std:: endl;
            }
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h"

#include "base/logging.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/content_settings/host_content_settings_map.h"
#include "chrome/browser/download/download_request_limiter.h"
#include "chrome/browser/download/download_throttling_resource_handler.h"
#include "chrome/browser/download/download_util.h"
#include "chrome/browser/external_protocol/external_protocol_handler.h"
#include "chrome/browser/instant/instant_loader.h"
#include "chrome/browser/net/load_timing_observer.h"
#include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/browser/prerender/prerender_manager_factory.h"
#include "chrome/browser/prerender/prerender_tracker.h"
#include "chrome/browser/profiles/profile_io_data.h"
#include "chrome/browser/renderer_host/chrome_url_request_user_data.h"
#include "chrome/browser/renderer_host/safe_browsing_resource_handler.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
#include "chrome/browser/ui/auto_login_prompter.h"
#include "chrome/browser/ui/login/login_prompt.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/extensions/user_script.h"
#include "chrome/common/render_messages.h"
#include "content/browser/browser_thread.h"
#include "content/browser/resource_context.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/renderer_host/resource_dispatcher_host.h"
#include "content/browser/renderer_host/resource_dispatcher_host_request_info.h"
#include "content/browser/renderer_host/resource_message_filter.h"
#include "content/public/browser/notification_service.h"
#include "content/common/resource_messages.h"
#include "net/base/load_flags.h"

// TODO(oshima): Enable this for other platforms.
#if defined(OS_CHROMEOS)
#include "chrome/browser/renderer_host/offline_resource_handler.h"
#endif

namespace {

// Empty ResourceDispatcherHostLoginDelegate implementation used for instant.
// Auth navigations don't commit the load (the load remains pending) until the
// user cancels or succeeds in authorizing. Since we don't allow merging of
// TabContents with pending loads we disallow auth dialogs from showing during
// instant. This empty ResourceDispatcherHostLoginDelegate implementation does
// that.
// TODO: see if we can handle this case more robustly.
class InstantResourceDispatcherHostLoginDelegate
    : public ResourceDispatcherHostLoginDelegate {
 public:
  InstantResourceDispatcherHostLoginDelegate() {}

 private:
  DISALLOW_COPY_AND_ASSIGN(InstantResourceDispatcherHostLoginDelegate);
};

void AddPrerenderOnUI(
    int render_process_id, int render_view_id,
    const GURL& url, const GURL& referrer) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  prerender::PrerenderManager* prerender_manager =
      prerender::FindPrerenderManagerUsingRenderProcessId(render_process_id);
  if (!prerender_manager || !prerender_manager->is_enabled())
    return;

  prerender_manager->AddPrerenderFromLinkRelPrerender(render_process_id,
                                                      render_view_id,
                                                      url,
                                                      referrer);
}

void NotifyDownloadInitiatedOnUI(int render_process_id, int render_view_id) {
  RenderViewHost* rvh = RenderViewHost::FromID(render_process_id,
                                               render_view_id);
  if (!rvh)
    return;

  content::NotificationService::current()->Notify(
      chrome::NOTIFICATION_DOWNLOAD_INITIATED,
      content::Source<RenderViewHost>(rvh),
      content::NotificationService::NoDetails());
}

}  // end namespace

ChromeResourceDispatcherHostDelegate::ChromeResourceDispatcherHostDelegate(
    ResourceDispatcherHost* resource_dispatcher_host,
    prerender::PrerenderTracker* prerender_tracker)
    : resource_dispatcher_host_(resource_dispatcher_host),
      download_request_limiter_(g_browser_process->download_request_limiter()),
      safe_browsing_(g_browser_process->safe_browsing_service()),
      prerender_tracker_(prerender_tracker) {
}

ChromeResourceDispatcherHostDelegate::~ChromeResourceDispatcherHostDelegate() {
}

bool ChromeResourceDispatcherHostDelegate::ShouldBeginRequest(
    int child_id, int route_id,
    const ResourceHostMsg_Request& request_data,
    const content::ResourceContext& resource_context,
    const GURL& referrer) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));

  // Handle a PREFETCH resource type. If prefetch is disabled, squelch the
  // request.  Otherwise, do a normal request to warm the cache.
  if (request_data.resource_type == ResourceType::PREFETCH) {
    // All PREFETCH requests should be GETs, but be defensive about it.
    if (request_data.method != "GET")
      return false;

    // If prefetch is disabled, kill the request.
    if (!ResourceDispatcherHost::is_prefetch_enabled())
      return false;
  }

  // Handle a PRERENDER motivated request. Very similar to rel=prefetch, these
  // rel=prerender requests instead launch an early render of the entire page.
  if (request_data.resource_type == ResourceType::PRERENDER) {
    if (prerender::PrerenderManager::IsPrerenderingPossible()) {
      BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
          NewRunnableFunction(AddPrerenderOnUI,
                              child_id,
                              route_id,
                              request_data.url,
                              referrer));
    }
    // Prerendering or not, this request should be aborted.
    return false;
  }

  // Abort any prerenders that spawn requests that use invalid HTTP methods.
  if (prerender_tracker_->IsPrerenderingOnIOThread(child_id, route_id) &&
      !prerender::PrerenderManager::IsValidHttpMethod(request_data.method)) {
    prerender_tracker_->TryCancelOnIOThread(
        child_id, route_id,
        prerender::FINAL_STATUS_INVALID_HTTP_METHOD);
    return false;
  }

  return true;
}

ResourceHandler* ChromeResourceDispatcherHostDelegate::RequestBeginning(
    ResourceHandler* handler,
    net::URLRequest* request,
    const content::ResourceContext& resource_context,
    bool is_subresource,
    int child_id,
    int route_id) {
  ChromeURLRequestUserData* user_data =
      ChromeURLRequestUserData::Create(request);
  if (prerender_tracker_->IsPrerenderingOnIOThread(child_id, route_id)) {
    user_data->set_is_prerender(true);
    request->set_priority(net::IDLE);
  }

#if defined(ENABLE_SAFE_BROWSING)
  // Insert safe browsing at the front of the chain, so it gets to decide
  // on policies first.
  ProfileIOData* io_data = reinterpret_cast<ProfileIOData*>(
      resource_context.GetUserData(NULL));
  if (io_data->safe_browsing_enabled()->GetValue()) {
    handler = CreateSafeBrowsingResourceHandler(
        handler, child_id, route_id, is_subresource);
  }
#endif

#if defined(OS_CHROMEOS)
  // We check offline first, then check safe browsing so that we still can block
  // unsafe site after we remove offline page.
  handler = new OfflineResourceHandler(
      handler, child_id, route_id, resource_dispatcher_host_, request,
      resource_context.appcache_service());
#endif
  return handler;
}

ResourceHandler* ChromeResourceDispatcherHostDelegate::DownloadStarting(
      ResourceHandler* handler,
      const content::ResourceContext& resource_context,
      net::URLRequest* request,
      int child_id,
      int route_id,
      int request_id,
      bool is_new_request,
      bool in_complete) {

  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE,
      NewRunnableFunction(&NotifyDownloadInitiatedOnUI, child_id, route_id));

  // If this isn't a new request, we've seen this before and added the safe
  // browsing resource handler already so no need to add it again. This code
  // path is only hit for requests initiated through the browser, and not the
  // web, so no need to add the throttling handler.
  if (is_new_request) {
#if defined(ENABLE_SAFE_BROWSING)
    ProfileIOData* io_data = reinterpret_cast<ProfileIOData*>(
        resource_context.GetUserData(NULL));
    if (!io_data->safe_browsing_enabled()->GetValue())
      return handler;

    return CreateSafeBrowsingResourceHandler(
        handler, child_id, route_id, false);
#else
    return handler;
#endif
  }

  return new DownloadThrottlingResourceHandler(
      handler, resource_dispatcher_host_, download_request_limiter_, request,
      request->url(), child_id, route_id, request_id, in_complete);
}

bool ChromeResourceDispatcherHostDelegate::ShouldDeferStart(
    net::URLRequest* request,
    const content::ResourceContext& resource_context) {
  ResourceDispatcherHostRequestInfo* info =
      resource_dispatcher_host_->InfoForRequest(request);
  return prerender_tracker_->PotentiallyDelayRequestOnIOThread(
      request->url(), info->child_id(), info->route_id(), info->request_id());
}

bool ChromeResourceDispatcherHostDelegate::AcceptSSLClientCertificateRequest(
    net::URLRequest* request, net::SSLCertRequestInfo* cert_request_info) {
  if (request->load_flags() & net::LOAD_PREFETCH)
    return false;

  ChromeURLRequestUserData* user_data = ChromeURLRequestUserData::Get(request);
  if (user_data && user_data->is_prerender()) {
    int child_id, route_id;
    if (ResourceDispatcherHost::RenderViewForRequest(
            request, &child_id, &route_id)) {
      if (prerender_tracker_->TryCancel(
              child_id, route_id,
              prerender::FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED)) {
        return false;
      }
    }
  }

  return true;
}

bool ChromeResourceDispatcherHostDelegate::AcceptAuthRequest(
    net::URLRequest* request,
    net::AuthChallengeInfo* auth_info) {
  ChromeURLRequestUserData* user_data = ChromeURLRequestUserData::Get(request);
  if (!user_data || !user_data->is_prerender())
    return true;

  int child_id, route_id;
  if (!ResourceDispatcherHost::RenderViewForRequest(
          request, &child_id, &route_id)) {
    NOTREACHED();
    return true;
  }

  if (!prerender_tracker_->TryCancelOnIOThread(
          child_id, route_id, prerender::FINAL_STATUS_AUTH_NEEDED)) {
    return true;
  }

  return false;
}

ResourceDispatcherHostLoginDelegate*
    ChromeResourceDispatcherHostDelegate::CreateLoginDelegate(
        net::AuthChallengeInfo* auth_info, net::URLRequest* request) {
  std::string instant_header_value;
  if (request->extra_request_headers().GetHeader(
          InstantLoader::kInstantHeader, &instant_header_value) &&
      instant_header_value == InstantLoader::kInstantHeaderValue)
    return new InstantResourceDispatcherHostLoginDelegate;
  return CreateLoginPrompt(auth_info, request);
}

void ChromeResourceDispatcherHostDelegate::HandleExternalProtocol(
    const GURL& url, int child_id, int route_id) {
  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE,
      NewRunnableFunction(
          &ExternalProtocolHandler::LaunchUrl, url, child_id, route_id));
}

#if defined(ENABLE_SAFE_BROWSING)
ResourceHandler*
    ChromeResourceDispatcherHostDelegate::CreateSafeBrowsingResourceHandler(
        ResourceHandler* handler, int child_id, int route_id,
        bool subresource) {
  return SafeBrowsingResourceHandler::Create(
      handler, child_id, route_id, subresource, safe_browsing_,
      resource_dispatcher_host_);
}
#endif

bool ChromeResourceDispatcherHostDelegate::ShouldForceDownloadResource(
    const GURL& url, const std::string& mime_type) {
  // Special-case user scripts to get downloaded instead of viewed.
  return UserScript::IsURLUserScript(url, mime_type);
}

void ChromeResourceDispatcherHostDelegate::OnResponseStarted(
    net::URLRequest* request,
    ResourceResponse* response,
    ResourceMessageFilter* filter) {
  LoadTimingObserver::PopulateTimingInfo(request, response);

  // We must send the content settings for the URL before sending response
  // headers to the renderer.
  const content::ResourceContext& resource_context = filter->resource_context();
  ProfileIOData* io_data =
      reinterpret_cast<ProfileIOData*>(resource_context.GetUserData(NULL));
  HostContentSettingsMap* map = io_data->GetHostContentSettingsMap();

  ResourceDispatcherHostRequestInfo* info =
      resource_dispatcher_host_->InfoForRequest(request);
  filter->Send(new ChromeViewMsg_SetContentSettingsForLoadingURL(
      info->route_id(), request->url(),
      map->GetContentSettings(request->url(), request->url())));

  // See if the response contains the X-Auto-Login header.  If so, this was
  // a request for a login page, and the server is allowing the browser to
  // suggest auto-login, if available.
  AutoLoginPrompter::ShowInfoBarIfPossible(request, info->child_id(),
                                           info->route_id());
}

void ChromeResourceDispatcherHostDelegate::OnRequestRedirected(
    net::URLRequest* request,
    ResourceResponse* response,
    ResourceMessageFilter* filter) {
  LoadTimingObserver::PopulateTimingInfo(request, response);
}
<commit_msg>Replace NewRunnableFunction with Callback in ChromeResourceDispatcherHostDelegate.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h"

#include "base/logging.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/content_settings/host_content_settings_map.h"
#include "chrome/browser/download/download_request_limiter.h"
#include "chrome/browser/download/download_throttling_resource_handler.h"
#include "chrome/browser/download/download_util.h"
#include "chrome/browser/external_protocol/external_protocol_handler.h"
#include "chrome/browser/instant/instant_loader.h"
#include "chrome/browser/net/load_timing_observer.h"
#include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/browser/prerender/prerender_manager_factory.h"
#include "chrome/browser/prerender/prerender_tracker.h"
#include "chrome/browser/profiles/profile_io_data.h"
#include "chrome/browser/renderer_host/chrome_url_request_user_data.h"
#include "chrome/browser/renderer_host/safe_browsing_resource_handler.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
#include "chrome/browser/ui/auto_login_prompter.h"
#include "chrome/browser/ui/login/login_prompt.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/extensions/user_script.h"
#include "chrome/common/render_messages.h"
#include "content/browser/browser_thread.h"
#include "content/browser/resource_context.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/renderer_host/resource_dispatcher_host.h"
#include "content/browser/renderer_host/resource_dispatcher_host_request_info.h"
#include "content/browser/renderer_host/resource_message_filter.h"
#include "content/public/browser/notification_service.h"
#include "content/common/resource_messages.h"
#include "net/base/load_flags.h"

// TODO(oshima): Enable this for other platforms.
#if defined(OS_CHROMEOS)
#include "chrome/browser/renderer_host/offline_resource_handler.h"
#endif

namespace {

// Empty ResourceDispatcherHostLoginDelegate implementation used for instant.
// Auth navigations don't commit the load (the load remains pending) until the
// user cancels or succeeds in authorizing. Since we don't allow merging of
// TabContents with pending loads we disallow auth dialogs from showing during
// instant. This empty ResourceDispatcherHostLoginDelegate implementation does
// that.
// TODO: see if we can handle this case more robustly.
class InstantResourceDispatcherHostLoginDelegate
    : public ResourceDispatcherHostLoginDelegate {
 public:
  InstantResourceDispatcherHostLoginDelegate() {}

 private:
  DISALLOW_COPY_AND_ASSIGN(InstantResourceDispatcherHostLoginDelegate);
};

void AddPrerenderOnUI(
    int render_process_id, int render_view_id,
    const GURL& url, const GURL& referrer) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  prerender::PrerenderManager* prerender_manager =
      prerender::FindPrerenderManagerUsingRenderProcessId(render_process_id);
  if (!prerender_manager || !prerender_manager->is_enabled())
    return;

  prerender_manager->AddPrerenderFromLinkRelPrerender(render_process_id,
                                                      render_view_id,
                                                      url,
                                                      referrer);
}

void NotifyDownloadInitiatedOnUI(int render_process_id, int render_view_id) {
  RenderViewHost* rvh = RenderViewHost::FromID(render_process_id,
                                               render_view_id);
  if (!rvh)
    return;

  content::NotificationService::current()->Notify(
      chrome::NOTIFICATION_DOWNLOAD_INITIATED,
      content::Source<RenderViewHost>(rvh),
      content::NotificationService::NoDetails());
}

}  // end namespace

ChromeResourceDispatcherHostDelegate::ChromeResourceDispatcherHostDelegate(
    ResourceDispatcherHost* resource_dispatcher_host,
    prerender::PrerenderTracker* prerender_tracker)
    : resource_dispatcher_host_(resource_dispatcher_host),
      download_request_limiter_(g_browser_process->download_request_limiter()),
      safe_browsing_(g_browser_process->safe_browsing_service()),
      prerender_tracker_(prerender_tracker) {
}

ChromeResourceDispatcherHostDelegate::~ChromeResourceDispatcherHostDelegate() {
}

bool ChromeResourceDispatcherHostDelegate::ShouldBeginRequest(
    int child_id, int route_id,
    const ResourceHostMsg_Request& request_data,
    const content::ResourceContext& resource_context,
    const GURL& referrer) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));

  // Handle a PREFETCH resource type. If prefetch is disabled, squelch the
  // request.  Otherwise, do a normal request to warm the cache.
  if (request_data.resource_type == ResourceType::PREFETCH) {
    // All PREFETCH requests should be GETs, but be defensive about it.
    if (request_data.method != "GET")
      return false;

    // If prefetch is disabled, kill the request.
    if (!ResourceDispatcherHost::is_prefetch_enabled())
      return false;
  }

  // Handle a PRERENDER motivated request. Very similar to rel=prefetch, these
  // rel=prerender requests instead launch an early render of the entire page.
  if (request_data.resource_type == ResourceType::PRERENDER) {
    if (prerender::PrerenderManager::IsPrerenderingPossible()) {
      BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
          base::Bind(&AddPrerenderOnUI,
                     child_id,
                     route_id,
                     request_data.url,
                     referrer));
    }
    // Prerendering or not, this request should be aborted.
    return false;
  }

  // Abort any prerenders that spawn requests that use invalid HTTP methods.
  if (prerender_tracker_->IsPrerenderingOnIOThread(child_id, route_id) &&
      !prerender::PrerenderManager::IsValidHttpMethod(request_data.method)) {
    prerender_tracker_->TryCancelOnIOThread(
        child_id, route_id,
        prerender::FINAL_STATUS_INVALID_HTTP_METHOD);
    return false;
  }

  return true;
}

ResourceHandler* ChromeResourceDispatcherHostDelegate::RequestBeginning(
    ResourceHandler* handler,
    net::URLRequest* request,
    const content::ResourceContext& resource_context,
    bool is_subresource,
    int child_id,
    int route_id) {
  ChromeURLRequestUserData* user_data =
      ChromeURLRequestUserData::Create(request);
  if (prerender_tracker_->IsPrerenderingOnIOThread(child_id, route_id)) {
    user_data->set_is_prerender(true);
    request->set_priority(net::IDLE);
  }

#if defined(ENABLE_SAFE_BROWSING)
  // Insert safe browsing at the front of the chain, so it gets to decide
  // on policies first.
  ProfileIOData* io_data = reinterpret_cast<ProfileIOData*>(
      resource_context.GetUserData(NULL));
  if (io_data->safe_browsing_enabled()->GetValue()) {
    handler = CreateSafeBrowsingResourceHandler(
        handler, child_id, route_id, is_subresource);
  }
#endif

#if defined(OS_CHROMEOS)
  // We check offline first, then check safe browsing so that we still can block
  // unsafe site after we remove offline page.
  handler = new OfflineResourceHandler(
      handler, child_id, route_id, resource_dispatcher_host_, request,
      resource_context.appcache_service());
#endif
  return handler;
}

ResourceHandler* ChromeResourceDispatcherHostDelegate::DownloadStarting(
      ResourceHandler* handler,
      const content::ResourceContext& resource_context,
      net::URLRequest* request,
      int child_id,
      int route_id,
      int request_id,
      bool is_new_request,
      bool in_complete) {

  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE,
      base::Bind(&NotifyDownloadInitiatedOnUI, child_id, route_id));

  // If this isn't a new request, we've seen this before and added the safe
  // browsing resource handler already so no need to add it again. This code
  // path is only hit for requests initiated through the browser, and not the
  // web, so no need to add the throttling handler.
  if (is_new_request) {
#if defined(ENABLE_SAFE_BROWSING)
    ProfileIOData* io_data = reinterpret_cast<ProfileIOData*>(
        resource_context.GetUserData(NULL));
    if (!io_data->safe_browsing_enabled()->GetValue())
      return handler;

    return CreateSafeBrowsingResourceHandler(
        handler, child_id, route_id, false);
#else
    return handler;
#endif
  }

  return new DownloadThrottlingResourceHandler(
      handler, resource_dispatcher_host_, download_request_limiter_, request,
      request->url(), child_id, route_id, request_id, in_complete);
}

bool ChromeResourceDispatcherHostDelegate::ShouldDeferStart(
    net::URLRequest* request,
    const content::ResourceContext& resource_context) {
  ResourceDispatcherHostRequestInfo* info =
      resource_dispatcher_host_->InfoForRequest(request);
  return prerender_tracker_->PotentiallyDelayRequestOnIOThread(
      request->url(), info->child_id(), info->route_id(), info->request_id());
}

bool ChromeResourceDispatcherHostDelegate::AcceptSSLClientCertificateRequest(
    net::URLRequest* request, net::SSLCertRequestInfo* cert_request_info) {
  if (request->load_flags() & net::LOAD_PREFETCH)
    return false;

  ChromeURLRequestUserData* user_data = ChromeURLRequestUserData::Get(request);
  if (user_data && user_data->is_prerender()) {
    int child_id, route_id;
    if (ResourceDispatcherHost::RenderViewForRequest(
            request, &child_id, &route_id)) {
      if (prerender_tracker_->TryCancel(
              child_id, route_id,
              prerender::FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED)) {
        return false;
      }
    }
  }

  return true;
}

bool ChromeResourceDispatcherHostDelegate::AcceptAuthRequest(
    net::URLRequest* request,
    net::AuthChallengeInfo* auth_info) {
  ChromeURLRequestUserData* user_data = ChromeURLRequestUserData::Get(request);
  if (!user_data || !user_data->is_prerender())
    return true;

  int child_id, route_id;
  if (!ResourceDispatcherHost::RenderViewForRequest(
          request, &child_id, &route_id)) {
    NOTREACHED();
    return true;
  }

  if (!prerender_tracker_->TryCancelOnIOThread(
          child_id, route_id, prerender::FINAL_STATUS_AUTH_NEEDED)) {
    return true;
  }

  return false;
}

ResourceDispatcherHostLoginDelegate*
    ChromeResourceDispatcherHostDelegate::CreateLoginDelegate(
        net::AuthChallengeInfo* auth_info, net::URLRequest* request) {
  std::string instant_header_value;
  if (request->extra_request_headers().GetHeader(
          InstantLoader::kInstantHeader, &instant_header_value) &&
      instant_header_value == InstantLoader::kInstantHeaderValue)
    return new InstantResourceDispatcherHostLoginDelegate;
  return CreateLoginPrompt(auth_info, request);
}

void ChromeResourceDispatcherHostDelegate::HandleExternalProtocol(
    const GURL& url, int child_id, int route_id) {
  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE,
      base::Bind(&ExternalProtocolHandler::LaunchUrl, url, child_id, route_id));
}

#if defined(ENABLE_SAFE_BROWSING)
ResourceHandler*
    ChromeResourceDispatcherHostDelegate::CreateSafeBrowsingResourceHandler(
        ResourceHandler* handler, int child_id, int route_id,
        bool subresource) {
  return SafeBrowsingResourceHandler::Create(
      handler, child_id, route_id, subresource, safe_browsing_,
      resource_dispatcher_host_);
}
#endif

bool ChromeResourceDispatcherHostDelegate::ShouldForceDownloadResource(
    const GURL& url, const std::string& mime_type) {
  // Special-case user scripts to get downloaded instead of viewed.
  return UserScript::IsURLUserScript(url, mime_type);
}

void ChromeResourceDispatcherHostDelegate::OnResponseStarted(
    net::URLRequest* request,
    ResourceResponse* response,
    ResourceMessageFilter* filter) {
  LoadTimingObserver::PopulateTimingInfo(request, response);

  // We must send the content settings for the URL before sending response
  // headers to the renderer.
  const content::ResourceContext& resource_context = filter->resource_context();
  ProfileIOData* io_data =
      reinterpret_cast<ProfileIOData*>(resource_context.GetUserData(NULL));
  HostContentSettingsMap* map = io_data->GetHostContentSettingsMap();

  ResourceDispatcherHostRequestInfo* info =
      resource_dispatcher_host_->InfoForRequest(request);
  filter->Send(new ChromeViewMsg_SetContentSettingsForLoadingURL(
      info->route_id(), request->url(),
      map->GetContentSettings(request->url(), request->url())));

  // See if the response contains the X-Auto-Login header.  If so, this was
  // a request for a login page, and the server is allowing the browser to
  // suggest auto-login, if available.
  AutoLoginPrompter::ShowInfoBarIfPossible(request, info->child_id(),
                                           info->route_id());
}

void ChromeResourceDispatcherHostDelegate::OnRequestRedirected(
    net::URLRequest* request,
    ResourceResponse* response,
    ResourceMessageFilter* filter) {
  LoadTimingObserver::PopulateTimingInfo(request, response);
}
<|endoftext|>


<commit_before>#pragma once

#include <utility>
#include <memory>
#include <chrono>
#include <uv.h>
#include "error.h"
#include "handle.hpp"
#include "util.hpp"

namespace uvw {

class Timer final: public Handle<Timer> {
    static void startCallback(Timer &timer, uv_timer_t *) {
        timer.publish(TimerEvent{});
    }

    using Handle<Timer>::Handle;

public:
    using Time = std::chrono::milliseconds;

    template<typename... Args>
    static std::shared_ptr<Timer> create(Args&&... args) {
        return std::shared_ptr<Timer>{new Timer{std::forward<Args>(args)...}};
    }

    bool init() {
        return Handle<Timer>::init<uv_timer_t>(&uv_timer_init);
    }

    void start(Time timeout, Time repeat) {
        using CBF = CallbackFactory<void(uv_timer_t *)>;
        auto func = &CBF::template proto<&Timer::startCallback>;
        auto err = uv_timer_start(get<uv_timer_t>(), func, timeout.count(), repeat.count());
        if(err) publish(ErrorEvent{err});
    }

    void stop() {
        auto err = uv_timer_stop(get<uv_timer_t>());
        if(err) publish(ErrorEvent{err});
    }

    void again() {
        auto err = uv_timer_again(get<uv_timer_t>());
        if(err) publish(ErrorEvent{err});
    }

    void repeat(Time repeat) {
        uv_timer_set_repeat(get<uv_timer_t>(), repeat.count());
    }

    Time repeat() {
        return Time{uv_timer_get_repeat(get<uv_timer_t>())};
    }
};

}
<commit_msg>fixed include<commit_after>#pragma once

#include <utility>
#include <memory>
#include <chrono>
#include <uv.h>
#include "event.hpp"
#include "handle.hpp"
#include "util.hpp"

namespace uvw {

class Timer final: public Handle<Timer> {
    static void startCallback(Timer &timer, uv_timer_t *) {
        timer.publish(TimerEvent{});
    }

    using Handle<Timer>::Handle;

public:
    using Time = std::chrono::milliseconds;

    template<typename... Args>
    static std::shared_ptr<Timer> create(Args&&... args) {
        return std::shared_ptr<Timer>{new Timer{std::forward<Args>(args)...}};
    }

    bool init() {
        return Handle<Timer>::init<uv_timer_t>(&uv_timer_init);
    }

    void start(Time timeout, Time repeat) {
        using CBF = CallbackFactory<void(uv_timer_t *)>;
        auto func = &CBF::template proto<&Timer::startCallback>;
        auto err = uv_timer_start(get<uv_timer_t>(), func, timeout.count(), repeat.count());
        if(err) publish(ErrorEvent{err});
    }

    void stop() {
        auto err = uv_timer_stop(get<uv_timer_t>());
        if(err) publish(ErrorEvent{err});
    }

    void again() {
        auto err = uv_timer_again(get<uv_timer_t>());
        if(err) publish(ErrorEvent{err});
    }

    void repeat(Time repeat) {
        uv_timer_set_repeat(get<uv_timer_t>(), repeat.count());
    }

    Time repeat() {
        return Time{uv_timer_get_repeat(get<uv_timer_t>())};
    }
};

}
<|endoftext|>


<commit_before>#pragma once

#include <set>
#include <vector>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>

#include <stdio.h>

#include "channel9.hpp"
#include "memcheck.h"
#include "bittwiddle.h"
#include "forwardtable.hpp"

namespace Channel9
{
	class GC::Markcompact : protected GC
	{
		struct Block;
		struct Chunk;

	public:
		typedef unsigned char uchar;

		struct Data
		{
			uint16_t m_type;
			uint8_t  m_block_size; //so (this & ~((1<<blocksize)-1)) gives the pointer to the block header
			bool     m_mark;
			uint32_t m_count;   //number of bytes of memory in this allocation
			uchar    m_data[0]; //the actual data, 8 byte aligned

			Data * next() const { return (Data*)((uchar*)(this + 1) + m_count); }
			Block * block() const { return (Block *)((uintptr_t)this & ~((1 << m_block_size)-1)); }
			static Data *ptr_for(const void *ptr) { return (Data*)ptr - 1; }
		};

	private:

		static const double   GC_GROWTH_LIMIT = 2.0;
		static const uint64_t CHUNK_SIZE = 21; // 2mb
		static const uint64_t BLOCK_SIZE = 15; // 32kb

		struct Block
		{
			uint32_t m_capacity;   //in bytes, total size not including this header
			uint32_t m_next_alloc; //in bytes, offset to the next allocation
			uint32_t m_in_use;     //in bytes, how much is actually used, is m_next - unmarked Data pieces
			uint8_t  m_skipped;    //how many times a block has skipped compaction
			uint8_t  m_block_size; //used to initialize Data::m_block_size
			bool     m_mark;       //has this anything block been reached yet?
			uchar    m_data[0];    //actual memory

			void init(uint8_t block_size)
			{
				m_capacity = 1 << block_size;
				m_next_alloc = 0;
				m_in_use = 0;
				m_skipped = 0;
				m_block_size = block_size;
				m_mark = false;
				DO_DEBUG VALGRIND_CREATE_MEMPOOL(m_data, 0, false);
			}

			Data * alloc(size_t size)
			{
				if(m_next_alloc + size <= m_capacity)
				{
					Data * ret = (Data*)(m_data + m_next_alloc);
					m_next_alloc += size;
					DO_DEBUG VALGRIND_MEMPOOL_ALLOC(m_data, ret, size);
					return ret;
				}
				return NULL;
			}
			Data * begin() const { return (Data *) m_data; }
			Data * end()   const { return (Data *) (m_data + m_next_alloc); }
			Block * next() const { return (Block*)((uchar*)(this + 1) + m_capacity); }

			void deadbeef()
			{
				uint32_t * i = (uint32_t *) m_data,
				         * e = (uint32_t *) (m_data + m_capacity);
				for(; i < e; ++i)
					*i = 0xDEADBEEF;
			}
		};

		struct Chunk
		{
			uint32_t m_capacity; //in bytes
			uchar *  m_data;     //pointer to actual memory

			void init(uint32_t c, Block * b)
			{
				m_capacity = c;
				m_data = (uchar *) b;
			}

			Block * begin(){ return (Block *) m_data; }
			Block * end()  { return (Block *) (m_data + m_capacity); }
		};

		std::vector<Chunk>   m_chunks;       // list of all chunks
		std::vector<Block *> m_empty_blocks; // list of empty blocks
		Block * m_cur_block;

		ForwardTable forward;

		enum GCPhase { Running, Marking, Compacting, Updating };

		GCPhase  m_gc_phase;
		uint64_t m_alloced;  //how much memory are in all pools (active or not) combined
		uint64_t m_used;     //how much memory is used by data blocks, not including the header
		uint64_t m_data_blocks; //how many data allocations are in the current pool
		uint64_t m_next_gc;  //garbage collect when m_next_gc < m_used

		std::set<GCRoot*> m_roots;

		void collect();

		uchar *next(size_t size, uint16_t type)
		{
			assert(size < 8000);

			if(m_gc_phase == Running)
				DO_TRACEGC printf("Alloc %u type %x ... ", (unsigned)size, type);

			size += (8 - size % 8) % 8; //8 byte align

			while(1){
				Data * data = m_cur_block->alloc(size + sizeof(Data));

				if(data){
					m_used += size;
					m_data_blocks++;

					data->m_type = type;
					data->m_block_size = m_cur_block->m_block_size;
					data->m_mark = false;
					data->m_count = size;

					if(m_gc_phase == Running)
						DO_TRACEGC printf("alloc return %p\n", data->m_data);

					return data->m_data;
				}

				if(m_empty_blocks.empty())
					alloc_chunk();

				m_cur_block = m_empty_blocks.back();
				m_empty_blocks.pop_back();
			}
			return NULL;
		}

		void alloc_chunk(unsigned int size = 0){
			if(size)
				size = ceil_power2(size);
			else
				size = 1<<CHUNK_SIZE;

			Block * b = (Block *)malloc(size);

			assert((uintptr_t)b & ~((1<<BLOCK_SIZE) - 1) == 0); //make sure blocks will be properly aligned

			m_alloced += size;

			Chunk c;
			c.init(size, b);

			m_chunks.push_back(c);

			for(Block * i = b; i != c.end(); i++){
				i->init(BLOCK_SIZE);
				m_empty_blocks.push_back(i);
			}
		}

	public:
		Markcompact()
		 : m_cur_block(NULL), m_gc_phase(Running), m_alloced(0), m_used(0), m_data_blocks(0), m_next_gc(0.9*(1<<CHUNK_SIZE))
		{

			alloc_chunk();

			m_cur_block = m_empty_blocks.back();
			m_empty_blocks.pop_back();

		}

		template <typename tObj>
		tObj *alloc(size_t extra, uint16_t type)
		{
			return reinterpret_cast<tObj*>(next(sizeof(tObj) + extra, type));
		}

		template <typename tObj>
		bool validate(tObj * from)
		{
			if(m_gc_phase != Running)
				return true;
			else
				return (Data::ptr_for(from)->m_mark == false);
		}

		template <typename tObj>
		bool mark(tObj ** from)
		{
			Data * d = Data::ptr_for(*from);
			switch(m_gc_phase)
			{
			case Running:
				assert(m_gc_phase != Running); //shouldn't be calling mark when not in gc mode
			case Marking: {
				if(d->m_mark)
					return false;

				d->m_mark = true;

				m_data_blocks++;
				m_used += d->m_count;

				Block * b = d->block();
				if(!b->m_mark)
				{
					b->m_mark = true;
					b->m_in_use = 0;
				}
				b->m_in_use += d->m_count;

				gc_scan(*from);

				return false;
			}
			case Updating: {
				tObj * to = (tObj*)forward.get(d);

				bool ret = (to == *from);
				if(ret)
				{
					*from = to;
					d = Data::ptr_for(to);
				}

				if(d->m_mark)
				{
					d->m_mark = false;
					gc_scan(*from);
				}

				return ret;
			}
			}
		}

		// make sure this object is ready to be read from
		template <typename tObj>
		void read_barrier(tObj * obj) { }

		// tell the GC that obj will contain a reference to the object pointed to by ptr
		template <typename tObj, typename tPtr>
		void write_barrier(tObj * obj, tPtr * ptr) { }

		// now is a valid time to stop the world
		void safe_point() {
			if(m_next_gc < m_used)
				collect();
		}

		void register_root(GCRoot *root);
		void unregister_root(GCRoot *root);
	};
}

<commit_msg>Reduce block size and switch to mmap. It still fails, but does slightly better<commit_after>#pragma once

#include <set>
#include <vector>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>

#include <stdio.h>

#include <sys/mman.h>

#include "channel9.hpp"
#include "memcheck.h"
#include "bittwiddle.h"
#include "forwardtable.hpp"

namespace Channel9
{
	class GC::Markcompact : protected GC
	{
		struct Block;
		struct Chunk;

	public:
		typedef unsigned char uchar;

		struct Data
		{
			uint16_t m_type;
			uint8_t  m_block_size; //so (this & ~((1<<blocksize)-1)) gives the pointer to the block header
			bool     m_mark;
			uint32_t m_count;   //number of bytes of memory in this allocation
			uchar    m_data[0]; //the actual data, 8 byte aligned

			Data * next() const { return (Data*)((uchar*)(this + 1) + m_count); }
			Block * block() const { return (Block *)((uintptr_t)this & ~((1 << m_block_size)-1)); }
			static Data *ptr_for(const void *ptr) { return (Data*)ptr - 1; }
		};

	private:

		static const double   GC_GROWTH_LIMIT = 2.0;
		static const uint64_t CHUNK_SIZE = 21;
		static const uint64_t BLOCK_SIZE = 12;

		struct Block
		{
			uint32_t m_capacity;   //in bytes, total size not including this header
			uint32_t m_next_alloc; //in bytes, offset to the next allocation
			uint32_t m_in_use;     //in bytes, how much is actually used, is m_next - unmarked Data pieces
			uint8_t  m_skipped;    //how many times a block has skipped compaction
			uint8_t  m_block_size; //used to initialize Data::m_block_size
			bool     m_mark;       //has this anything block been reached yet?
			uchar    m_data[0];    //actual memory

			void init(uint8_t block_size)
			{
				m_capacity = 1 << block_size;
				m_next_alloc = 0;
				m_in_use = 0;
				m_skipped = 0;
				m_block_size = block_size;
				m_mark = false;
				DO_DEBUG VALGRIND_CREATE_MEMPOOL(m_data, 0, false);
			}

			Data * alloc(size_t size)
			{
				if(m_next_alloc + size <= m_capacity)
				{
					Data * ret = (Data*)(m_data + m_next_alloc);
					m_next_alloc += size;
					DO_DEBUG VALGRIND_MEMPOOL_ALLOC(m_data, ret, size);
					return ret;
				}
				return NULL;
			}
			Data * begin() const { return (Data *) m_data; }
			Data * end()   const { return (Data *) (m_data + m_next_alloc); }
			Block * next() const { return (Block*)((uchar*)(this + 1) + m_capacity); }

			void deadbeef()
			{
				uint32_t * i = (uint32_t *) m_data,
				         * e = (uint32_t *) (m_data + m_capacity);
				for(; i < e; ++i)
					*i = 0xDEADBEEF;
			}
		};

		struct Chunk
		{
			uint32_t m_capacity; //in bytes
			uchar *  m_data;     //pointer to actual memory

			void init(uint32_t c, Block * b)
			{
				m_capacity = c;
				m_data = (uchar *) b;
			}

			Block * begin(){ return (Block *) m_data; }
			Block * end()  { return (Block *) (m_data + m_capacity); }
		};

		std::vector<Chunk>   m_chunks;       // list of all chunks
		std::vector<Block *> m_empty_blocks; // list of empty blocks
		Block * m_cur_block;

		ForwardTable forward;

		enum GCPhase { Running, Marking, Compacting, Updating };

		GCPhase  m_gc_phase;
		uint64_t m_alloced;  //how much memory are in all pools (active or not) combined
		uint64_t m_used;     //how much memory is used by data blocks, not including the header
		uint64_t m_data_blocks; //how many data allocations are in the current pool
		uint64_t m_next_gc;  //garbage collect when m_next_gc < m_used

		std::set<GCRoot*> m_roots;

		void collect();

		uchar *next(size_t size, uint16_t type)
		{
			assert(size < 8000);

			if(m_gc_phase == Running)
				DO_TRACEGC printf("Alloc %u type %x ... ", (unsigned)size, type);

			size += (8 - size % 8) % 8; //8 byte align

			while(1){
				Data * data = m_cur_block->alloc(size + sizeof(Data));

				if(data){
					m_used += size;
					m_data_blocks++;

					data->m_type = type;
					data->m_block_size = m_cur_block->m_block_size;
					data->m_mark = false;
					data->m_count = size;

					if(m_gc_phase == Running)
						DO_TRACEGC printf("alloc return %p\n", data->m_data);

					return data->m_data;
				}

				if(m_empty_blocks.empty())
					alloc_chunk();

				m_cur_block = m_empty_blocks.back();
				m_empty_blocks.pop_back();
			}
			return NULL;
		}

		void alloc_chunk(unsigned int size = 0){
			if(size)
				size = ceil_power2(size);
			else
				size = 1<<CHUNK_SIZE;

			Block * b = (Block *)mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);

			printf("alloc chunk %p, %i zeros\n", b, count_bottom_zeros4((uintptr_t)b));

			assert(count_bottom_zeros4((uintptr_t)b) >= BLOCK_SIZE); //make sure blocks will be properly aligned

			m_alloced += size;

			Chunk c;
			c.init(size, b);

			m_chunks.push_back(c);

			for(Block * i = b; i != c.end(); i++){
				i->init(BLOCK_SIZE);
				m_empty_blocks.push_back(i);
			}
		}

	public:
		Markcompact()
		 : m_cur_block(NULL), m_gc_phase(Running), m_alloced(0), m_used(0), m_data_blocks(0), m_next_gc(0.9*(1<<CHUNK_SIZE))
		{

			alloc_chunk();

			m_cur_block = m_empty_blocks.back();
			m_empty_blocks.pop_back();

		}

		template <typename tObj>
		tObj *alloc(size_t extra, uint16_t type)
		{
			return reinterpret_cast<tObj*>(next(sizeof(tObj) + extra, type));
		}

		template <typename tObj>
		bool validate(tObj * from)
		{
			if(m_gc_phase != Running)
				return true;
			else
				return (Data::ptr_for(from)->m_mark == false);
		}

		template <typename tObj>
		bool mark(tObj ** from)
		{
			Data * d = Data::ptr_for(*from);
			switch(m_gc_phase)
			{
			case Running:
				assert(m_gc_phase != Running); //shouldn't be calling mark when not in gc mode
			case Marking: {
				if(d->m_mark)
					return false;

				d->m_mark = true;

				m_data_blocks++;
				m_used += d->m_count;

				Block * b = d->block();
				if(!b->m_mark)
				{
					b->m_mark = true;
					b->m_in_use = 0;
				}
				b->m_in_use += d->m_count;

				gc_scan(*from);

				return false;
			}
			case Updating: {
				tObj * to = (tObj*)forward.get(d);

				bool ret = (to == *from);
				if(ret)
				{
					*from = to;
					d = Data::ptr_for(to);
				}

				if(d->m_mark)
				{
					d->m_mark = false;
					gc_scan(*from);
				}

				return ret;
			}
			}
		}

		// make sure this object is ready to be read from
		template <typename tObj>
		void read_barrier(tObj * obj) { }

		// tell the GC that obj will contain a reference to the object pointed to by ptr
		template <typename tObj, typename tPtr>
		void write_barrier(tObj * obj, tPtr * ptr) { }

		// now is a valid time to stop the world
		void safe_point() {
			if(m_next_gc < m_used)
				collect();
		}

		void register_root(GCRoot *root);
		void unregister_root(GCRoot *root);
	};
}

<|endoftext|>


<commit_before>#include "parser.h"
#include <QFileInfoList>
#include <iostream>
#include <QString>

#ifdef DEBUG
#include <QDebug>
#endif

Parser::Parser(int argc, char **argv)
    : itsArgc(argc)
    , itsArgv(argv)
    , itsDir(new QDir)
    , itsOptions(NONE)
{
}

void Parser::applyOptions()
{
    parseOptions();
#ifdef DEBUG
    qDebug() << "getCollectedOptions() =" << getCollectedOptions();
    qDebug() << "(int)getCollectedOptions() =" << (int)getCollectedOptions();
#endif
    switcher(getCollectedOptions());
}

void Parser::parseToFile()
{
    dirFilters();

    itsDir->setSorting(QDir::Name | QDir::DirsLast | QDir::Type);

    if(!itsDir->exists(itsArgv[1]))
    {
        std::cout << "EROR: path to list don't exist\n";
        return;
    }

    itsDir->cd(itsArgv[1]);

    QFile file;
    QFileInfo info;

    file.setFileName(itsArgv[2]);
    info.setFile(file);

    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        std::cout << "ERROR opening file:" << qPrintable(file.fileName());
        return;
    }

    QTextStream out(&file);
    out << itsArgv[1] << ":" << "\n";

    QString filePath = info.absoluteFilePath();

    if(itsOptions.testFlag(RECURSIVE))
    {
        recursive(filePath, out);
    }
    else
    {
        notRecursive(filePath, out);
    }

    QString p = info.filePath();
    QString n = info.fileName();

    std::cout << "\nSaving file: " << qPrintable(info.fileName())
              << " into "
              << qPrintable(p.remove(p.size() - n.size(), p.size() - 1))
              << std::endl;

    file.close();
}

void Parser::parseToConsole()
{

    dirFilters();

    itsDir->setSorting(QDir::Name | QDir::DirsLast | QDir::Type);

    if(!itsDir->exists(itsArgv[1]))
    {
        std::cout << "EROR: path to list don't exist\n";
        return;
    }

    itsDir->cd(itsArgv[1]);
    std::cout << itsArgv[1] << ":" << std::endl;

    if(itsOptions.testFlag(RECURSIVE))
    {
        recursive(itsDir->absolutePath());
    }
    else
    {
        notRecursive(itsDir->absolutePath());
    }
}

void Parser::help()
{
    qDebug() << "usage:\t[--help]\n";
    qDebug() << "   or:\t<path to list> [options]\n";
    qDebug() << "   or:\t<path to list> <path and file name to save results> [options]\n";
    qDebug() << "options:\n";
    qDebug() << "\t-d\tshow directories\n";
    qDebug() << "\t-h\thide output to console\n";
    qDebug() << "\t-r\trecursively listing\n";
    qDebug() << "\t-s\tshow hidden files\n";
    qDebug() << "\t-a\tlist absolute paths\n";
    qDebug() << "\t--ext:\"*.ext1, *.ext2,*.ext3 *.ext4\"\n\t\tcreate mask on listing files extensions\n";
    qDebug() << "\t--f:\"^fileName1, ^fileName2,^fileName3 ^fileName4\"\n\t\tcreate mask on listing file names\n";
    qDebug() << "Ctrl+C to skip\n";
}

void Parser::dirFilters()
{
    if(itsOptions.testFlag(HIDENFILES))
    {
        itsDir->setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks | QDir::Dirs | QDir::NoDotAndDotDot);
    }
    else
    {
        itsDir->setFilter(QDir::Files | QDir::NoSymLinks | QDir::Dirs | QDir::NoDotAndDotDot);
    }
}

void Parser::recursive(const QString &dirPath)
{
    itsDir->cd(dirPath);

    dirFilters();

    QFileInfoList list = itsDir->entryInfoList();

    for(int iList = 0; iList < list.size(); ++iList)
    {
        QFileInfo fileInfo = list.at(iList);
        QString filePath = fileInfo.absoluteFilePath();

        if(fileInfo.isDir())
        {
            if(itsOptions.testFlag(SHOWDIRS))
            {
                if(itsOptions.testFlag(ABSOLUTEPATH))
                {
                    QString temp = filePath;
                    std::cout << std::endl << "." << qPrintable(temp.remove(0, QString(itsArgv[1]).size())) << ":" << std::endl;
                }
                else
                {
                    std::cout << std::endl << qPrintable(filePath) << ":" << std::endl;
                }
            }
            recursive(filePath);
        }
        else
        {
            std::cout << qPrintable(fileInfo.fileName()) << std::endl;
        }
    }
}

void Parser::recursive(const QString &dirPath, QTextStream &out)
{
    itsDir->cd(dirPath);

    QFileInfoList list = itsDir->entryInfoList();

    for(int iList = 0; iList < list.size(); ++iList)
    {
        QFileInfo fileInfo = list.at(iList);
        QString filePath = fileInfo.absoluteFilePath();

        if(fileInfo.isDir())
        {
            if(itsOptions.testFlag(SHOWDIRS))
            {
                if(itsOptions.testFlag(ABSOLUTEPATH))
                {
                    QString temp = filePath;
                    out << "\n" << "." << temp.remove(0, QString(itsArgv[1]).size()) << ":\n";
                }
                else
                {
                    out << "\n" << filePath << ":" << "\n";
                }
            }
            recursive(filePath, out);
        }
        else
        {
            out << fileInfo.fileName() << "\n";
        }
    }
}

void Parser::notRecursive(const QString &dirPath)
{
    itsDir->cd(dirPath);

    dirFilters();

    QFileInfoList list = itsDir->entryInfoList();

    for(int iList = 0; iList < list.size(); ++iList)
    {
        QFileInfo fileInfo = list.at(iList);
        QString filePath = fileInfo.absoluteFilePath();

        if(fileInfo.isDir())
        {
            if(itsOptions.testFlag(SHOWDIRS))
            {
                std::cout << std::endl << qPrintable(filePath) << ":" << std::endl;
            }
        }
        else
        {
            std::cout << qPrintable(fileInfo.fileName()) << std::endl;
        }
    }
}

void Parser::notRecursive(const QString &dirPath, QTextStream &out)
{
    itsDir->cd(dirPath);

    dirFilters();

    QFileInfoList list = itsDir->entryInfoList();

    for(int iList = 0; iList < list.size(); ++iList)
    {
        QFileInfo fileInfo = list.at(iList);
        QString filePath = fileInfo.absoluteFilePath();

        if(fileInfo.isDir())
        {
            if(itsOptions.testFlag(SHOWDIRS))
            {
                out << "\n" << filePath << ":" << "\n";
            }
        }
        else
        {
            out << qPrintable(fileInfo.fileName()) << "\n";
        }
    }
}

void Parser::switcher(Parser::OPTIONS opt)
{
    if(opt.testFlag(HELP))
    {
        help();
        return;
    }
    if(!opt.testFlag(HIDECONSOLE))
    {
        parseToConsole();
    }

    // if save to file
    if(itsDir->isAbsolutePath(itsArgv[2]))
    {
        parseToFile();
    }
}

Parser::OPTIONS Parser::parseOptions()
{
    QString str;
    for(int i = 1; i < itsArgc; ++i)
    {
        str.append(QString(itsArgv[i]));
    }
#ifdef DEBUG
    qDebug() << "str:" << str;
#endif

    QVector <QStringList> opts = polyOptParser(str);

    if(opts.at(0).contains("help")) collectorOptions(HELP);
    if(opts.at(1).contains("d")) collectorOptions(SHOWDIRS);
    if(opts.at(1).contains("h")) collectorOptions(HIDECONSOLE);
    if(opts.at(1).contains("r")) collectorOptions(RECURSIVE);
    if(opts.at(1).contains("s")) collectorOptions(HIDENFILES);
    if(opts.at(1).contains("a")) collectorOptions(ABSOLUTEPATH);

    if(!opts.at(2).isEmpty())
    {
        itsDir->setNameFilters(opts.at(2));
#ifdef DEBUG
        qDebug() << "opts.at(2)" << opts.at(2);
#endif
    }
    if(!opts.at(3).isEmpty())
    {
        itsDir->setNameFilters(opts.at(3));
#ifdef DEBUG
        qDebug() << "opts.at(3)" << opts.at(3);
#endif
    }

    return getCollectedOptions();
}

void Parser::collectorOptions(Parser::OPTIONS opt)
{
    itsOptions = itsOptions | opt;
#ifdef DEBUG
    qDebug() << "itsOptions =" << QString::number(itsOptions);
#endif
}

Parser::OPTIONS Parser::getCollectedOptions() const
{
    return itsOptions;
}

QVector <QStringList> Parser::polyOptParser(QString str)
{
    QString ext = QString("(\\*\\.\\w+,?\\s?)");
    QString f = QString("(\\^\\w+,?\\s?)");
    QString opt_opt = QString("(-[hrdsa]+[^elp]+)");
    QString opt_help = QString("(--help)");
    QString opt_ext = QString("(--ext:\"%1+\")").arg(ext);
    QString opt_f = QString("(--f:\"%1+\")").arg(f);
    QString opt = QString("%1?\\s?%2?\\s?%3?%4?\\s?").arg(opt_help).arg(opt_opt).arg(opt_ext).arg(opt_f);

    QRegExp rx_ext(ext);
    QRegExp rx_f(f);
    QRegExp rx_opt_opt(opt_opt);
    QRegExp rx_opt_ext(opt_ext);
    QRegExp rx_opt_f(opt_f);
    QRegExp rx_opt_help(opt_help);
    QRegExp rx_opt(opt);

    QStringList listOpt;
    QStringList listExt;
    QStringList listFiles;
    QStringList listHelp;

    int pos = 0;

    QString stringExt;
    QString stringFiles;
    QString stringOpt;
    QString stringHelp;

    if((rx_opt.indexIn(str, 0) != -1) && (rx_opt_help.indexIn(str, 0) == -1))
    {
        if(rx_opt_opt.indexIn(str, 0) != -1)
        {
            while((pos = rx_opt_opt.indexIn(str, pos)) != -1)
            {
                stringOpt = rx_opt_opt.cap(1);
                listOpt.append(stringOpt);
                pos += rx_opt_opt.matchedLength();
            }
        }
        if(rx_opt_ext.indexIn(str, 0) !=-1)
        {
            pos = rx_opt_ext.indexIn(str, 0);

            while (((pos = rx_ext.indexIn(str, pos)) != -1) &&
                   ((pos < rx_opt_f.indexIn(str, 0)) || (rx_opt_f.indexIn(str, 0) == -1)))
            {
                stringExt = rx_ext.cap(1);
                listExt.append(stringExt);
                pos += rx_ext.matchedLength();
            }
        }
        if(rx_opt_f.indexIn(str, 0) !=-1)
        {
            pos = rx_opt_f.indexIn(str, 0);
            while ((pos = rx_f.indexIn(str, pos)) != -1)
            {
                stringFiles = rx_f.cap(1);
                listFiles.append(stringFiles);
                pos += rx_f.matchedLength();
            }
        }
    }
    else if((rx_opt_help.indexIn(str, 0) != -1) && (rx_opt.indexIn(str, 0) != -1))
    {
        stringHelp = rx_opt_help.cap(0);
        listHelp.append(stringHelp);
    }
    else
    {
        qDebug() << "Incorrect input options!";
    }

    QStringList sl;

    foreach (QString temp_str, listOpt) {
        sl.append(temp_str.replace(QRegExp("-"), "").split(QRegExp("(?=\\w)"), QString::SkipEmptyParts));
    }
    listOpt = sl;
    sl.clear();

    listOpt.removeDuplicates();

    if(!listOpt.isEmpty())
        qDebug() << "\nOptions:\n" << listOpt << "\n";
    else
        qDebug() << "\nEmpty Options\n";

    foreach (QString temp_str, listExt) {
        sl.append(temp_str.replace(QRegExp("[\\s,]"), ""));
    }
    listExt = sl;
    sl.clear();

    listExt.removeDuplicates();

    if(!listExt.isEmpty())
        qDebug() << "\nMask Extensions:\n" << listExt << "\n";
    else
        qDebug() << "\nEmpty Mask Extentions\n";

    foreach (QString temp_str, listFiles) {
        sl.append(temp_str.replace(QRegExp("[\\^\\s,]"), ""));
    }
    listFiles = sl;
    sl.clear();

    listFiles.removeDuplicates();

    if(!listFiles.isEmpty())
        qDebug() << "\nFiles Names:\n" << listFiles << "\n";
    else
        qDebug() << "\nEmpty Files Names\n";

    foreach (QString temp_str, listHelp)
    {
        sl.append(temp_str.remove(QRegExp("--")));
    }
    listHelp = sl;
    sl.clear();

    listHelp.removeDuplicates();

    if(!listHelp.isEmpty())
        qDebug() << "\nHelp:\n" << listHelp << "\n";
    else
        qDebug() << "\nEmpty Help\n";

    QVector <QStringList> list;

    list.append(listHelp); // 0
    list.append(listOpt);  // 1
    list.append(listExt);  // 2
    list.append(listFiles);// 3

#ifdef DEBUG
    qDebug() << "list.at(listHelp)" << list[0];
    qDebug() << "list.at(listOpt)" << list[1];
    qDebug() << "list.at(listExt)" << list[2];
    qDebug() << "list.at(listFiles)" << list[3];
#endif

    return list;
}
<commit_msg>Исправил опцию --ext. Исправил опцию -a (выводило наоборот). Сделал рефакторинг. Остались проблемы с --f (хотя уже выводит опции).<commit_after>#include "parser.h"
#include <QFileInfoList>
#include <iostream>
#include <QString>

#ifdef DEBUG
#include <QDebug>
#endif

Parser::Parser(int argc, char **argv)
    : itsArgc(argc)
    , itsArgv(argv)
    , itsDir(new QDir)
    , itsOptions(NONE)
{
}

void Parser::applyOptions()
{
    parseOptions();
#ifdef DEBUG
    qDebug() << "getCollectedOptions() =" << getCollectedOptions();
    qDebug() << "(int)getCollectedOptions() =" << (int)getCollectedOptions();
#endif
    switcher(getCollectedOptions());
}

void Parser::parseToFile()
{
    dirFilters();

    if(!itsDir->exists(itsArgv[1]))
    {
        std::cout << "EROR: path to list don't exist\n";
        return;
    }

    itsDir->cd(itsArgv[1]);

    QFile file;
    QFileInfo info;

    file.setFileName(itsArgv[2]);
    info.setFile(file);

    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        std::cout << "ERROR opening file:" << qPrintable(file.fileName());
        return;
    }

    QTextStream out(&file);
    out << itsArgv[1] << ":" << "\n";

    QString filePath = info.absoluteFilePath();

    if(itsOptions.testFlag(RECURSIVE))
    {
        recursive(filePath, out);
    }
    else
    {
        notRecursive(filePath, out);
    }

    QString p = info.filePath();
    QString n = info.fileName();

    std::cout << "\nSaving file: " << qPrintable(info.fileName())
              << " into "
              << qPrintable(p.remove(p.size() - n.size(), p.size() - 1))
              << std::endl;

    file.close();
}

void Parser::parseToConsole()
{

    dirFilters();

    if(!itsDir->exists(itsArgv[1]))
    {
        std::cout << "EROR: path to list don't exist\n";
        return;
    }

    itsDir->cd(itsArgv[1]);
    std::cout << itsArgv[1] << ":" << std::endl;

    if(itsOptions.testFlag(RECURSIVE))
    {
        recursive(itsDir->absolutePath());
    }
    else
    {
        notRecursive(itsDir->absolutePath());
    }
}

void Parser::help()
{
    qDebug() << "usage:\t[--help]\n";
    qDebug() << "   or:\t<path to list> [options]\n";
    qDebug() << "   or:\t<path to list> <path and file name to save results> [options]\n";
    qDebug() << "options:\n";
    qDebug() << "\t-d\tshow directories\n";
    qDebug() << "\t-h\thide output to console\n";
    qDebug() << "\t-r\trecursively listing\n";
    qDebug() << "\t-s\tshow hidden files\n";
    qDebug() << "\t-a\tlist absolute paths\n";
    qDebug() << "\t--ext:\"*.ext1, *.ext2,*.ext3 *.ext4\"\n\t\tcreate mask on listing files extensions\n";
    qDebug() << "\t--f:\"^fileName1, ^fileName2,^fileName3 ^fileName4\"\n\t\tcreate mask on listing file names\n";
    qDebug() << "Ctrl+C to skip\n";
}

void Parser::dirFilters()
{
    if(itsOptions.testFlag(HIDENFILES))
    {
        itsDir->setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks | QDir::Dirs | QDir::NoDotAndDotDot | QDir::AllDirs);
    }
    else
    {
        itsDir->setFilter(QDir::Files | QDir::NoSymLinks | QDir::Dirs | QDir::NoDotAndDotDot | QDir::AllDirs);
    }
    itsDir->setSorting(QDir::Name | QDir::DirsLast | QDir::Type);
}

void Parser::recursive(const QString &dirPath)
{
    itsDir->cd(dirPath);

    dirFilters();

    QFileInfoList list = itsDir->entryInfoList();

    for(int iList = 0; iList < list.size(); ++iList)
    {
        QFileInfo fileInfo = list.at(iList);
        QString filePath = fileInfo.absoluteFilePath();

        if(fileInfo.isDir())
        {
            if(itsOptions.testFlag(SHOWDIRS))
            {
                if(itsOptions.testFlag(ABSOLUTEPATH))
                {
                    std::cout << std::endl << qPrintable(filePath) << ":" << std::endl;
                }
                else
                {
                    QString temp = filePath;
                    std::cout << std::endl << ".." << qPrintable(temp.remove(0, QString(itsArgv[1]).size())) << ":" << std::endl;
                }
            }
            recursive(filePath);
        }
        else
        {
            std::cout << qPrintable(fileInfo.fileName()) << std::endl;
        }
    }
}

void Parser::recursive(const QString &dirPath, QTextStream &out)
{
    itsDir->cd(dirPath);

    QFileInfoList list = itsDir->entryInfoList();

    for(int iList = 0; iList < list.size(); ++iList)
    {
        QFileInfo fileInfo = list.at(iList);
        QString filePath = fileInfo.absoluteFilePath();
        itsDir->setNameFilters(QStringList() << "*");

        if(fileInfo.isDir())
        {
            if(itsOptions.testFlag(SHOWDIRS))
            {
                if(itsOptions.testFlag(ABSOLUTEPATH))
                {
                    out << "\n" << filePath << ":" << "\n";
                }
                else
                {
                    QString temp = filePath;
                    out << "\n" << ".." << temp.remove(0, QString(itsArgv[1]).size()) << ":\n";
                }
            }
            recursive(filePath, out);
        }
        else
        {
            out << fileInfo.fileName() << "\n";
        }
    }
}

void Parser::notRecursive(const QString &dirPath)
{
    itsDir->cd(dirPath);

    dirFilters();

    QFileInfoList list = itsDir->entryInfoList();

    for(int iList = 0; iList < list.size(); ++iList)
    {
        QFileInfo fileInfo = list.at(iList);
        QString filePath = fileInfo.absoluteFilePath();

        if(fileInfo.isDir())
        {
            if(itsOptions.testFlag(SHOWDIRS))
            {
                std::cout << std::endl << qPrintable(filePath) << ":" << std::endl;
            }
        }
        else
        {
            std::cout << qPrintable(fileInfo.fileName()) << std::endl;
        }
    }
}

void Parser::notRecursive(const QString &dirPath, QTextStream &out)
{
    itsDir->cd(dirPath);

    dirFilters();

    QFileInfoList list = itsDir->entryInfoList();

    for(int iList = 0; iList < list.size(); ++iList)
    {
        QFileInfo fileInfo = list.at(iList);
        QString filePath = fileInfo.absoluteFilePath();

        if(fileInfo.isDir())
        {
            if(itsOptions.testFlag(SHOWDIRS))
            {
                out << "\n" << filePath << ":" << "\n";
            }
        }
        else
        {
            out << qPrintable(fileInfo.fileName()) << "\n";
        }
    }
}

void Parser::switcher(Parser::OPTIONS opt)
{
    if(opt.testFlag(HELP))
    {
        help();
        return;
    }
    if(!opt.testFlag(HIDECONSOLE))
    {
        parseToConsole();
    }

    // if save to file
    if(itsDir->isAbsolutePath(itsArgv[2]))
    {
        parseToFile();
    }
}

Parser::OPTIONS Parser::parseOptions()
{
    QString str;
    for(int i = 1; i < itsArgc; ++i)
    {
        str.append(QString(itsArgv[i]));
    }
#ifdef DEBUG
    qDebug() << "str:" << str;
#endif

    QVector <QStringList> opts = polyOptParser(str);

    if(opts.at(0).contains("help")) collectorOptions(HELP);
    if(opts.at(1).contains("d")) collectorOptions(SHOWDIRS);
    if(opts.at(1).contains("h")) collectorOptions(HIDECONSOLE);
    if(opts.at(1).contains("r")) collectorOptions(RECURSIVE);
    if(opts.at(1).contains("s")) collectorOptions(HIDENFILES);
    if(opts.at(1).contains("a")) collectorOptions(ABSOLUTEPATH);

    if(!opts.at(2).isEmpty())
    {
        itsDir->setNameFilters(opts.at(2));

#ifdef DEBUG
        qDebug() << "opts.at(2)" << opts.at(2);
#endif
    }
    if(!opts.at(3).isEmpty())
    {
        itsDir->setNameFilters(opts.at(3));
#ifdef DEBUG
        qDebug() << "opts.at(3)" << opts.at(3);
#endif
    }

    return getCollectedOptions();
}

void Parser::collectorOptions(Parser::OPTIONS opt)
{
    itsOptions = itsOptions | opt;
#ifdef DEBUG
    qDebug() << "itsOptions =" << QString::number(itsOptions);
#endif
}

Parser::OPTIONS Parser::getCollectedOptions() const
{
    return itsOptions;
}

QVector <QStringList> Parser::polyOptParser(QString str)
{
    QString ext = QString("(\\*\\.\\w+,?\\s?)");
    QString f = QString("(\\^\\w+,?\\s?)");
    QString opt_opt = QString("(-[hrdsa]+[^elp]+)");
    QString opt_help = QString("(--help)");
    QString opt_ext = QString("(--ext:\"%1+\")").arg(ext);
    QString opt_f = QString("(--f:\"%1+\")").arg(f);
    QString opt = QString("%1?\\s?%2?\\s?%3?%4?\\s?").arg(opt_help).arg(opt_opt).arg(opt_ext).arg(opt_f);

    QRegExp rx_ext(ext);
    QRegExp rx_f(f);
    QRegExp rx_opt_opt(opt_opt);
    QRegExp rx_opt_ext(opt_ext);
    QRegExp rx_opt_f(opt_f);
    QRegExp rx_opt_help(opt_help);
    QRegExp rx_opt(opt);

    QStringList listOpt;
    QStringList listExt;
    QStringList listFiles;
    QStringList listHelp;

    int pos = 0;

    QString stringExt;
    QString stringFiles;
    QString stringOpt;
    QString stringHelp;

    if((rx_opt.indexIn(str, 0) != -1) && (rx_opt_help.indexIn(str, 0) == -1))
    {
        if(rx_opt_opt.indexIn(str, 0) != -1)
        {
            while((pos = rx_opt_opt.indexIn(str, pos)) != -1)
            {
                stringOpt = rx_opt_opt.cap(1);
                listOpt.append(stringOpt);
                pos += rx_opt_opt.matchedLength();
            }
        }
        if(rx_opt_ext.indexIn(str, 0) !=-1)
        {
            pos = rx_opt_ext.indexIn(str, 0);

            while (((pos = rx_ext.indexIn(str, pos)) != -1) &&
                   ((pos < rx_opt_f.indexIn(str, 0)) || (rx_opt_f.indexIn(str, 0) == -1)))
            {
                stringExt = rx_ext.cap(1);
                listExt.append(stringExt);
                pos += rx_ext.matchedLength();
            }
        }
#ifdef DEBUG
        qDebug() << "rx_opt_f.indexIn(str, 0):" << rx_opt_f.indexIn(str, 0);
#endif
        if(rx_opt_f.indexIn(str, 0) !=-1)
        {
            pos = rx_opt_f.indexIn(str, 0);
            while ((pos = rx_f.indexIn(str, pos)) != -1)
            {
                stringFiles = rx_f.cap(1);
                listFiles.append(stringFiles);
                pos += rx_f.matchedLength();
#ifdef DEBUG
                qDebug() << "stringFiles:" << stringFiles;
#endif
            }
        }
    }
    else if((rx_opt_help.indexIn(str, 0) != -1) && (rx_opt.indexIn(str, 0) != -1))
    {
        stringHelp = rx_opt_help.cap(0);
        listHelp.append(stringHelp);
    }
    else
    {
        qDebug() << "Incorrect input options!";
    }

    QStringList sl;

    foreach (QString temp_str, listOpt) {
        sl.append(temp_str.replace(QRegExp("-"), "").split(QRegExp("(?=\\w)"), QString::SkipEmptyParts));
    }
    listOpt = sl;
    sl.clear();

    listOpt.removeDuplicates();

    if(!listOpt.isEmpty())
        qDebug() << "\nOptions:\n" << listOpt << "\n";
    else
        qDebug() << "\nEmpty Options\n";

    foreach (QString temp_str, listExt) {
        sl.append(temp_str.replace(QRegExp("[\\s,]"), ""));
    }
    listExt = sl;
    sl.clear();

    listExt.removeDuplicates();

    if(!listExt.isEmpty())
        qDebug() << "\nMask Extensions:\n" << listExt << "\n";
    else
        qDebug() << "\nEmpty Mask Extentions\n";

    foreach (QString temp_str, listFiles) {
        sl.append(temp_str.replace(QRegExp("[\\^\\s,]"), ""));
    }
    listFiles = sl;
    sl.clear();

    listFiles.removeDuplicates();

    if(!listFiles.isEmpty())
        qDebug() << "\nFiles Names:\n" << listFiles << "\n";
    else
        qDebug() << "\nEmpty Files Names\n";

    foreach (QString temp_str, listHelp)
    {
        sl.append(temp_str.remove(QRegExp("--")));
    }
    listHelp = sl;
    sl.clear();

    listHelp.removeDuplicates();

    if(!listHelp.isEmpty())
        qDebug() << "\nHelp:\n" << listHelp << "\n";
    else
        qDebug() << "\nEmpty Help\n";

    QVector <QStringList> list;

    list.append(listHelp); // 0
    list.append(listOpt);  // 1
    list.append(listExt);  // 2
    list.append(listFiles);// 3

#ifdef DEBUG
    qDebug() << "list.at(listHelp)" << list[0];
    qDebug() << "list.at(listOpt)" << list[1];
    qDebug() << "list.at(listExt)" << list[2];
    qDebug() << "list.at(listFiles)" << list[3];
#endif

    return list;
}
<|endoftext|>