<commit_before>#ifndef TSA_VU8_DETAIL_FROM_V8_HPP
#define TSA_VU8_DETAIL_FROM_V8_HPP

#include <vu8/detail/ConvertibleString.hpp>

#include <v8.h>

#include <string>
#include <stdexcept>
#include <vector>

namespace vu8 { namespace detail {

typedef v8::Handle<v8::Value> ValueHandle;

template <class T>
struct FromV8;

template <>
struct FromV8<std::string> {
    static inline std::string exec(ValueHandle value) {
        if (! value->IsString())
            throw std::runtime_error("cannot make string from non-string type");

        v8::String::Utf8Value str(value);
        return *str;
    }
};

template <>
struct FromV8<ConvertibleString> {
    static inline ConvertibleString exec(ValueHandle value) {
        if (! value->IsString())
            throw std::runtime_error("cannot make string from non-string type");

        v8::String::Utf8Value str(value);
        return *str;
    }
};

template <>
struct FromV8< v8::Handle<v8::Function> > {
    static inline v8::Handle<v8::Function> exec(ValueHandle value) {
        if (! value->IsFunction())
            throw std::runtime_error("expected javascript function");

        return value.As<v8::Function>();
    }
};

template <>
struct FromV8<int32_t> {
    static inline int32_t exec(ValueHandle value) {
        if (! value->IsNumber())
            throw std::runtime_error("expected javascript number");

        return value->ToInt32()->Value();
    }
};

template <>
struct FromV8<uint32_t> {
    static inline uint32_t exec(ValueHandle value) {
        if (! value->IsNumber())
            throw std::runtime_error("expected javascript number");

        return value->ToUint32()->Value();
    }
};

template <>
struct FromV8<int64_t> {
    static inline int64_t exec(ValueHandle value) {
        if (! value->IsNumber())
            throw std::runtime_error("expected javascript number");

        return value->ToNumber()->Value();
    }
};

template <>
struct FromV8<uint64_t> {
    static inline uint64_t exec(ValueHandle value) {
        if (! value->IsNumber())
            throw std::runtime_error("expected javascript number");

        return value->ToNumber()->Value();
    }
};

template <class T, class A>
struct FromV8< std::vector<T, A> > {
    static inline std::vector<T, A> exec(ValueHandle value) {
        if (! value->IsArray())
            throw std::runtime_error("expected javascript array");

        v8::Array *array = v8::Array::Cast(*value);
        std::vector<T, A> result;
        for (uint32_t i = 0; i < array->Length(); ++i) {
            v8::Local<v8::Value> obj = array->Get(i);
            result.push_back(FromV8<T>::exec(obj));
        }
        return result;
    }
};

template <>
struct FromV8<ValueHandle> {
    static inline ValueHandle exec(ValueHandle value) {
        return value;
    }
};

} }
#endif
<commit_msg>can extract object pointers from v8 handles now<commit_after>#ifndef TSA_VU8_DETAIL_FROM_V8_HPP
#define TSA_VU8_DETAIL_FROM_V8_HPP

#include <vu8/detail/ConvertibleString.hpp>

#include <v8.h>

#include <string>
#include <stdexcept>
#include <vector>

namespace vu8 { namespace detail {

typedef v8::Handle<v8::Value> ValueHandle;

template <class T>
struct FromV8;

template <>
struct FromV8<std::string> {
    static inline std::string exec(ValueHandle value) {
        if (! value->IsString())
            throw std::runtime_error("cannot make string from non-string type");

        v8::String::Utf8Value str(value);
        return *str;
    }
};

template <>
struct FromV8<ConvertibleString> {
    static inline ConvertibleString exec(ValueHandle value) {
        if (! value->IsString())
            throw std::runtime_error("cannot make string from non-string type");

        v8::String::Utf8Value str(value);
        return *str;
    }
};

template <>
struct FromV8< v8::Handle<v8::Function> > {
    static inline v8::Handle<v8::Function> exec(ValueHandle value) {
        if (! value->IsFunction())
            throw std::runtime_error("expected javascript function");

        return value.As<v8::Function>();
    }
};

template <>
struct FromV8<int32_t> {
    static inline int32_t exec(ValueHandle value) {
        if (! value->IsNumber())
            throw std::runtime_error("expected javascript number");

        return value->ToInt32()->Value();
    }
};

template <>
struct FromV8<uint32_t> {
    static inline uint32_t exec(ValueHandle value) {
        if (! value->IsNumber())
            throw std::runtime_error("expected javascript number");

        return value->ToUint32()->Value();
    }
};

template <>
struct FromV8<int64_t> {
    static inline int64_t exec(ValueHandle value) {
        if (! value->IsNumber())
            throw std::runtime_error("expected javascript number");

        return value->ToNumber()->Value();
    }
};

template <>
struct FromV8<uint64_t> {
    static inline uint64_t exec(ValueHandle value) {
        if (! value->IsNumber())
            throw std::runtime_error("expected javascript number");

        return value->ToNumber()->Value();
    }
};

template <class T, class A>
struct FromV8< std::vector<T, A> > {
    static inline std::vector<T, A> exec(ValueHandle value) {
        if (! value->IsArray())
            throw std::runtime_error("expected javascript array");

        v8::Array *array = v8::Array::Cast(*value);
        std::vector<T, A> result;
        for (uint32_t i = 0; i < array->Length(); ++i) {
            v8::Local<v8::Value> obj = array->Get(i);
            result.push_back(FromV8<T>::exec(obj));
        }
        return result;
    }
};

template <>
struct FromV8<ValueHandle> {
    static inline ValueHandle exec(ValueHandle value) {
        return value;
    }
};

////////////////////////////////////////////////////////////////////////////
// extracting classes
template <class T>
struct FromV8Ptr {
    static inline T exec(ValueHandle value) {
        if (! value->IsObject())
            throw std::runtime_error("expected object");

        v8::Local<v8::Object> obj = value->ToObject();

        if (! obj->InternalFieldCount())
            throw std::runtime_error("expected c++ wrapped object");

        return static_cast<T>(obj->GetPointerFromInternalField(0));
    }
};

template <class T>
struct FromV8<T *> : FromV8Ptr<T *> {};

template <class T>
struct FromV8<T const *> : FromV8Ptr<T const *> {};

} }
#endif
<|endoftext|>


<commit_before>#include <yuni/yuni.h>
#include <yuni/core/noncopyable.h>
#include <yuni/io/file.h>
#include <yuni/core/system/console.h>
#include <yuni/core/getopt.h>
#include <yuni/io/directory.h>
#include <yuni/io/directory/info.h>
#include <yuni/datetime/timestamp.h>
#include <yuni/core/logs/logs.h>
#include "nany/nany.h"
#include <algorithm>
#include <yuni/datetime/timestamp.h>
#include <iostream>
#include <vector>

using namespace Yuni;

namespace {

struct {
	//! List of filenames to verify
	std::vector<String> filenames;
	// no colors
	bool noColors = false;
	// Result expected from filename convention
	bool useFilenameConvention = false;
}
settings;

template<class LeftType = Logs::NullDecorator>
struct ParseVerbosity : public LeftType {
	template<class Handler, class VerbosityType, class O>
	void internalDecoratorAddPrefix(O& out, const AnyString& s) const {
		// Write the verbosity to the output
		if (VerbosityType::hasName) {
			AnyString name{VerbosityType::Name()};
			if (s.empty()) {
			}
			else if (name == "info") {
				if (Handler::colorsAllowed)
					System::Console::TextColor<System::Console::yellow>::Set(out);
				#ifndef YUNI_OS_WINDOWS
				out << "      \u2713  ";
				#else
				out << "      >  ";
				#endif
				if (Handler::colorsAllowed)
					System::Console::TextColor<System::Console::white>::Set(out);
				out << "parsing";
				if (Handler::colorsAllowed)
					System::Console::ResetTextColor(out);
			}
			else if (name == "error") {
				if (Handler::colorsAllowed)
					System::Console::TextColor<System::Console::red>::Set(out);
				out << "  FAILED ";
				if (Handler::colorsAllowed)
					System::Console::TextColor<System::Console::white>::Set(out);
				out << "parsing";
				if (Handler::colorsAllowed)
					System::Console::ResetTextColor(out);
			}
			else if (name == "warning") {
				if (Handler::colorsAllowed)
					System::Console::TextColor<System::Console::yellow>::Set(out);
				out << "  {warn} ";
				if (Handler::colorsAllowed)
					System::Console::TextColor<System::Console::white>::Set(out);
				out << "parsing";
				if (Handler::colorsAllowed)
					System::Console::ResetTextColor(out);
			}
			else {
				// Set Color
				if (Handler::colorsAllowed && VerbosityType::color != System::Console::none)
					System::Console::TextColor<VerbosityType::color>::Set(out);
				// The verbosity
				VerbosityType::AppendName(out);
				// Reset Color
				if (Handler::colorsAllowed && VerbosityType::color != System::Console::none)
					System::Console::ResetTextColor(out);
			}
		}
		// Transmit the message to the next decorator
		LeftType::template internalDecoratorAddPrefix<Handler, VerbosityType,O>(out, s);
	}
}; // struct VerbosityLevel

using Logging = Logs::Logger<Logs::StdCout<>, ParseVerbosity<Logs::Message<>>>;
static Logging logs;

uint32_t fincCommonFolderLength(const std::vector<String>& filenames) {
	if (filenames.empty())
		return 0;
	auto& firstElement = filenames[0];
	const char sep = IO::Separator;
	uint32_t pos = 0;
	for (; ; ++pos) {
		for (size_t i = 0; i < filenames.size(); ++i) {
			auto& str = filenames[i];
			if (pos == firstElement.size())
				return pos;
			if (pos < str.size() and str[pos] != '\0' and str[pos] == firstElement[pos])
				continue;
			// back to the last sep
			while (pos > 0 && firstElement[--pos] != sep) {
			}
			return pos;
		}
	}
	return pos;
}

bool expandFilelist(std::vector<String>& list) {
	std::vector<String> filelist;
	filelist.reserve(512);
	String currentfile;
	currentfile.reserve(4096);
	for (auto& element: list) {
		IO::Canonicalize(currentfile, element);
		switch (IO::TypeOf(currentfile)) {
			case IO::typeFile: {
				filelist.emplace_back(currentfile);
				break;
			}
			case IO::typeFolder: {
				ShortString16 ext;
				IO::Directory::Info info(currentfile);
				auto end = info.recursive_file_end();
				for (auto i = info.recursive_file_begin(); i != end; ++i)
				{
					IO::ExtractExtension(ext, *i);
					if (ext == ".ny")
						filelist.emplace_back(i.filename());
				}
				break;
			}
			default: {
				logs.error() << "impossible to find '" << currentfile << "'";
				return false;
			}
		}
	}
	// for beauty in singled-threaded (and to always produce the same output)
	std::sort(filelist.begin(), filelist.end());
	list.swap(filelist);
	return true;
}

template<class F>
bool IterateThroughAllFiles(const std::vector<String>& filenames, const F& callback) {
	String currentfile;
	uint32_t testOK = 0;
	uint32_t testFAILED = 0;
	int64_t maxCheckDuration = 0;
	int64_t startTime = DateTime::NowMilliSeconds();
	for (auto& filename: filenames) {
		int64_t duration = 0;
		if (callback(filename, duration))
			++testOK;
		else
			++testFAILED;
		if (duration > maxCheckDuration)
			maxCheckDuration = duration;
	}
	int64_t endTime = DateTime::NowMilliSeconds();
	uint32_t total = testOK + testFAILED;
	if (total > 0) {
		int64_t duration = (endTime - startTime);
		String durationStr;
		durationStr << " (in " << duration << "ms, max: " << maxCheckDuration << "ms)";
		if (total > 1) {
			if (0 != testFAILED) {
				switch (total) {
					case 1:
						logs.warning() << "-- FAILED -- 1 file, +" << testOK << ", -" << testFAILED << durationStr;
						break;
					default:
						logs.warning() << "-- FAILED -- " << total << " files, +" << testOK << ", -" << testFAILED << durationStr;
				}
			}
			else
			{
				switch (total) {
					case 1:
						logs.info() << "success: 1 file, +" << testOK << ", -0" << durationStr;
						break;
					default:
						logs.info() << "success: " << total << " files, +" << testOK << ", -0" << durationStr;
				}
			}
		}
	}
	else
		logs.warning() << "no input file";
	return (0 == testFAILED);
}

bool batchCheckIfFilenamesConformToGrammar(std::vector<String>& filenames) {
	if (not expandFilelist(filenames))
		return false;
	auto commonFolder = (filenames.size() > 1 ? fincCommonFolderLength(filenames) : 0);
	if (0 != commonFolder)
		++commonFolder;
	return IterateThroughAllFiles(filenames, [&](const AnyString& file, int64_t& duration) -> bool {
		String barefile;
		IO::ExtractFileName(barefile, file);
		bool expected = true;
		bool canfail = false;
		if (settings.useFilenameConvention)
		{
			if (barefile.startsWith("ko-"))
				expected = false;
			if (barefile.find("-canfail-") < barefile.size())
				canfail = true;
		}
		// PARSE
		int64_t start = DateTime::NowMilliSeconds();
		bool success = (nytrue == nytry_parse_file_n(file.c_str(), file.size()));
		duration = DateTime::NowMilliSeconds() - start;
		success = (success == expected);
		if (success and duration < 300) {
			logs.info() << AnyString{file, commonFolder} << " [" << duration << "ms]";
		}
		else {
			if (not success) {
				if (not canfail)
					logs.error() << AnyString{file, commonFolder} << " [" << duration << "ms]";
				else
					logs.warning() << AnyString{file, commonFolder} << " [" << duration << "ms, can fail]";
			}
			else
				logs.error() << AnyString{file, commonFolder} << " [" << duration << "ms - time limit reached]";
			success = canfail;
		}
		return success;
	});
}

} // namespace

int main(int argc, char** argv)
{
	// parse the command
	{
		// The command line options parser
		GetOpt::Parser options;
		// Input files
		options.add(settings.filenames, 'i', "input", "Input files (or folders)");
		options.remainingArguments(settings.filenames);
		// --no-color
		options.addFlag(settings.noColors, ' ', "no-color", "Disable color output");
		// use filename convention
		options.addFlag(settings.useFilenameConvention, ' ', "use-filename-convention",
			"Use the filename to determine if the test should succeed or not (should succeed if starting with 'ok-'");
		// version
		bool optVersion = false;
		options.addFlag(optVersion, ' ', "version", "Display the version of the compiler and exit");
		// Ask to the parser to parse the command line
		if (not options(argc, argv)) {
			// The program should not continue here
			// The user may have requested the help or an error has happened
			// If an error has happened, the exit status should be different from 0
			if (options.errors()) {
				std::cerr << "Abort due to error\n";
				return EXIT_FAILURE;
			}
			return EXIT_SUCCESS;
		}

		if (optVersion) {
			std::cout << "0.0\n";
			return EXIT_SUCCESS;
		}
		if (settings.filenames.empty()) {
			std::cerr << argv[0] << ": no input file\n";
			return EXIT_FAILURE;
		}
	}
	// Print AST or check for Nany Grammar
	bool success = batchCheckIfFilenamesConformToGrammar(settings.filenames);
	return success ? EXIT_SUCCESS : EXIT_FAILURE;
}
<commit_msg>check-syntax: remove global variable 'settings'<commit_after>#include <yuni/yuni.h>
#include <yuni/core/noncopyable.h>
#include <yuni/io/file.h>
#include <yuni/core/system/console.h>
#include <yuni/core/getopt.h>
#include <yuni/io/directory.h>
#include <yuni/io/directory/info.h>
#include <yuni/datetime/timestamp.h>
#include <yuni/core/logs/logs.h>
#include "nany/nany.h"
#include <algorithm>
#include <yuni/datetime/timestamp.h>
#include <iostream>
#include <vector>

using namespace Yuni;

namespace {

struct Settings {
	//! List of filenames to verify
	std::vector<String> filenames;
	// no colors
	bool noColors = false;
	// Result expected from filename convention
	bool useFilenameConvention = false;
};

template<class LeftType = Logs::NullDecorator>
struct ParseVerbosity : public LeftType {
	template<class Handler, class VerbosityType, class O>
	void internalDecoratorAddPrefix(O& out, const AnyString& s) const {
		// Write the verbosity to the output
		if (VerbosityType::hasName) {
			AnyString name{VerbosityType::Name()};
			if (s.empty()) {
			}
			else if (name == "info") {
				if (Handler::colorsAllowed)
					System::Console::TextColor<System::Console::yellow>::Set(out);
				#ifndef YUNI_OS_WINDOWS
				out << "      \u2713  ";
				#else
				out << "      >  ";
				#endif
				if (Handler::colorsAllowed)
					System::Console::TextColor<System::Console::white>::Set(out);
				out << "parsing";
				if (Handler::colorsAllowed)
					System::Console::ResetTextColor(out);
			}
			else if (name == "error") {
				if (Handler::colorsAllowed)
					System::Console::TextColor<System::Console::red>::Set(out);
				out << "  FAILED ";
				if (Handler::colorsAllowed)
					System::Console::TextColor<System::Console::white>::Set(out);
				out << "parsing";
				if (Handler::colorsAllowed)
					System::Console::ResetTextColor(out);
			}
			else if (name == "warning") {
				if (Handler::colorsAllowed)
					System::Console::TextColor<System::Console::yellow>::Set(out);
				out << "  {warn} ";
				if (Handler::colorsAllowed)
					System::Console::TextColor<System::Console::white>::Set(out);
				out << "parsing";
				if (Handler::colorsAllowed)
					System::Console::ResetTextColor(out);
			}
			else {
				// Set Color
				if (Handler::colorsAllowed && VerbosityType::color != System::Console::none)
					System::Console::TextColor<VerbosityType::color>::Set(out);
				// The verbosity
				VerbosityType::AppendName(out);
				// Reset Color
				if (Handler::colorsAllowed && VerbosityType::color != System::Console::none)
					System::Console::ResetTextColor(out);
			}
		}
		// Transmit the message to the next decorator
		LeftType::template internalDecoratorAddPrefix<Handler, VerbosityType,O>(out, s);
	}
}; // struct VerbosityLevel

using Logging = Logs::Logger<Logs::StdCout<>, ParseVerbosity<Logs::Message<>>>;
static Logging logs;

uint32_t fincCommonFolderLength(const std::vector<String>& filenames) {
	if (filenames.empty())
		return 0;
	auto& firstElement = filenames[0];
	const char sep = IO::Separator;
	uint32_t pos = 0;
	for (; ; ++pos) {
		for (size_t i = 0; i < filenames.size(); ++i) {
			auto& str = filenames[i];
			if (pos == firstElement.size())
				return pos;
			if (pos < str.size() and str[pos] != '\0' and str[pos] == firstElement[pos])
				continue;
			// back to the last sep
			while (pos > 0 && firstElement[--pos] != sep) {
			}
			return pos;
		}
	}
	return pos;
}

bool expandFilelist(std::vector<String>& list) {
	std::vector<String> filelist;
	filelist.reserve(512);
	String currentfile;
	currentfile.reserve(4096);
	for (auto& element: list) {
		IO::Canonicalize(currentfile, element);
		switch (IO::TypeOf(currentfile)) {
			case IO::typeFile: {
				filelist.emplace_back(currentfile);
				break;
			}
			case IO::typeFolder: {
				ShortString16 ext;
				IO::Directory::Info info(currentfile);
				auto end = info.recursive_file_end();
				for (auto i = info.recursive_file_begin(); i != end; ++i)
				{
					IO::ExtractExtension(ext, *i);
					if (ext == ".ny")
						filelist.emplace_back(i.filename());
				}
				break;
			}
			default: {
				logs.error() << "impossible to find '" << currentfile << "'";
				return false;
			}
		}
	}
	// for beauty in singled-threaded (and to always produce the same output)
	std::sort(filelist.begin(), filelist.end());
	list.swap(filelist);
	return true;
}

template<class F>
bool IterateThroughAllFiles(const std::vector<String>& filenames, const F& callback) {
	String currentfile;
	uint32_t testOK = 0;
	uint32_t testFAILED = 0;
	int64_t maxCheckDuration = 0;
	int64_t startTime = DateTime::NowMilliSeconds();
	for (auto& filename: filenames) {
		int64_t duration = 0;
		if (callback(filename, duration))
			++testOK;
		else
			++testFAILED;
		if (duration > maxCheckDuration)
			maxCheckDuration = duration;
	}
	int64_t endTime = DateTime::NowMilliSeconds();
	uint32_t total = testOK + testFAILED;
	if (total > 0) {
		int64_t duration = (endTime - startTime);
		String durationStr;
		durationStr << " (in " << duration << "ms, max: " << maxCheckDuration << "ms)";
		if (total > 1) {
			if (0 != testFAILED) {
				switch (total) {
					case 1:
						logs.warning() << "-- FAILED -- 1 file, +" << testOK << ", -" << testFAILED << durationStr;
						break;
					default:
						logs.warning() << "-- FAILED -- " << total << " files, +" << testOK << ", -" << testFAILED << durationStr;
				}
			}
			else
			{
				switch (total) {
					case 1:
						logs.info() << "success: 1 file, +" << testOK << ", -0" << durationStr;
						break;
					default:
						logs.info() << "success: " << total << " files, +" << testOK << ", -0" << durationStr;
				}
			}
		}
	}
	else
		logs.warning() << "no input file";
	return (0 == testFAILED);
}

bool batchCheckIfFilenamesConformToGrammar(Settings& settings) {
	if (not expandFilelist(settings.filenames))
		return false;
	auto commonFolder = (settings.filenames.size() > 1 ? fincCommonFolderLength(settings.filenames) : 0);
	if (0 != commonFolder)
		++commonFolder;
	return IterateThroughAllFiles(settings.filenames, [&](const AnyString& file, int64_t& duration) -> bool {
		String barefile;
		IO::ExtractFileName(barefile, file);
		bool expected = true;
		bool canfail = false;
		if (settings.useFilenameConvention)
		{
			if (barefile.startsWith("ko-"))
				expected = false;
			if (barefile.find("-canfail-") < barefile.size())
				canfail = true;
		}
		// PARSE
		int64_t start = DateTime::NowMilliSeconds();
		bool success = (nytrue == nytry_parse_file_n(file.c_str(), file.size()));
		duration = DateTime::NowMilliSeconds() - start;
		success = (success == expected);
		if (success and duration < 300) {
			logs.info() << AnyString{file, commonFolder} << " [" << duration << "ms]";
		}
		else {
			if (not success) {
				if (not canfail)
					logs.error() << AnyString{file, commonFolder} << " [" << duration << "ms]";
				else
					logs.warning() << AnyString{file, commonFolder} << " [" << duration << "ms, can fail]";
			}
			else
				logs.error() << AnyString{file, commonFolder} << " [" << duration << "ms - time limit reached]";
			success = canfail;
		}
		return success;
	});
}

} // namespace

int main(int argc, char** argv)
{
	Settings settings;
	// parse the command
	{
		// The command line options parser
		GetOpt::Parser options;
		// Input files
		options.add(settings.filenames, 'i', "input", "Input files (or folders)");
		options.remainingArguments(settings.filenames);
		// --no-color
		options.addFlag(settings.noColors, ' ', "no-color", "Disable color output");
		// use filename convention
		options.addFlag(settings.useFilenameConvention, ' ', "use-filename-convention",
			"Use the filename to determine if the test should succeed or not (should succeed if starting with 'ok-'");
		// version
		bool optVersion = false;
		options.addFlag(optVersion, ' ', "version", "Display the version of the compiler and exit");
		// Ask to the parser to parse the command line
		if (not options(argc, argv)) {
			// The program should not continue here
			// The user may have requested the help or an error has happened
			// If an error has happened, the exit status should be different from 0
			if (options.errors()) {
				std::cerr << "Abort due to error\n";
				return EXIT_FAILURE;
			}
			return EXIT_SUCCESS;
		}

		if (optVersion) {
			std::cout << "0.0\n";
			return EXIT_SUCCESS;
		}
		if (settings.filenames.empty()) {
			std::cerr << argv[0] << ": no input file\n";
			return EXIT_FAILURE;
		}
	}
	// Print AST or check for Nany Grammar
	bool success = batchCheckIfFilenamesConformToGrammar(settings);
	return success ? EXIT_SUCCESS : EXIT_FAILURE;
}
<|endoftext|>


<commit_before>// Copyright 2014 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/chromeos/file_system_provider/request_manager.h"

#include "base/files/file.h"
#include "base/stl_util.h"
#include "base/trace_event/trace_event.h"
#include "chrome/browser/extensions/window_controller_list.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "extensions/browser/app_window/app_window_registry.h"
#include "extensions/common/constants.h"

namespace chromeos {
namespace file_system_provider {
namespace {

// Timeout in seconds, before a request is considered as stale and hence
// aborted.
const int kDefaultTimeout = 10;

}  // namespace

RequestManager::RequestManager(
    Profile* profile,
    const std::string& extension_id,
    NotificationManagerInterface* notification_manager)
    : profile_(profile),
      extension_id_(extension_id),
      notification_manager_(notification_manager),
      next_id_(1),
      timeout_(base::TimeDelta::FromSeconds(kDefaultTimeout)),
      weak_ptr_factory_(this) {
}

RequestManager::~RequestManager() {
  // Abort all of the active requests.
  RequestMap::iterator it = requests_.begin();
  while (it != requests_.end()) {
    const int request_id = it->first;
    ++it;
    RejectRequest(request_id,
                  scoped_ptr<RequestValue>(new RequestValue()),
                  base::File::FILE_ERROR_ABORT);
  }

  DCHECK_EQ(0u, requests_.size());
  STLDeleteValues(&requests_);
}

int RequestManager::CreateRequest(RequestType type,
                                  scoped_ptr<HandlerInterface> handler) {
  // The request id is unique per request manager, so per service, thereof
  // per profile.
  int request_id = next_id_++;

  // If cycled the int, then signal an error.
  if (requests_.find(request_id) != requests_.end())
    return 0;

  TRACE_EVENT_ASYNC_BEGIN1("file_system_provider",
                           "RequestManager::Request",
                           request_id,
                           "type",
                           type);

  Request* request = new Request;
  request->handler = handler.Pass();
  requests_[request_id] = request;
  ResetTimer(request_id);

  FOR_EACH_OBSERVER(Observer, observers_, OnRequestCreated(request_id, type));

  // Execute the request implementation. In case of an execution failure,
  // unregister and return 0. This may often happen, eg. if the providing
  // extension is not listening for the request event being sent.
  // In such case, we should abort as soon as possible.
  if (!request->handler->Execute(request_id)) {
    DestroyRequest(request_id);
    return 0;
  }

  FOR_EACH_OBSERVER(Observer, observers_, OnRequestExecuted(request_id));

  return request_id;
}

base::File::Error RequestManager::FulfillRequest(
    int request_id,
    scoped_ptr<RequestValue> response,
    bool has_more) {
  CHECK(response.get());
  RequestMap::iterator request_it = requests_.find(request_id);
  if (request_it == requests_.end())
    return base::File::FILE_ERROR_NOT_FOUND;

  FOR_EACH_OBSERVER(Observer,
                    observers_,
                    OnRequestFulfilled(request_id, *response.get(), has_more));

  request_it->second->handler->OnSuccess(request_id, response.Pass(), has_more);

  if (!has_more) {
    DestroyRequest(request_id);
  } else {
    if (notification_manager_)
      notification_manager_->HideUnresponsiveNotification(request_id);
    ResetTimer(request_id);
  }

  return base::File::FILE_OK;
}

base::File::Error RequestManager::RejectRequest(
    int request_id,
    scoped_ptr<RequestValue> response,
    base::File::Error error) {
  CHECK(response.get());
  RequestMap::iterator request_it = requests_.find(request_id);
  if (request_it == requests_.end())
    return base::File::FILE_ERROR_NOT_FOUND;

  FOR_EACH_OBSERVER(Observer,
                    observers_,
                    OnRequestRejected(request_id, *response.get(), error));
  request_it->second->handler->OnError(request_id, response.Pass(), error);
  DestroyRequest(request_id);

  return base::File::FILE_OK;
}

void RequestManager::SetTimeoutForTesting(const base::TimeDelta& timeout) {
  timeout_ = timeout;
}

std::vector<int> RequestManager::GetActiveRequestIds() const {
  std::vector<int> result;

  for (RequestMap::const_iterator request_it = requests_.begin();
       request_it != requests_.end();
       ++request_it) {
    result.push_back(request_it->first);
  }

  return result;
}

void RequestManager::AddObserver(Observer* observer) {
  DCHECK(observer);
  observers_.AddObserver(observer);
}

void RequestManager::RemoveObserver(Observer* observer) {
  DCHECK(observer);
  observers_.RemoveObserver(observer);
}

RequestManager::Request::Request() {}

RequestManager::Request::~Request() {}

void RequestManager::OnRequestTimeout(int request_id) {
  FOR_EACH_OBSERVER(Observer, observers_, OnRequestTimeouted(request_id));

  if (!notification_manager_) {
    RejectRequest(request_id,
                  scoped_ptr<RequestValue>(new RequestValue()),
                  base::File::FILE_ERROR_ABORT);
    return;
  }

  if (!IsInteractingWithUser()) {
    notification_manager_->ShowUnresponsiveNotification(
        request_id,
        base::Bind(&RequestManager::OnUnresponsiveNotificationResult,
                   weak_ptr_factory_.GetWeakPtr(), request_id));
  } else {
    ResetTimer(request_id);
  }
}

void RequestManager::OnUnresponsiveNotificationResult(
    int request_id,
    NotificationManagerInterface::NotificationResult result) {
  RequestMap::iterator request_it = requests_.find(request_id);
  if (request_it == requests_.end())
    return;

  if (result == NotificationManagerInterface::CONTINUE) {
    ResetTimer(request_id);
    return;
  }

  RejectRequest(request_id,
                scoped_ptr<RequestValue>(new RequestValue()),
                base::File::FILE_ERROR_ABORT);
}

void RequestManager::ResetTimer(int request_id) {
  RequestMap::iterator request_it = requests_.find(request_id);
  if (request_it == requests_.end())
    return;

  request_it->second->timeout_timer.Start(
      FROM_HERE,
      timeout_,
      base::Bind(&RequestManager::OnRequestTimeout,
                 weak_ptr_factory_.GetWeakPtr(),
                 request_id));
}

bool RequestManager::IsInteractingWithUser() const {
  // First try for app windows. If not found, then fall back to browser windows
  // and tabs.

  const extensions::AppWindowRegistry* const registry =
      extensions::AppWindowRegistry::Get(profile_);
  DCHECK(registry);
  if (registry->GetCurrentAppWindowForApp(extension_id_))
    return true;

  // This loop is heavy, but it's not called often. Only when a request timeouts
  // which is at most once every 10 seconds per request (except tests).
  const extensions::WindowControllerList::ControllerList& windows =
      extensions::WindowControllerList::GetInstance()->windows();
  for (const auto& window : windows) {
    const TabStripModel* const tabs = window->GetBrowser()->tab_strip_model();
    for (int i = 0; i < tabs->count(); ++i) {
      const content::WebContents* const web_contents =
          tabs->GetWebContentsAt(i);
      const GURL& url = web_contents->GetURL();
      if (url.scheme() == extensions::kExtensionScheme &&
          url.host() == extension_id_) {
        return true;
      }
    }
  }

  return false;
}

void RequestManager::DestroyRequest(int request_id) {
  RequestMap::iterator request_it = requests_.find(request_id);
  if (request_it == requests_.end())
    return;

  delete request_it->second;
  requests_.erase(request_it);

  if (notification_manager_)
    notification_manager_->HideUnresponsiveNotification(request_id);

  FOR_EACH_OBSERVER(Observer, observers_, OnRequestDestroyed(request_id));

  TRACE_EVENT_ASYNC_END0(
      "file_system_provider", "RequestManager::Request", request_id);
}

}  // namespace file_system_provider
}  // namespace chromeos
<commit_msg>Fix crash when accessing an archive of a deleted file.<commit_after>// Copyright 2014 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/chromeos/file_system_provider/request_manager.h"

#include "base/files/file.h"
#include "base/stl_util.h"
#include "base/trace_event/trace_event.h"
#include "chrome/browser/extensions/window_controller_list.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "extensions/browser/app_window/app_window_registry.h"
#include "extensions/common/constants.h"

namespace chromeos {
namespace file_system_provider {
namespace {

// Timeout in seconds, before a request is considered as stale and hence
// aborted.
const int kDefaultTimeout = 10;

}  // namespace

RequestManager::RequestManager(
    Profile* profile,
    const std::string& extension_id,
    NotificationManagerInterface* notification_manager)
    : profile_(profile),
      extension_id_(extension_id),
      notification_manager_(notification_manager),
      next_id_(1),
      timeout_(base::TimeDelta::FromSeconds(kDefaultTimeout)),
      weak_ptr_factory_(this) {
}

RequestManager::~RequestManager() {
  // Abort all of the active requests.
  RequestMap::iterator it = requests_.begin();
  while (it != requests_.end()) {
    const int request_id = it->first;
    ++it;
    RejectRequest(request_id,
                  scoped_ptr<RequestValue>(new RequestValue()),
                  base::File::FILE_ERROR_ABORT);
  }

  DCHECK_EQ(0u, requests_.size());
  STLDeleteValues(&requests_);
}

int RequestManager::CreateRequest(RequestType type,
                                  scoped_ptr<HandlerInterface> handler) {
  // The request id is unique per request manager, so per service, thereof
  // per profile.
  int request_id = next_id_++;

  // If cycled the int, then signal an error.
  if (requests_.find(request_id) != requests_.end())
    return 0;

  TRACE_EVENT_ASYNC_BEGIN1("file_system_provider",
                           "RequestManager::Request",
                           request_id,
                           "type",
                           type);

  Request* request = new Request;
  request->handler = handler.Pass();
  requests_[request_id] = request;
  ResetTimer(request_id);

  FOR_EACH_OBSERVER(Observer, observers_, OnRequestCreated(request_id, type));

  // Execute the request implementation. In case of an execution failure,
  // unregister and return 0. This may often happen, eg. if the providing
  // extension is not listening for the request event being sent.
  // In such case, we should abort as soon as possible.
  if (!request->handler->Execute(request_id)) {
    DestroyRequest(request_id);
    return 0;
  }

  FOR_EACH_OBSERVER(Observer, observers_, OnRequestExecuted(request_id));

  return request_id;
}

base::File::Error RequestManager::FulfillRequest(
    int request_id,
    scoped_ptr<RequestValue> response,
    bool has_more) {
  CHECK(response.get());
  RequestMap::iterator request_it = requests_.find(request_id);
  if (request_it == requests_.end())
    return base::File::FILE_ERROR_NOT_FOUND;

  FOR_EACH_OBSERVER(Observer,
                    observers_,
                    OnRequestFulfilled(request_id, *response.get(), has_more));

  request_it->second->handler->OnSuccess(request_id, response.Pass(), has_more);

  if (!has_more) {
    DestroyRequest(request_id);
  } else {
    if (notification_manager_)
      notification_manager_->HideUnresponsiveNotification(request_id);
    ResetTimer(request_id);
  }

  return base::File::FILE_OK;
}

base::File::Error RequestManager::RejectRequest(
    int request_id,
    scoped_ptr<RequestValue> response,
    base::File::Error error) {
  CHECK(response.get());
  RequestMap::iterator request_it = requests_.find(request_id);
  if (request_it == requests_.end())
    return base::File::FILE_ERROR_NOT_FOUND;

  FOR_EACH_OBSERVER(Observer,
                    observers_,
                    OnRequestRejected(request_id, *response.get(), error));
  request_it->second->handler->OnError(request_id, response.Pass(), error);
  DestroyRequest(request_id);

  return base::File::FILE_OK;
}

void RequestManager::SetTimeoutForTesting(const base::TimeDelta& timeout) {
  timeout_ = timeout;
}

std::vector<int> RequestManager::GetActiveRequestIds() const {
  std::vector<int> result;

  for (RequestMap::const_iterator request_it = requests_.begin();
       request_it != requests_.end();
       ++request_it) {
    result.push_back(request_it->first);
  }

  return result;
}

void RequestManager::AddObserver(Observer* observer) {
  DCHECK(observer);
  observers_.AddObserver(observer);
}

void RequestManager::RemoveObserver(Observer* observer) {
  DCHECK(observer);
  observers_.RemoveObserver(observer);
}

RequestManager::Request::Request() {}

RequestManager::Request::~Request() {}

void RequestManager::OnRequestTimeout(int request_id) {
  FOR_EACH_OBSERVER(Observer, observers_, OnRequestTimeouted(request_id));

  if (!notification_manager_) {
    RejectRequest(request_id,
                  scoped_ptr<RequestValue>(new RequestValue()),
                  base::File::FILE_ERROR_ABORT);
    return;
  }

  if (!IsInteractingWithUser()) {
    notification_manager_->ShowUnresponsiveNotification(
        request_id,
        base::Bind(&RequestManager::OnUnresponsiveNotificationResult,
                   weak_ptr_factory_.GetWeakPtr(), request_id));
  } else {
    ResetTimer(request_id);
  }
}

void RequestManager::OnUnresponsiveNotificationResult(
    int request_id,
    NotificationManagerInterface::NotificationResult result) {
  RequestMap::iterator request_it = requests_.find(request_id);
  if (request_it == requests_.end())
    return;

  if (result == NotificationManagerInterface::CONTINUE) {
    ResetTimer(request_id);
    return;
  }

  RejectRequest(request_id,
                scoped_ptr<RequestValue>(new RequestValue()),
                base::File::FILE_ERROR_ABORT);
}

void RequestManager::ResetTimer(int request_id) {
  RequestMap::iterator request_it = requests_.find(request_id);
  if (request_it == requests_.end())
    return;

  request_it->second->timeout_timer.Start(
      FROM_HERE,
      timeout_,
      base::Bind(&RequestManager::OnRequestTimeout,
                 weak_ptr_factory_.GetWeakPtr(),
                 request_id));
}

bool RequestManager::IsInteractingWithUser() const {
  // First try for app windows. If not found, then fall back to browser windows
  // and tabs.

  const extensions::AppWindowRegistry* const registry =
      extensions::AppWindowRegistry::Get(profile_);
  DCHECK(registry);
  if (registry->GetCurrentAppWindowForApp(extension_id_))
    return true;

  // This loop is heavy, but it's not called often. Only when a request timeouts
  // which is at most once every 10 seconds per request (except tests).
  const extensions::WindowControllerList::ControllerList& windows =
      extensions::WindowControllerList::GetInstance()->windows();
  for (const auto& window : windows) {
    const Browser* const browser = window->GetBrowser();
    if (!browser)
      continue;
    const TabStripModel* const tabs = browser->tab_strip_model();
    DCHECK(tabs);
    for (int i = 0; i < tabs->count(); ++i) {
      const content::WebContents* const web_contents =
          tabs->GetWebContentsAt(i);
      const GURL& url = web_contents->GetURL();
      if (url.scheme() == extensions::kExtensionScheme &&
          url.host() == extension_id_) {
        return true;
      }
    }
  }

  return false;
}

void RequestManager::DestroyRequest(int request_id) {
  RequestMap::iterator request_it = requests_.find(request_id);
  if (request_it == requests_.end())
    return;

  delete request_it->second;
  requests_.erase(request_it);

  if (notification_manager_)
    notification_manager_->HideUnresponsiveNotification(request_id);

  FOR_EACH_OBSERVER(Observer, observers_, OnRequestDestroyed(request_id));

  TRACE_EVENT_ASYNC_END0(
      "file_system_provider", "RequestManager::Request", request_id);
}

}  // namespace file_system_provider
}  // namespace chromeos
<|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/tab_contents/render_view_host_delegate_helper.h"

#include <string>

#include "base/command_line.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/background_contents_service.h"
#include "chrome/browser/character_encoding.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/render_widget_fullscreen_host.h"
#include "chrome/browser/renderer_host/render_widget_host.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/renderer_host/site_instance.h"
#include "chrome/browser/tab_contents/background_contents.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/tab_contents_view.h"
#include "chrome/browser/user_style_sheet_watcher.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"

RenderViewHostDelegateViewHelper::RenderViewHostDelegateViewHelper() {}

RenderViewHostDelegateViewHelper::~RenderViewHostDelegateViewHelper() {}

BackgroundContents*
RenderViewHostDelegateViewHelper::MaybeCreateBackgroundContents(
    int route_id,
    Profile* profile,
    SiteInstance* site,
    const GURL& opener_url,
    const string16& frame_name) {
  ExtensionService* extensions_service = profile->GetExtensionService();

  if (!opener_url.is_valid() ||
      frame_name.empty() ||
      !extensions_service ||
      !extensions_service->is_ready())
    return NULL;

  // Only hosted apps have web extents, so this ensures that only hosted apps
  // can create BackgroundContents. We don't have to check for background
  // permission as that is checked in RenderMessageFilter when the CreateWindow
  // message is processed.
  const Extension* extension =
      extensions_service->GetExtensionByWebExtent(opener_url);
  if (!extension)
    return NULL;

  // Only allow a single background contents per app.
  if (!profile->GetBackgroundContentsService() ||
      profile->GetBackgroundContentsService()->GetAppBackgroundContents(
          ASCIIToUTF16(extension->id())))
    return NULL;

  // Ensure that we're trying to open this from the extension's process.
  ExtensionProcessManager* process_manager =
      profile->GetExtensionProcessManager();
  if (!site->GetProcess() || !process_manager ||
      site->GetProcess() != process_manager->GetExtensionProcess(opener_url))
    return NULL;

  // Passed all the checks, so this should be created as a BackgroundContents.
  return profile->GetBackgroundContentsService()->CreateBackgroundContents(
      site, route_id, profile, frame_name, ASCIIToUTF16(extension->id()));
}

TabContents* RenderViewHostDelegateViewHelper::CreateNewWindow(
    int route_id,
    Profile* profile,
    SiteInstance* site,
    WebUITypeID webui_type,
    RenderViewHostDelegate* opener,
    WindowContainerType window_container_type,
    const string16& frame_name) {
  if (window_container_type == WINDOW_CONTAINER_TYPE_BACKGROUND) {
    BackgroundContents* contents = MaybeCreateBackgroundContents(
        route_id,
        profile,
        site,
        opener->GetURL(),
        frame_name);
    if (contents) {
      pending_contents_[route_id] = contents->render_view_host();
      return NULL;
    }
  }

  // Create the new web contents. This will automatically create the new
  // TabContentsView. In the future, we may want to create the view separately.
  TabContents* new_contents =
      new TabContents(profile,
                      site,
                      route_id,
                      opener->GetAsTabContents(),
                      NULL);
  new_contents->set_opener_web_ui_type(webui_type);
  TabContentsView* new_view = new_contents->view();

  // TODO(brettw) it seems bogus that we have to call this function on the
  // newly created object and give it one of its own member variables.
  new_view->CreateViewForWidget(new_contents->render_view_host());

  // Save the created window associated with the route so we can show it later.
  pending_contents_[route_id] = new_contents->render_view_host();
  return new_contents;
}

RenderWidgetHostView* RenderViewHostDelegateViewHelper::CreateNewWidget(
    int route_id, WebKit::WebPopupType popup_type, RenderProcessHost* process) {
  RenderWidgetHost* widget_host =
      new RenderWidgetHost(process, route_id);
  RenderWidgetHostView* widget_view =
      RenderWidgetHostView::CreateViewForWidget(widget_host);
  // Popups should not get activated.
  widget_view->set_popup_type(popup_type);
  // Save the created widget associated with the route so we can show it later.
  pending_widget_views_[route_id] = widget_view;
  return widget_view;
}

RenderWidgetHostView*
RenderViewHostDelegateViewHelper::CreateNewFullscreenWidget(
    int route_id, RenderProcessHost* process) {
  RenderWidgetFullscreenHost* fullscreen_widget_host =
      new RenderWidgetFullscreenHost(process, route_id);
  RenderWidgetHostView* widget_view =
      RenderWidgetHostView::CreateViewForWidget(fullscreen_widget_host);
  pending_widget_views_[route_id] = widget_view;
  return widget_view;
}

TabContents* RenderViewHostDelegateViewHelper::GetCreatedWindow(int route_id) {
  PendingContents::iterator iter = pending_contents_.find(route_id);
  if (iter == pending_contents_.end()) {
    DCHECK(false);
    return NULL;
  }

  RenderViewHost* new_rvh = iter->second;
  pending_contents_.erase(route_id);

  // The renderer crashed or it is a TabContents and has no view.
  if (!new_rvh->process()->HasConnection() ||
      (new_rvh->delegate()->GetAsTabContents() && !new_rvh->view()))
    return NULL;

  // TODO(brettw) this seems bogus to reach into here and initialize the host.
  new_rvh->Init();
  return new_rvh->delegate()->GetAsTabContents();
}

RenderWidgetHostView* RenderViewHostDelegateViewHelper::GetCreatedWidget(
    int route_id) {
  PendingWidgetViews::iterator iter = pending_widget_views_.find(route_id);
  if (iter == pending_widget_views_.end()) {
    DCHECK(false);
    return NULL;
  }

  RenderWidgetHostView* widget_host_view = iter->second;
  pending_widget_views_.erase(route_id);

  RenderWidgetHost* widget_host = widget_host_view->GetRenderWidgetHost();
  if (!widget_host->process()->HasConnection()) {
    // The view has gone away or the renderer crashed. Nothing to do.
    return NULL;
  }

  return widget_host_view;
}

void RenderViewHostDelegateViewHelper::RenderWidgetHostDestroyed(
    RenderWidgetHost* host) {
  for (PendingWidgetViews::iterator i = pending_widget_views_.begin();
       i != pending_widget_views_.end(); ++i) {
    if (host->view() == i->second) {
      pending_widget_views_.erase(i);
      return;
    }
  }
}

bool RenderViewHostDelegateHelper::gpu_enabled_ = true;

// static
WebPreferences RenderViewHostDelegateHelper::GetWebkitPrefs(
    Profile* profile, bool is_web_ui) {
  PrefService* prefs = profile->GetPrefs();
  WebPreferences web_prefs;

  web_prefs.fixed_font_family =
      UTF8ToUTF16(prefs->GetString(prefs::kWebKitFixedFontFamily));
  web_prefs.serif_font_family =
      UTF8ToUTF16(prefs->GetString(prefs::kWebKitSerifFontFamily));
  web_prefs.sans_serif_font_family =
      UTF8ToUTF16(prefs->GetString(prefs::kWebKitSansSerifFontFamily));
  if (prefs->GetBoolean(prefs::kWebKitStandardFontIsSerif))
    web_prefs.standard_font_family = web_prefs.serif_font_family;
  else
    web_prefs.standard_font_family = web_prefs.sans_serif_font_family;
  web_prefs.cursive_font_family =
      UTF8ToUTF16(prefs->GetString(prefs::kWebKitCursiveFontFamily));
  web_prefs.fantasy_font_family =
      UTF8ToUTF16(prefs->GetString(prefs::kWebKitFantasyFontFamily));

  web_prefs.default_font_size =
      prefs->GetInteger(prefs::kWebKitDefaultFontSize);
  web_prefs.default_fixed_font_size =
      prefs->GetInteger(prefs::kWebKitDefaultFixedFontSize);
  web_prefs.minimum_font_size =
      prefs->GetInteger(prefs::kWebKitMinimumFontSize);
  web_prefs.minimum_logical_font_size =
      prefs->GetInteger(prefs::kWebKitMinimumLogicalFontSize);

  web_prefs.default_encoding = prefs->GetString(prefs::kDefaultCharset);

  web_prefs.javascript_can_open_windows_automatically =
      prefs->GetBoolean(prefs::kWebKitJavascriptCanOpenWindowsAutomatically);
  web_prefs.dom_paste_enabled =
      prefs->GetBoolean(prefs::kWebKitDomPasteEnabled);
  web_prefs.shrinks_standalone_images_to_fit =
      prefs->GetBoolean(prefs::kWebKitShrinksStandaloneImagesToFit);
  const DictionaryValue* inspector_settings =
      prefs->GetDictionary(prefs::kWebKitInspectorSettings);
  if (inspector_settings) {
    for (DictionaryValue::key_iterator iter(inspector_settings->begin_keys());
         iter != inspector_settings->end_keys(); ++iter) {
      std::string value;
      if (inspector_settings->GetStringWithoutPathExpansion(*iter, &value))
          web_prefs.inspector_settings.push_back(
              std::make_pair(*iter, value));
    }
  }
  web_prefs.tabs_to_links = prefs->GetBoolean(prefs::kWebkitTabsToLinks);

  {  // Command line switches are used for preferences with no user interface.
    const CommandLine& command_line = *CommandLine::ForCurrentProcess();
    web_prefs.developer_extras_enabled =
        !command_line.HasSwitch(switches::kDisableDevTools);
    web_prefs.javascript_enabled =
        !command_line.HasSwitch(switches::kDisableJavaScript) &&
        prefs->GetBoolean(prefs::kWebKitJavascriptEnabled);
    web_prefs.web_security_enabled =
        !command_line.HasSwitch(switches::kDisableWebSecurity) &&
        prefs->GetBoolean(prefs::kWebKitWebSecurityEnabled);
    web_prefs.plugins_enabled =
        !command_line.HasSwitch(switches::kDisablePlugins) &&
        prefs->GetBoolean(prefs::kWebKitPluginsEnabled);
    web_prefs.java_enabled =
        !command_line.HasSwitch(switches::kDisableJava) &&
        prefs->GetBoolean(prefs::kWebKitJavaEnabled);
    web_prefs.loads_images_automatically =
        prefs->GetBoolean(prefs::kWebKitLoadsImagesAutomatically);
    web_prefs.uses_page_cache =
        command_line.HasSwitch(switches::kEnableFastback);
    web_prefs.remote_fonts_enabled =
        !command_line.HasSwitch(switches::kDisableRemoteFonts);
    web_prefs.xss_auditor_enabled =
        !command_line.HasSwitch(switches::kDisableXSSAuditor);
    web_prefs.application_cache_enabled =
        !command_line.HasSwitch(switches::kDisableApplicationCache);

    web_prefs.local_storage_enabled =
        !command_line.HasSwitch(switches::kDisableLocalStorage);
    web_prefs.databases_enabled =
        !command_line.HasSwitch(switches::kDisableDatabases);
    web_prefs.webaudio_enabled =
        command_line.HasSwitch(switches::kEnableWebAudio);
    web_prefs.experimental_webgl_enabled =
        gpu_enabled() &&
        !command_line.HasSwitch(switches::kDisable3DAPIs) &&
        !command_line.HasSwitch(switches::kDisableExperimentalWebGL);
    web_prefs.gl_multisampling_enabled =
        !command_line.HasSwitch(switches::kDisableGLMultisampling);
    web_prefs.site_specific_quirks_enabled =
        !command_line.HasSwitch(switches::kDisableSiteSpecificQuirks);
    web_prefs.allow_file_access_from_file_urls =
        command_line.HasSwitch(switches::kAllowFileAccessFromFiles);
    web_prefs.show_composited_layer_borders =
        command_line.HasSwitch(switches::kShowCompositedLayerBorders);
    web_prefs.accelerated_compositing_enabled =
        gpu_enabled() &&
        !command_line.HasSwitch(switches::kDisableAcceleratedCompositing);
    web_prefs.accelerated_2d_canvas_enabled =
        gpu_enabled() &&
        command_line.HasSwitch(switches::kEnableAccelerated2dCanvas);
    web_prefs.accelerated_layers_enabled =
        !command_line.HasSwitch(switches::kDisableAcceleratedLayers);
    web_prefs.composite_to_texture_enabled =
        command_line.HasSwitch(switches::kEnableCompositeToTexture);
    web_prefs.accelerated_plugins_enabled =
        command_line.HasSwitch(switches::kEnableAcceleratedPlugins);
    web_prefs.accelerated_video_enabled =
        !command_line.HasSwitch(switches::kDisableAcceleratedVideo);
    web_prefs.memory_info_enabled =
        command_line.HasSwitch(switches::kEnableMemoryInfo);
    web_prefs.hyperlink_auditing_enabled =
        !command_line.HasSwitch(switches::kNoPings);
    web_prefs.interactive_form_validation_enabled =
        !command_line.HasSwitch(switches::kDisableInteractiveFormValidation);
    // The user stylesheet watcher may not exist in a testing profile.
    if (profile->GetUserStyleSheetWatcher()) {
      web_prefs.user_style_sheet_enabled = true;
      web_prefs.user_style_sheet_location =
          profile->GetUserStyleSheetWatcher()->user_style_sheet();
    } else {
      web_prefs.user_style_sheet_enabled = false;
    }
  }

  web_prefs.uses_universal_detector =
      prefs->GetBoolean(prefs::kWebKitUsesUniversalDetector);
  web_prefs.text_areas_are_resizable =
      prefs->GetBoolean(prefs::kWebKitTextAreasAreResizable);

  // Make sure we will set the default_encoding with canonical encoding name.
  web_prefs.default_encoding =
      CharacterEncoding::GetCanonicalEncodingNameByAliasName(
          web_prefs.default_encoding);
  if (web_prefs.default_encoding.empty()) {
    prefs->ClearPref(prefs::kDefaultCharset);
    web_prefs.default_encoding = prefs->GetString(prefs::kDefaultCharset);
  }
  DCHECK(!web_prefs.default_encoding.empty());

  if (is_web_ui) {
    web_prefs.loads_images_automatically = true;
    web_prefs.javascript_enabled = true;
  }

  return web_prefs;
}

void RenderViewHostDelegateHelper::UpdateInspectorSetting(
    Profile* profile, const std::string& key, const std::string& value) {
  DictionaryValue* inspector_settings =
      profile->GetPrefs()->GetMutableDictionary(
          prefs::kWebKitInspectorSettings);
  inspector_settings->SetWithoutPathExpansion(key,
                                              Value::CreateStringValue(value));
}

void RenderViewHostDelegateHelper::ClearInspectorSettings(Profile* profile) {
  DictionaryValue* inspector_settings =
      profile->GetPrefs()->GetMutableDictionary(
          prefs::kWebKitInspectorSettings);
  inspector_settings->Clear();
}
<commit_msg>Set the standard font from 'serif' family font.<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/tab_contents/render_view_host_delegate_helper.h"

#include <string>

#include "base/command_line.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/background_contents_service.h"
#include "chrome/browser/character_encoding.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/render_widget_fullscreen_host.h"
#include "chrome/browser/renderer_host/render_widget_host.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/renderer_host/site_instance.h"
#include "chrome/browser/tab_contents/background_contents.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/tab_contents_view.h"
#include "chrome/browser/user_style_sheet_watcher.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"

RenderViewHostDelegateViewHelper::RenderViewHostDelegateViewHelper() {}

RenderViewHostDelegateViewHelper::~RenderViewHostDelegateViewHelper() {}

BackgroundContents*
RenderViewHostDelegateViewHelper::MaybeCreateBackgroundContents(
    int route_id,
    Profile* profile,
    SiteInstance* site,
    const GURL& opener_url,
    const string16& frame_name) {
  ExtensionService* extensions_service = profile->GetExtensionService();

  if (!opener_url.is_valid() ||
      frame_name.empty() ||
      !extensions_service ||
      !extensions_service->is_ready())
    return NULL;

  // Only hosted apps have web extents, so this ensures that only hosted apps
  // can create BackgroundContents. We don't have to check for background
  // permission as that is checked in RenderMessageFilter when the CreateWindow
  // message is processed.
  const Extension* extension =
      extensions_service->GetExtensionByWebExtent(opener_url);
  if (!extension)
    return NULL;

  // Only allow a single background contents per app.
  if (!profile->GetBackgroundContentsService() ||
      profile->GetBackgroundContentsService()->GetAppBackgroundContents(
          ASCIIToUTF16(extension->id())))
    return NULL;

  // Ensure that we're trying to open this from the extension's process.
  ExtensionProcessManager* process_manager =
      profile->GetExtensionProcessManager();
  if (!site->GetProcess() || !process_manager ||
      site->GetProcess() != process_manager->GetExtensionProcess(opener_url))
    return NULL;

  // Passed all the checks, so this should be created as a BackgroundContents.
  return profile->GetBackgroundContentsService()->CreateBackgroundContents(
      site, route_id, profile, frame_name, ASCIIToUTF16(extension->id()));
}

TabContents* RenderViewHostDelegateViewHelper::CreateNewWindow(
    int route_id,
    Profile* profile,
    SiteInstance* site,
    WebUITypeID webui_type,
    RenderViewHostDelegate* opener,
    WindowContainerType window_container_type,
    const string16& frame_name) {
  if (window_container_type == WINDOW_CONTAINER_TYPE_BACKGROUND) {
    BackgroundContents* contents = MaybeCreateBackgroundContents(
        route_id,
        profile,
        site,
        opener->GetURL(),
        frame_name);
    if (contents) {
      pending_contents_[route_id] = contents->render_view_host();
      return NULL;
    }
  }

  // Create the new web contents. This will automatically create the new
  // TabContentsView. In the future, we may want to create the view separately.
  TabContents* new_contents =
      new TabContents(profile,
                      site,
                      route_id,
                      opener->GetAsTabContents(),
                      NULL);
  new_contents->set_opener_web_ui_type(webui_type);
  TabContentsView* new_view = new_contents->view();

  // TODO(brettw) it seems bogus that we have to call this function on the
  // newly created object and give it one of its own member variables.
  new_view->CreateViewForWidget(new_contents->render_view_host());

  // Save the created window associated with the route so we can show it later.
  pending_contents_[route_id] = new_contents->render_view_host();
  return new_contents;
}

RenderWidgetHostView* RenderViewHostDelegateViewHelper::CreateNewWidget(
    int route_id, WebKit::WebPopupType popup_type, RenderProcessHost* process) {
  RenderWidgetHost* widget_host =
      new RenderWidgetHost(process, route_id);
  RenderWidgetHostView* widget_view =
      RenderWidgetHostView::CreateViewForWidget(widget_host);
  // Popups should not get activated.
  widget_view->set_popup_type(popup_type);
  // Save the created widget associated with the route so we can show it later.
  pending_widget_views_[route_id] = widget_view;
  return widget_view;
}

RenderWidgetHostView*
RenderViewHostDelegateViewHelper::CreateNewFullscreenWidget(
    int route_id, RenderProcessHost* process) {
  RenderWidgetFullscreenHost* fullscreen_widget_host =
      new RenderWidgetFullscreenHost(process, route_id);
  RenderWidgetHostView* widget_view =
      RenderWidgetHostView::CreateViewForWidget(fullscreen_widget_host);
  pending_widget_views_[route_id] = widget_view;
  return widget_view;
}

TabContents* RenderViewHostDelegateViewHelper::GetCreatedWindow(int route_id) {
  PendingContents::iterator iter = pending_contents_.find(route_id);
  if (iter == pending_contents_.end()) {
    DCHECK(false);
    return NULL;
  }

  RenderViewHost* new_rvh = iter->second;
  pending_contents_.erase(route_id);

  // The renderer crashed or it is a TabContents and has no view.
  if (!new_rvh->process()->HasConnection() ||
      (new_rvh->delegate()->GetAsTabContents() && !new_rvh->view()))
    return NULL;

  // TODO(brettw) this seems bogus to reach into here and initialize the host.
  new_rvh->Init();
  return new_rvh->delegate()->GetAsTabContents();
}

RenderWidgetHostView* RenderViewHostDelegateViewHelper::GetCreatedWidget(
    int route_id) {
  PendingWidgetViews::iterator iter = pending_widget_views_.find(route_id);
  if (iter == pending_widget_views_.end()) {
    DCHECK(false);
    return NULL;
  }

  RenderWidgetHostView* widget_host_view = iter->second;
  pending_widget_views_.erase(route_id);

  RenderWidgetHost* widget_host = widget_host_view->GetRenderWidgetHost();
  if (!widget_host->process()->HasConnection()) {
    // The view has gone away or the renderer crashed. Nothing to do.
    return NULL;
  }

  return widget_host_view;
}

void RenderViewHostDelegateViewHelper::RenderWidgetHostDestroyed(
    RenderWidgetHost* host) {
  for (PendingWidgetViews::iterator i = pending_widget_views_.begin();
       i != pending_widget_views_.end(); ++i) {
    if (host->view() == i->second) {
      pending_widget_views_.erase(i);
      return;
    }
  }
}

bool RenderViewHostDelegateHelper::gpu_enabled_ = true;

// static
WebPreferences RenderViewHostDelegateHelper::GetWebkitPrefs(
    Profile* profile, bool is_web_ui) {
  PrefService* prefs = profile->GetPrefs();
  WebPreferences web_prefs;

  web_prefs.fixed_font_family =
      UTF8ToUTF16(prefs->GetString(prefs::kWebKitFixedFontFamily));
  web_prefs.serif_font_family =
      UTF8ToUTF16(prefs->GetString(prefs::kWebKitSerifFontFamily));
  web_prefs.sans_serif_font_family =
      UTF8ToUTF16(prefs->GetString(prefs::kWebKitSansSerifFontFamily));
  // TODO(kochi): As we don't have setting UI for kWebKitStandardFontIsSerif,
  // we always use web_prefs.serif_font_family as a standard font
  // temporarily for now.  Ideally we should have a pref UI for serif/sans
  // selection as for CJK font sans-serif family font is the default.
  // See discussion in http://crosbug.com/12311.
  web_prefs.standard_font_family = web_prefs.serif_font_family;
  web_prefs.cursive_font_family =
      UTF8ToUTF16(prefs->GetString(prefs::kWebKitCursiveFontFamily));
  web_prefs.fantasy_font_family =
      UTF8ToUTF16(prefs->GetString(prefs::kWebKitFantasyFontFamily));

  web_prefs.default_font_size =
      prefs->GetInteger(prefs::kWebKitDefaultFontSize);
  web_prefs.default_fixed_font_size =
      prefs->GetInteger(prefs::kWebKitDefaultFixedFontSize);
  web_prefs.minimum_font_size =
      prefs->GetInteger(prefs::kWebKitMinimumFontSize);
  web_prefs.minimum_logical_font_size =
      prefs->GetInteger(prefs::kWebKitMinimumLogicalFontSize);

  web_prefs.default_encoding = prefs->GetString(prefs::kDefaultCharset);

  web_prefs.javascript_can_open_windows_automatically =
      prefs->GetBoolean(prefs::kWebKitJavascriptCanOpenWindowsAutomatically);
  web_prefs.dom_paste_enabled =
      prefs->GetBoolean(prefs::kWebKitDomPasteEnabled);
  web_prefs.shrinks_standalone_images_to_fit =
      prefs->GetBoolean(prefs::kWebKitShrinksStandaloneImagesToFit);
  const DictionaryValue* inspector_settings =
      prefs->GetDictionary(prefs::kWebKitInspectorSettings);
  if (inspector_settings) {
    for (DictionaryValue::key_iterator iter(inspector_settings->begin_keys());
         iter != inspector_settings->end_keys(); ++iter) {
      std::string value;
      if (inspector_settings->GetStringWithoutPathExpansion(*iter, &value))
          web_prefs.inspector_settings.push_back(
              std::make_pair(*iter, value));
    }
  }
  web_prefs.tabs_to_links = prefs->GetBoolean(prefs::kWebkitTabsToLinks);

  {  // Command line switches are used for preferences with no user interface.
    const CommandLine& command_line = *CommandLine::ForCurrentProcess();
    web_prefs.developer_extras_enabled =
        !command_line.HasSwitch(switches::kDisableDevTools);
    web_prefs.javascript_enabled =
        !command_line.HasSwitch(switches::kDisableJavaScript) &&
        prefs->GetBoolean(prefs::kWebKitJavascriptEnabled);
    web_prefs.web_security_enabled =
        !command_line.HasSwitch(switches::kDisableWebSecurity) &&
        prefs->GetBoolean(prefs::kWebKitWebSecurityEnabled);
    web_prefs.plugins_enabled =
        !command_line.HasSwitch(switches::kDisablePlugins) &&
        prefs->GetBoolean(prefs::kWebKitPluginsEnabled);
    web_prefs.java_enabled =
        !command_line.HasSwitch(switches::kDisableJava) &&
        prefs->GetBoolean(prefs::kWebKitJavaEnabled);
    web_prefs.loads_images_automatically =
        prefs->GetBoolean(prefs::kWebKitLoadsImagesAutomatically);
    web_prefs.uses_page_cache =
        command_line.HasSwitch(switches::kEnableFastback);
    web_prefs.remote_fonts_enabled =
        !command_line.HasSwitch(switches::kDisableRemoteFonts);
    web_prefs.xss_auditor_enabled =
        !command_line.HasSwitch(switches::kDisableXSSAuditor);
    web_prefs.application_cache_enabled =
        !command_line.HasSwitch(switches::kDisableApplicationCache);

    web_prefs.local_storage_enabled =
        !command_line.HasSwitch(switches::kDisableLocalStorage);
    web_prefs.databases_enabled =
        !command_line.HasSwitch(switches::kDisableDatabases);
    web_prefs.webaudio_enabled =
        command_line.HasSwitch(switches::kEnableWebAudio);
    web_prefs.experimental_webgl_enabled =
        gpu_enabled() &&
        !command_line.HasSwitch(switches::kDisable3DAPIs) &&
        !command_line.HasSwitch(switches::kDisableExperimentalWebGL);
    web_prefs.gl_multisampling_enabled =
        !command_line.HasSwitch(switches::kDisableGLMultisampling);
    web_prefs.site_specific_quirks_enabled =
        !command_line.HasSwitch(switches::kDisableSiteSpecificQuirks);
    web_prefs.allow_file_access_from_file_urls =
        command_line.HasSwitch(switches::kAllowFileAccessFromFiles);
    web_prefs.show_composited_layer_borders =
        command_line.HasSwitch(switches::kShowCompositedLayerBorders);
    web_prefs.accelerated_compositing_enabled =
        gpu_enabled() &&
        !command_line.HasSwitch(switches::kDisableAcceleratedCompositing);
    web_prefs.accelerated_2d_canvas_enabled =
        gpu_enabled() &&
        command_line.HasSwitch(switches::kEnableAccelerated2dCanvas);
    web_prefs.accelerated_layers_enabled =
        !command_line.HasSwitch(switches::kDisableAcceleratedLayers);
    web_prefs.composite_to_texture_enabled =
        command_line.HasSwitch(switches::kEnableCompositeToTexture);
    web_prefs.accelerated_plugins_enabled =
        command_line.HasSwitch(switches::kEnableAcceleratedPlugins);
    web_prefs.accelerated_video_enabled =
        !command_line.HasSwitch(switches::kDisableAcceleratedVideo);
    web_prefs.memory_info_enabled =
        command_line.HasSwitch(switches::kEnableMemoryInfo);
    web_prefs.hyperlink_auditing_enabled =
        !command_line.HasSwitch(switches::kNoPings);
    web_prefs.interactive_form_validation_enabled =
        !command_line.HasSwitch(switches::kDisableInteractiveFormValidation);
    // The user stylesheet watcher may not exist in a testing profile.
    if (profile->GetUserStyleSheetWatcher()) {
      web_prefs.user_style_sheet_enabled = true;
      web_prefs.user_style_sheet_location =
          profile->GetUserStyleSheetWatcher()->user_style_sheet();
    } else {
      web_prefs.user_style_sheet_enabled = false;
    }
  }

  web_prefs.uses_universal_detector =
      prefs->GetBoolean(prefs::kWebKitUsesUniversalDetector);
  web_prefs.text_areas_are_resizable =
      prefs->GetBoolean(prefs::kWebKitTextAreasAreResizable);

  // Make sure we will set the default_encoding with canonical encoding name.
  web_prefs.default_encoding =
      CharacterEncoding::GetCanonicalEncodingNameByAliasName(
          web_prefs.default_encoding);
  if (web_prefs.default_encoding.empty()) {
    prefs->ClearPref(prefs::kDefaultCharset);
    web_prefs.default_encoding = prefs->GetString(prefs::kDefaultCharset);
  }
  DCHECK(!web_prefs.default_encoding.empty());

  if (is_web_ui) {
    web_prefs.loads_images_automatically = true;
    web_prefs.javascript_enabled = true;
  }

  return web_prefs;
}

void RenderViewHostDelegateHelper::UpdateInspectorSetting(
    Profile* profile, const std::string& key, const std::string& value) {
  DictionaryValue* inspector_settings =
      profile->GetPrefs()->GetMutableDictionary(
          prefs::kWebKitInspectorSettings);
  inspector_settings->SetWithoutPathExpansion(key,
                                              Value::CreateStringValue(value));
}

void RenderViewHostDelegateHelper::ClearInspectorSettings(Profile* profile) {
  DictionaryValue* inspector_settings =
      profile->GetPrefs()->GetMutableDictionary(
          prefs::kWebKitInspectorSettings);
  inspector_settings->Clear();
}
<|endoftext|>


<commit_before>#ifndef _PITO_INTERCEPTOR_LIB_C_
#define _PITO_INTERCEPTOR_LIB_C_

#include <pito/interceptor/lib/c_traits.hpp>
#include <pito/interceptor/SystemCall.hpp>

#include <stdlib.h>
#include <stdarg.h>
#include <fcntl.h>

#ifndef PITO_SYSTEM_CALL_BASE
#define PITO_SYSTEM_CALL_BASE  SystemCallBase
#endif

#ifndef PITO_JAIL_BASE
#define PITO_JAIL_BASE PITO_SYSTEM_CALL_BASE
#endif

namespace pito { namespace interceptor {

using namespace system_call;

////////////////////////////////////////////////////////////////////////////////
// security intercepts
PITO_SYSTEM_CALL(chmod)
PITO_SYSTEM_CALL(fchmod)
PITO_SYSTEM_CALL(fchmodat)
PITO_SYSTEM_CALL(chown)
PITO_SYSTEM_CALL(fchown)
PITO_SYSTEM_CALL(fchownat)

template <>
struct SystemCall<open>
 : PITO_SYSTEM_CALL_BASE<open> {};

extern "C" {
    int open(const char *pathname, int flags, ...) {
        if (flags & O_CREAT) {
            va_list ap;
            va_start(ap, flags);
            mode_t mode = va_arg(ap, int);
            va_end(ap);
            return PITO_SUPER(open)(pathname, flags, mode);
        }
        else return PITO_SUPER(open)(pathname, flags);
    }
}

template <>
struct SystemCall<openat>
  : PITO_SYSTEM_CALL_BASE<openat> {};

extern "C" {
    int openat(int dirfd, const char *pathname, int flags, ...) {
        if (flags & O_CREAT) {
            va_list ap;
            va_start(ap, flags);
            mode_t mode = va_arg(ap, int);
            va_end(ap);
            return PITO_SUPER(openat)(dirfd, pathname, flags, mode);
        }
        else return PITO_SUPER(openat)(dirfd, pathname, flags);
    }
}

PITO_SYSTEM_CALL(creat)
PITO_SYSTEM_CALL(fopen)
PITO_SYSTEM_CALL(lchown)
PITO_SYSTEM_CALL(link)
PITO_SYSTEM_CALL(linkat)
PITO_SYSTEM_CALL(mkdir)
PITO_SYSTEM_CALL(mkdirat)
PITO_SYSTEM_CALL(opendir)
PITO_SYSTEM_CALL(mknod)
PITO_SYSTEM_CALL(mknodat)
// function todo: __xmknod
PITO_SYSTEM_CALL(mkfifo)
PITO_SYSTEM_CALL(mkfifoat)
PITO_SYSTEM_CALL(access)
PITO_SYSTEM_CALL(faccessat)
PITO_SYSTEM_CALL(rename)
PITO_SYSTEM_CALL(renameat)
PITO_SYSTEM_CALL(rmdir)
PITO_SYSTEM_CALL(symlink)
PITO_SYSTEM_CALL(symlinkat)
PITO_SYSTEM_CALL(truncate)
PITO_SYSTEM_CALL(unlink)
PITO_SYSTEM_CALL(unlinkat)
PITO_SYSTEM_CALL(getcwd)

template <>
struct SystemCall<open64>
  : PITO_SYSTEM_CALL_BASE<open64> {};

extern "C" {
    int open64(const char *pathname, int flags, ...) {
        if (flags & O_CREAT) {
            va_list ap;
            va_start(ap, flags);
            mode_t mode = va_arg(ap, int);
            va_end(ap);
            return PITO_SUPER(open64)(pathname, flags, mode);
        }
        else return PITO_SUPER(open64)(pathname, flags);
    }
}

template <>
struct SystemCall<openat64>
  : PITO_SYSTEM_CALL_BASE<openat64> {};

extern "C" {
    int openat64(RBUTIL_ARGS_3(SystemCall<openat64>::arg_types), ...) {
        if (arg2 & O_CREAT) {
            va_list ap;
            va_start(ap, arg2);
            mode_t mode = va_arg(ap, int);
            va_end(ap);
            return PITO_SUPER(openat64)(arg0, arg1, arg2, mode);
        }
        else return PITO_SUPER(openat64)(arg0, arg1, arg2);
    }
}

PITO_SYSTEM_CALL(creat64)
PITO_SYSTEM_CALL(fopen64)
PITO_SYSTEM_CALL(truncate64)

////////////////////////////////////////////////////////////////////////////////
// jail
////////////////////////////////////////////////////////////////////////////////
PITO_SYSTEM_CALL_WITH_BASE(execve, PITO_JAIL_BASE)
PITO_SYSTEM_CALL_WITH_BASE(execv, PITO_JAIL_BASE)
PITO_SYSTEM_CALL_WITH_BASE(execvp, PITO_JAIL_BASE)
////////////////////////////////////////////////////////////////////////////////
// end jail
////////////////////////////////////////////////////////////////////////////////

PITO_SYSTEM_CALL(utime)
PITO_SYSTEM_CALL(utimes)
PITO_SYSTEM_CALL(utimensat)
PITO_SYSTEM_CALL(futimesat)
PITO_SYSTEM_CALL(lutimes)
PITO_SYSTEM_CALL(getuid)

} }

#endif
<commit_msg>remove some code innit<commit_after>#ifndef _PITO_INTERCEPTOR_LIB_C_
#define _PITO_INTERCEPTOR_LIB_C_

#include <pito/interceptor/lib/c_traits.hpp>
#include <pito/interceptor/SystemCall.hpp>

#include <stdlib.h>
#include <stdarg.h>
#include <fcntl.h>

#ifndef PITO_SYSTEM_CALL_BASE
#define PITO_SYSTEM_CALL_BASE  SystemCallBase
#endif

#ifndef PITO_JAIL_BASE
#define PITO_JAIL_BASE PITO_SYSTEM_CALL_BASE
#endif

namespace pito { namespace interceptor {

using namespace system_call;

////////////////////////////////////////////////////////////////////////////////
// security intercepts
PITO_SYSTEM_CALL(chmod)
PITO_SYSTEM_CALL(fchmod)
PITO_SYSTEM_CALL(fchmodat)
PITO_SYSTEM_CALL(chown)
PITO_SYSTEM_CALL(fchown)
PITO_SYSTEM_CALL(fchownat)

template <>
struct SystemCall<open>
 : PITO_SYSTEM_CALL_BASE<open> {};

extern "C" {
    int open(PITO_ARGS(open), ...) {
        if (arg1 & O_CREAT) {
            va_list ap;
            va_start(ap, arg1);
            mode_t mode = va_arg(ap, int);
            va_end(ap);
            return PITO_SUPER(open)(arg0, arg1, mode);
        }
        else return PITO_SUPER(open)(arg0, arg1);
    }
}

template <>
struct SystemCall<openat>
  : PITO_SYSTEM_CALL_BASE<openat> {};

extern "C" {
    int openat(PITO_ARGS(openat), ...) {
        if (arg2 & O_CREAT) {
            va_list ap;
            va_start(ap, arg2);
            mode_t mode = va_arg(ap, int);
            va_end(ap);
            return PITO_SUPER(openat)(arg0, arg1, arg2, mode);
        }
        else return PITO_SUPER(openat)(arg0, arg1, arg2);
    }
}

PITO_SYSTEM_CALL(creat)
PITO_SYSTEM_CALL(fopen)
PITO_SYSTEM_CALL(lchown)
PITO_SYSTEM_CALL(link)
PITO_SYSTEM_CALL(linkat)
PITO_SYSTEM_CALL(mkdir)
PITO_SYSTEM_CALL(mkdirat)
PITO_SYSTEM_CALL(opendir)
PITO_SYSTEM_CALL(mknod)
PITO_SYSTEM_CALL(mknodat)
// function todo: __xmknod
PITO_SYSTEM_CALL(mkfifo)
PITO_SYSTEM_CALL(mkfifoat)
PITO_SYSTEM_CALL(access)
PITO_SYSTEM_CALL(faccessat)
PITO_SYSTEM_CALL(rename)
PITO_SYSTEM_CALL(renameat)
PITO_SYSTEM_CALL(rmdir)
PITO_SYSTEM_CALL(symlink)
PITO_SYSTEM_CALL(symlinkat)
PITO_SYSTEM_CALL(truncate)
PITO_SYSTEM_CALL(unlink)
PITO_SYSTEM_CALL(unlinkat)
PITO_SYSTEM_CALL(getcwd)

template <>
struct SystemCall<open64>
  : PITO_SYSTEM_CALL_BASE<open64> {};

extern "C" {
    int open64(PITO_ARGS(open64), ...) {
        if (arg1 & O_CREAT) {
            va_list ap;
            va_start(ap, arg1);
            mode_t mode = va_arg(ap, int);
            va_end(ap);
            return PITO_SUPER(open64)(arg0, arg1, mode);
        }
        else return PITO_SUPER(open64)(arg0, arg1);
    }
}

template <>
struct SystemCall<openat64>
  : PITO_SYSTEM_CALL_BASE<openat64> {};

extern "C" {
    int openat64(PITO_ARGS(openat64), ...) {
        if (arg2 & O_CREAT) {
            va_list ap;
            va_start(ap, arg2);
            mode_t mode = va_arg(ap, int);
            va_end(ap);
            return PITO_SUPER(openat64)(arg0, arg1, arg2, mode);
        }
        else return PITO_SUPER(openat64)(arg0, arg1, arg2);
    }
}

PITO_SYSTEM_CALL(creat64)
PITO_SYSTEM_CALL(fopen64)
PITO_SYSTEM_CALL(truncate64)

////////////////////////////////////////////////////////////////////////////////
// jail
////////////////////////////////////////////////////////////////////////////////
PITO_SYSTEM_CALL_WITH_BASE(execve, PITO_JAIL_BASE)
PITO_SYSTEM_CALL_WITH_BASE(execv, PITO_JAIL_BASE)
PITO_SYSTEM_CALL_WITH_BASE(execvp, PITO_JAIL_BASE)
////////////////////////////////////////////////////////////////////////////////
// end jail
////////////////////////////////////////////////////////////////////////////////

PITO_SYSTEM_CALL(utime)
PITO_SYSTEM_CALL(utimes)
PITO_SYSTEM_CALL(utimensat)
PITO_SYSTEM_CALL(futimesat)
PITO_SYSTEM_CALL(lutimes)
PITO_SYSTEM_CALL(getuid)

} }

#endif
<|endoftext|>


<commit_before>/* Copyright (C) 2003 MySQL AB

   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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#include <NDBT.hpp>
#include <NDBT_Test.hpp>
#include <HugoTransactions.hpp>
#include <UtilTransactions.hpp>
#include <random.h>
#include <getarg.h>

struct Parameter {
  char * name;
  unsigned value;
  unsigned min;
  unsigned max;
};

#define P_BATCH   0
#define P_PARRA   1
#define P_LOCK    2
#define P_FILT    3
#define P_BOUND   4
#define P_ACCESS  5
#define P_FETCH   6
#define P_ROWS    7
#define P_LOOPS   8
#define P_CREATE  9
#define P_LOAD   10
#define P_RESET  11

#define P_MAX 12

static
Parameter
g_paramters[] = {
  { "batch",       0, 0, 1 }, // 0, 15
  { "parallelism", 0, 0, 1 }, // 0,  1
  { "lock",        0, 0, 2 }, // read, exclusive, dirty
  { "filter",      0, 0, 3 }, // all, none, 1, 100
  { "range",       0, 0, 3 }, // all, none, 1, 100
  { "access",      0, 0, 2 }, // scan, idx, idx sorted
  { "fetch",       0, 0, 1 }, // No, yes
  { "size",  1000000, 1, ~0 },
  { "iterations",  3, 1, ~0 },
  { "create_drop", 1, 0, 1 },
  { "data",        1, 0, 1 },
  { "q-reset bounds", 0, 1, 0 }
};

static Ndb* g_ndb = 0;
static const NdbDictionary::Table * g_table;
static const NdbDictionary::Index * g_index;
static char g_tablename[256];
static char g_indexname[256];

int create_table();
int load_table();
int run_scan();
int clear_table();
int drop_table();

int
main(int argc, const char** argv){
  ndb_init();
  int verbose = 1;
  int optind = 0;

  struct getargs args[1+P_MAX] = {
    { "verbose", 'v', arg_flag, &verbose, "Print verbose status", "verbose" }
  };
  const int num_args = 1 + P_MAX;
  int i;
  for(i = 0; i<P_MAX; i++){
    args[i+1].long_name = g_paramters[i].name;
    args[i+1].short_name = * g_paramters[i].name;
    args[i+1].type = arg_integer;
    args[i+1].value = &g_paramters[i].value;
    BaseString tmp;
    tmp.assfmt("min: %d max: %d", g_paramters[i].min, g_paramters[i].max);
    args[i+1].help = strdup(tmp.c_str());
    args[i+1].arg_help = 0;
  }

  if(getarg(args, num_args, argc, argv, &optind)) {
    arg_printusage(args, num_args, argv[0], "tabname1 tabname2 ...");
    return NDBT_WRONGARGS;
  }

  myRandom48Init(NdbTick_CurrentMillisecond());

  g_ndb = new Ndb("TEST_DB");
  if(g_ndb->init() != 0){
    g_err << "init() failed" << endl;
    goto error;
  }
  if(g_ndb->waitUntilReady() != 0){
    g_err << "Wait until ready failed" << endl;
    goto error;
  }
  for(i = optind; i<argc; i++){
    const char * T = argv[i];
    g_info << "Testing " << T << endl;
    BaseString::snprintf(g_tablename, sizeof(g_tablename), T);
    BaseString::snprintf(g_indexname, sizeof(g_indexname), "IDX_%s", T);
    if(create_table())
      goto error;
    if(load_table())
      goto error;
    if(run_scan())
      goto error;
    if(clear_table())
      goto error;
    if(drop_table())
      goto error;
  }

  if(g_ndb) delete g_ndb;
  return NDBT_OK;
 error:
  if(g_ndb) delete g_ndb;
  return NDBT_FAILED;
}

int
create_table(){
  NdbDictionary::Dictionary* dict = g_ndb->getDictionary();
  assert(dict);
  if(g_paramters[P_CREATE].value){
    const NdbDictionary::Table * pTab = NDBT_Tables::getTable(g_tablename);
    assert(pTab);
    NdbDictionary::Table copy = * pTab;
    copy.setLogging(false);
    if(dict->createTable(copy) != 0){
      g_err << "Failed to create table: " << g_tablename << endl;
      return -1;
    }

    NdbDictionary::Index x(g_indexname);
    x.setTable(g_tablename);
    x.setType(NdbDictionary::Index::OrderedIndex);
    x.setLogging(false);
    for (unsigned k = 0; k < copy.getNoOfColumns(); k++){
      if(copy.getColumn(k)->getPrimaryKey()){
	x.addColumnName(copy.getColumn(k)->getName());
      }
    }

    if(dict->createIndex(x) != 0){
      g_err << "Failed to create index: " << endl;
      return -1;
    }
  }
  g_table = dict->getTable(g_tablename);
  g_index = dict->getIndex(g_indexname, g_tablename);
  assert(g_table);
  assert(g_index);
  return 0;
}

int
drop_table(){
  if(!g_paramters[P_CREATE].value)
    return 0;
  if(g_ndb->getDictionary()->dropTable(g_table->getName()) != 0){
    g_err << "Failed to drop table: " << g_table->getName() << endl;
    return -1;
  }
  g_table = 0;
  return 0;
}

int
load_table(){
  if(!g_paramters[P_LOAD].value)
    return 0;

  int rows = g_paramters[P_ROWS].value;
  HugoTransactions hugoTrans(* g_table);
  if (hugoTrans.loadTable(g_ndb, rows)){
    g_err.println("Failed to load %s with %d rows", g_table->getName(), rows);
    return -1;
  }
  return 0;
}

int
clear_table(){
  if(!g_paramters[P_LOAD].value)
    return 0;
  int rows = g_paramters[P_ROWS].value;

  UtilTransactions utilTrans(* g_table);
  if (utilTrans.clearTable(g_ndb,  rows) != 0){
    g_err.println("Failed to clear table %s", g_table->getName());
    return -1;
  }
  return 0;
}

inline
void err(NdbError e){
  ndbout << e << endl;
}

int
run_scan(){
  int iter = g_paramters[P_LOOPS].value;
  NDB_TICKS start1, stop;
  int sum_time= 0;

  int sample_rows = 0;
  NDB_TICKS sample_start = NdbTick_CurrentMillisecond();

  Uint32 tot = g_paramters[P_ROWS].value;

  if(g_paramters[P_BOUND].value == 2 || g_paramters[P_FILT].value == 2)
    iter *= g_paramters[P_ROWS].value;

  NdbScanOperation * pOp = 0;
  NdbIndexScanOperation * pIOp = 0;
  NdbConnection * pTrans = 0;
  NdbResultSet * rs = 0;
  int check = 0;

  for(int i = 0; i<iter; i++){
    start1 = NdbTick_CurrentMillisecond();
    pTrans = pTrans ? pTrans : g_ndb->startTransaction();
    if(!pTrans){
      g_err << "Failed to start transaction" << endl;
      err(g_ndb->getNdbError());
      return -1;
    }

    int par = g_paramters[P_PARRA].value;
    int bat = g_paramters[P_BATCH].value;
    NdbScanOperation::LockMode lm;
    switch(g_paramters[P_LOCK].value){
    case 0:
      lm = NdbScanOperation::LM_CommittedRead;
      break;
    case 1:
      lm = NdbScanOperation::LM_Read;
      break;
    case 2:
      lm = NdbScanOperation::LM_Exclusive;
      break;
    default:
      abort();
    }

    if(g_paramters[P_ACCESS].value == 0){
      pOp = pTrans->getNdbScanOperation(g_tablename);
      assert(pOp);
      rs = pOp->readTuples(lm, bat, par);
    } else {
      if(g_paramters[P_RESET].value == 0 || pIOp == 0)
      {
	pOp= pIOp= pTrans->getNdbIndexScanOperation(g_indexname, g_tablename);
	bool ord = g_paramters[P_ACCESS].value == 2;
	rs = pIOp->readTuples(lm, bat, par, ord);
      }
      else
      {
	pIOp->reset_bounds();
      }

      switch(g_paramters[P_BOUND].value){
      case 0: // All
	break;
      case 1: // None
	pIOp->setBound((Uint32)0, NdbIndexScanOperation::BoundEQ, 0);
	break;
      case 2: { // 1 row
      default:
	assert(g_table->getNoOfPrimaryKeys() == 1); // only impl. so far
	int tot = g_paramters[P_ROWS].value;
	int row = rand() % tot;
#if 0
	fix_eq_bound(pIOp, row);
#else
	pIOp->setBound((Uint32)0, NdbIndexScanOperation::BoundEQ, &row);
#endif
	break;
      }
      }
      if(g_paramters[P_RESET].value == 1)
	goto execute;
    }
    assert(pOp);
    assert(rs);

    switch(g_paramters[P_FILT].value){
    case 0: // All
      check = pOp->interpret_exit_ok();
      break;
    case 1: // None
      check = pOp->interpret_exit_nok();
      break;
    case 2: { // 1 row
    default:
      assert(g_table->getNoOfPrimaryKeys() == 1); // only impl. so far
      abort();
#if 0
      int tot = g_paramters[P_ROWS].value;
      int row = rand() % tot;
      NdbScanFilter filter(pOp) ;
      filter.begin(NdbScanFilter::AND);
      fix_eq(filter, pOp, row);
      filter.end();
      break;
#endif
    }
    }
    if(check != 0){
      err(pOp->getNdbError());
      return -1;
    }
    assert(check == 0);

    for(int i = 0; i<g_table->getNoOfColumns(); i++){
      pOp->getValue(i);
    }
execute:
    int rows = 0;
    check = pTrans->execute(NoCommit);
    assert(check == 0);
    int fetch = g_paramters[P_FETCH].value;
    while((check = rs->nextResult(true)) == 0){
      do {
	rows++;
      } while(!fetch && ((check = rs->nextResult(false)) == 0));
      if(check == -1){
        err(pTrans->getNdbError());
        return -1;
      }
      assert(check == 2);
    }

    if(check == -1){
      err(pTrans->getNdbError());
      return -1;
    }
    assert(check == 1);
    if(g_paramters[P_RESET].value == 0)
    {
      pTrans->close();
      pTrans = 0;
    }
    stop = NdbTick_CurrentMillisecond();

    int time_passed= (int)(stop - start1);
    sample_rows += rows;
    sum_time+= time_passed;

    if(sample_rows >= tot)
    {
      int sample_time = (int)(stop - sample_start);
      g_info << "Found " << sample_rows << " rows" << endl;
      g_err.println("Time: %d ms = %u rows/sec", sample_time,
		    (1000*sample_rows)/sample_time);
      sample_rows = 0;
      sample_start = stop;
    }
  }

  g_err.println("Avg time: %d ms = %u rows/sec", sum_time/iter,
                (1000*tot*iter)/sum_time);
  return 0;
}
<commit_msg>ndb - bugfix testScanPerf<commit_after>/* Copyright (C) 2003 MySQL AB

   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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#include <NDBT.hpp>
#include <NDBT_Test.hpp>
#include <HugoTransactions.hpp>
#include <UtilTransactions.hpp>
#include <random.h>
#include <getarg.h>

struct Parameter {
  char * name;
  unsigned value;
  unsigned min;
  unsigned max;
};

#define P_BATCH   0
#define P_PARRA   1
#define P_LOCK    2
#define P_FILT    3
#define P_BOUND   4
#define P_ACCESS  5
#define P_FETCH   6
#define P_ROWS    7
#define P_LOOPS   8
#define P_CREATE  9
#define P_LOAD   10
#define P_RESET  11

#define P_MAX 12

static
Parameter
g_paramters[] = {
  { "batch",       0, 0, 1 }, // 0, 15
  { "parallelism", 0, 0, 1 }, // 0,  1
  { "lock",        0, 0, 2 }, // read, exclusive, dirty
  { "filter",      0, 0, 3 }, // all, none, 1, 100
  { "range",       0, 0, 3 }, // all, none, 1, 100
  { "access",      0, 0, 2 }, // scan, idx, idx sorted
  { "fetch",       0, 0, 1 }, // No, yes
  { "size",  1000000, 1, ~0 },
  { "iterations",  3, 1, ~0 },
  { "create_drop", 1, 0, 1 },
  { "data",        1, 0, 1 },
  { "q-reset bounds", 0, 1, 0 }
};

static Ndb* g_ndb = 0;
static const NdbDictionary::Table * g_table;
static const NdbDictionary::Index * g_index;
static char g_tablename[256];
static char g_indexname[256];

int create_table();
int load_table();
int run_scan();
int clear_table();
int drop_table();

int
main(int argc, const char** argv){
  ndb_init();
  int verbose = 1;
  int optind = 0;

  struct getargs args[1+P_MAX] = {
    { "verbose", 'v', arg_flag, &verbose, "Print verbose status", "verbose" }
  };
  const int num_args = 1 + P_MAX;
  int i;
  for(i = 0; i<P_MAX; i++){
    args[i+1].long_name = g_paramters[i].name;
    args[i+1].short_name = * g_paramters[i].name;
    args[i+1].type = arg_integer;
    args[i+1].value = &g_paramters[i].value;
    BaseString tmp;
    tmp.assfmt("min: %d max: %d", g_paramters[i].min, g_paramters[i].max);
    args[i+1].help = strdup(tmp.c_str());
    args[i+1].arg_help = 0;
  }

  if(getarg(args, num_args, argc, argv, &optind)) {
    arg_printusage(args, num_args, argv[0], "tabname1 tabname2 ...");
    return NDBT_WRONGARGS;
  }

  myRandom48Init(NdbTick_CurrentMillisecond());

  g_ndb = new Ndb("TEST_DB");
  if(g_ndb->init() != 0){
    g_err << "init() failed" << endl;
    goto error;
  }
  if(g_ndb->waitUntilReady() != 0){
    g_err << "Wait until ready failed" << endl;
    goto error;
  }
  for(i = optind; i<argc; i++){
    const char * T = argv[i];
    g_info << "Testing " << T << endl;
    BaseString::snprintf(g_tablename, sizeof(g_tablename), T);
    BaseString::snprintf(g_indexname, sizeof(g_indexname), "IDX_%s", T);
    if(create_table())
      goto error;
    if(load_table())
      goto error;
    if(run_scan())
      goto error;
    if(clear_table())
      goto error;
    if(drop_table())
      goto error;
  }

  if(g_ndb) delete g_ndb;
  return NDBT_OK;
 error:
  if(g_ndb) delete g_ndb;
  return NDBT_FAILED;
}

int
create_table(){
  NdbDictionary::Dictionary* dict = g_ndb->getDictionary();
  assert(dict);
  if(g_paramters[P_CREATE].value){
    const NdbDictionary::Table * pTab = NDBT_Tables::getTable(g_tablename);
    assert(pTab);
    NdbDictionary::Table copy = * pTab;
    copy.setLogging(false);
    if(dict->createTable(copy) != 0){
      g_err << "Failed to create table: " << g_tablename << endl;
      return -1;
    }

    NdbDictionary::Index x(g_indexname);
    x.setTable(g_tablename);
    x.setType(NdbDictionary::Index::OrderedIndex);
    x.setLogging(false);
    for (unsigned k = 0; k < copy.getNoOfColumns(); k++){
      if(copy.getColumn(k)->getPrimaryKey()){
	x.addColumnName(copy.getColumn(k)->getName());
      }
    }

    if(dict->createIndex(x) != 0){
      g_err << "Failed to create index: " << endl;
      return -1;
    }
  }
  g_table = dict->getTable(g_tablename);
  g_index = dict->getIndex(g_indexname, g_tablename);
  assert(g_table);
  assert(g_index);
  return 0;
}

int
drop_table(){
  if(!g_paramters[P_CREATE].value)
    return 0;
  if(g_ndb->getDictionary()->dropTable(g_table->getName()) != 0){
    g_err << "Failed to drop table: " << g_table->getName() << endl;
    return -1;
  }
  g_table = 0;
  return 0;
}

int
load_table(){
  if(!g_paramters[P_LOAD].value)
    return 0;

  int rows = g_paramters[P_ROWS].value;
  HugoTransactions hugoTrans(* g_table);
  if (hugoTrans.loadTable(g_ndb, rows)){
    g_err.println("Failed to load %s with %d rows", g_table->getName(), rows);
    return -1;
  }
  return 0;
}

int
clear_table(){
  if(!g_paramters[P_LOAD].value)
    return 0;
  int rows = g_paramters[P_ROWS].value;

  UtilTransactions utilTrans(* g_table);
  if (utilTrans.clearTable(g_ndb,  rows) != 0){
    g_err.println("Failed to clear table %s", g_table->getName());
    return -1;
  }
  return 0;
}

inline
void err(NdbError e){
  ndbout << e << endl;
}

int
run_scan(){
  int iter = g_paramters[P_LOOPS].value;
  NDB_TICKS start1, stop;
  int sum_time= 0;

  int sample_rows = 0;
  int tot_rows = 0;
  NDB_TICKS sample_start = NdbTick_CurrentMillisecond();

  Uint32 tot = g_paramters[P_ROWS].value;

  if(g_paramters[P_BOUND].value == 2 || g_paramters[P_FILT].value == 2)
    iter *= g_paramters[P_ROWS].value;

  NdbScanOperation * pOp = 0;
  NdbIndexScanOperation * pIOp = 0;
  NdbConnection * pTrans = 0;
  NdbResultSet * rs = 0;
  int check = 0;

  for(int i = 0; i<iter; i++){
    start1 = NdbTick_CurrentMillisecond();
    pTrans = pTrans ? pTrans : g_ndb->startTransaction();
    if(!pTrans){
      g_err << "Failed to start transaction" << endl;
      err(g_ndb->getNdbError());
      return -1;
    }

    int par = g_paramters[P_PARRA].value;
    int bat = g_paramters[P_BATCH].value;
    NdbScanOperation::LockMode lm;
    switch(g_paramters[P_LOCK].value){
    case 0:
      lm = NdbScanOperation::LM_CommittedRead;
      break;
    case 1:
      lm = NdbScanOperation::LM_Read;
      break;
    case 2:
      lm = NdbScanOperation::LM_Exclusive;
      break;
    default:
      abort();
    }

    if(g_paramters[P_ACCESS].value == 0){
      pOp = pTrans->getNdbScanOperation(g_tablename);
      assert(pOp);
      rs = pOp->readTuples(lm, bat, par);
    } else {
      if(g_paramters[P_RESET].value == 0 || pIOp == 0)
      {
	pOp= pIOp= pTrans->getNdbIndexScanOperation(g_indexname, g_tablename);
	bool ord = g_paramters[P_ACCESS].value == 2;
	rs = pIOp->readTuples(lm, bat, par, ord);
      }
      else
      {
	pIOp->reset_bounds();
      }

      switch(g_paramters[P_BOUND].value){
      case 0: // All
	break;
      case 1: // None
	pIOp->setBound((Uint32)0, NdbIndexScanOperation::BoundEQ, 0);
	break;
      case 2: { // 1 row
      default:
	assert(g_table->getNoOfPrimaryKeys() == 1); // only impl. so far
	int tot = g_paramters[P_ROWS].value;
	int row = rand() % tot;
#if 0
	fix_eq_bound(pIOp, row);
#else
	pIOp->setBound((Uint32)0, NdbIndexScanOperation::BoundEQ, &row);
#endif
	break;
      }
      }
      if(g_paramters[P_RESET].value == 2)
	goto execute;
    }
    assert(pOp);
    assert(rs);

    switch(g_paramters[P_FILT].value){
    case 0: // All
      check = pOp->interpret_exit_ok();
      break;
    case 1: // None
      check = pOp->interpret_exit_nok();
      break;
    case 2: { // 1 row
    default:
      assert(g_table->getNoOfPrimaryKeys() == 1); // only impl. so far
      abort();
#if 0
      int tot = g_paramters[P_ROWS].value;
      int row = rand() % tot;
      NdbScanFilter filter(pOp) ;
      filter.begin(NdbScanFilter::AND);
      fix_eq(filter, pOp, row);
      filter.end();
      break;
#endif
    }
    }
    if(check != 0){
      err(pOp->getNdbError());
      return -1;
    }
    assert(check == 0);

    if(g_paramters[P_RESET].value == 1)
      g_paramters[P_RESET].value = 2;

    for(int i = 0; i<g_table->getNoOfColumns(); i++){
      pOp->getValue(i);
    }
execute:
    int rows = 0;
    check = pTrans->execute(NoCommit);
    assert(check == 0);
    int fetch = g_paramters[P_FETCH].value;
    while((check = rs->nextResult(true)) == 0){
      do {
	rows++;
      } while(!fetch && ((check = rs->nextResult(false)) == 0));
      if(check == -1){
        err(pTrans->getNdbError());
        return -1;
      }
      assert(check == 2);
    }

    if(check == -1){
      err(pTrans->getNdbError());
      return -1;
    }
    assert(check == 1);
    if(g_paramters[P_RESET].value == 0)
    {
      pTrans->close();
      pTrans = 0;
    }
    stop = NdbTick_CurrentMillisecond();

    int time_passed= (int)(stop - start1);
    sample_rows += rows;
    sum_time+= time_passed;
    tot_rows+= rows;

    if(sample_rows >= tot)
    {
      int sample_time = (int)(stop - sample_start);
      g_info << "Found " << sample_rows << " rows" << endl;
      g_err.println("Time: %d ms = %u rows/sec", sample_time,
		    (1000*sample_rows)/sample_time);
      sample_rows = 0;
      sample_start = stop;
    }
  }

  g_err.println("Avg time: %d ms = %u rows/sec", sum_time/tot_rows,
                (1000*tot_rows)/sum_time);
  return 0;
}
<|endoftext|>